From 3fbe3e04e80d8399f9394f0d2bf921a64bebdb78 Mon Sep 17 00:00:00 2001 From: George Wright Date: Mon, 20 Apr 2015 18:11:16 -0400 Subject: [PATCH 001/241] Bug 1155784 - Do not consider items when setting selectedIndex for e10s popups r=mconley --- toolkit/modules/SelectParentHelper.jsm | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/toolkit/modules/SelectParentHelper.jsm b/toolkit/modules/SelectParentHelper.jsm index afda8f9e3e43..86b50978fc35 100644 --- a/toolkit/modules/SelectParentHelper.jsm +++ b/toolkit/modules/SelectParentHelper.jsm @@ -14,13 +14,7 @@ this.SelectParentHelper = { populate: function(menulist, items, selectedIndex) { // Clear the current contents of the popup menulist.menupopup.textContent = ""; - populateChildren(menulist.menupopup, items, selectedIndex); - // We expect the parent element of the popup to be a that - // has the popuponly attribute set to "true". This is necessary in order - // for a to act like a proper dropdown, as - // the does things like remember state and set the - // _moz-menuactive attribute on the selected . - menulist.selectedIndex = selectedIndex; + populateChildren(menulist, items, selectedIndex); }, open: function(browser, menulist, rect) { @@ -71,8 +65,9 @@ this.SelectParentHelper = { }; -function populateChildren(element, options, selectedIndex, startIndex = 0, isGroup = false) { +function populateChildren(menulist, options, selectedIndex, startIndex = 0, isGroup = false) { let index = startIndex; + let element = menulist.menupopup; for (let option of options) { let item = element.ownerDocument.createElement("menuitem"); @@ -84,8 +79,16 @@ function populateChildren(element, options, selectedIndex, startIndex = 0, isGro if (option.children.length > 0) { item.classList.add("contentSelectDropdown-optgroup"); item.setAttribute("disabled", "true"); - index = populateChildren(element, option.children, selectedIndex, index, true); + index = populateChildren(menulist, option.children, selectedIndex, index, true); } else { + if (index == selectedIndex) { + // We expect the parent element of the popup to be a that + // has the popuponly attribute set to "true". This is necessary in order + // for a to act like a proper dropdown, as + // the does things like remember state and set the + // _moz-menuactive attribute on the selected . + menulist.selectedItem = item; + } item.setAttribute("value", index++); if (isGroup) { From 9b2bbc3d1a0b989247371295f8a70ca560db9746 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 21 Apr 2015 13:54:07 -0400 Subject: [PATCH 002/241] Bug 1141867 - Add OSX 10.10 fuzz to the newly-added tests. --- layout/reftests/floats/reftest.list | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/layout/reftests/floats/reftest.list b/layout/reftests/floats/reftest.list index fb7a8fa0c33a..5e71e988696f 100644 --- a/layout/reftests/floats/reftest.list +++ b/layout/reftests/floats/reftest.list @@ -35,7 +35,7 @@ fails == 345369-2.html 345369-2-ref.html == float-in-rtl-4b.html float-in-rtl-4-ref.html == float-in-rtl-4c.html float-in-rtl-4-ref.html == float-in-rtl-4d.html float-in-rtl-4-ref.html -fuzzy-if(Android,16,2) == orthogonal-floats-1a.html orthogonal-floats-1-ref.html -== orthogonal-floats-1b.html orthogonal-floats-1-ref.html -fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1c.html orthogonal-floats-1-ref.html -fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1d.html orthogonal-floats-1-ref.html +fuzzy-if(OSX==1010,26,7) fuzzy-if(Android,16,2) == orthogonal-floats-1a.html orthogonal-floats-1-ref.html +fuzzy-if(OSX==1010,26,7) == orthogonal-floats-1b.html orthogonal-floats-1-ref.html +fuzzy-if(OSX==1010,103,802) fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1c.html orthogonal-floats-1-ref.html +fuzzy-if(OSX==1010,103,802) fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1d.html orthogonal-floats-1-ref.html From b7970d33e8a17154eb647ced74cfd7f176772231 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Tue, 21 Apr 2015 13:57:57 -0400 Subject: [PATCH 003/241] Bug 1154347 - Don't set -fomit-frame-pointer on all of skia. r=glandium, r=gw280 --HG-- extra : rebase_source : cdc5b1362119d68c29e7a8182f2ed88db9abb122 --- gfx/skia/generate_mozbuild.py | 4 +++- gfx/skia/moz.build | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gfx/skia/generate_mozbuild.py b/gfx/skia/generate_mozbuild.py index 2e74da84080a..09873be7ed84 100755 --- a/gfx/skia/generate_mozbuild.py +++ b/gfx/skia/generate_mozbuild.py @@ -138,10 +138,11 @@ if CONFIG['GNU_CXX']: CXXFLAGS += [ '-Wno-overloaded-virtual', '-Wno-unused-function', - '-fomit-frame-pointer', ] if not CONFIG['CLANG_CXX']: CXXFLAGS += ['-Wno-logical-op'] + if CONFIG['CPU_ARCH'] == 'arm': + SOURCES['trunk/src/opts/SkBlitRow_opts_arm.cpp'].flags += ['-fomit-frame-pointer'] if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'android', 'gonk', 'qt'): CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS'] @@ -346,6 +347,7 @@ def write_sources(f, values, indent): 'SkBlitter_ARGB32.cpp', 'SkBlitter_RGB16.cpp', 'SkBlitter_Sprite.cpp', + 'SkBlitRow_opts_arm.cpp', 'SkScan_Antihair.cpp', 'SkCondVar.cpp', 'SkParse.cpp', diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build index 59bb7af66ca7..f9a85baae2a6 100644 --- a/gfx/skia/moz.build +++ b/gfx/skia/moz.build @@ -816,13 +816,15 @@ elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']: 'trunk/src/core/SkUtilsArm.cpp', 'trunk/src/opts/SkBitmapProcState_opts_arm.cpp', 'trunk/src/opts/SkBlitMask_opts_arm.cpp', - 'trunk/src/opts/SkBlitRow_opts_arm.cpp', 'trunk/src/opts/SkBlurImage_opts_arm.cpp', 'trunk/src/opts/SkMorphology_opts_arm.cpp', 'trunk/src/opts/SkTextureCompression_opts_arm.cpp', 'trunk/src/opts/SkUtils_opts_arm.cpp', 'trunk/src/opts/SkXfermode_opts_arm.cpp', ] + SOURCES += [ + 'trunk/src/opts/SkBlitRow_opts_arm.cpp', + ] if CONFIG['BUILD_ARM_NEON']: SOURCES += [ 'trunk/src/opts/SkBitmapProcState_arm_neon.cpp', @@ -964,10 +966,11 @@ if CONFIG['GNU_CXX']: CXXFLAGS += [ '-Wno-overloaded-virtual', '-Wno-unused-function', - '-fomit-frame-pointer', ] if not CONFIG['CLANG_CXX']: CXXFLAGS += ['-Wno-logical-op'] + if CONFIG['CPU_ARCH'] == 'arm': + SOURCES['trunk/src/opts/SkBlitRow_opts_arm.cpp'].flags += ['-fomit-frame-pointer'] if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'android', 'gonk', 'qt'): CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS'] From fb0c40e0c698def423e707416a75e3f391dbefa1 Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Tue, 21 Apr 2015 11:04:27 -0700 Subject: [PATCH 004/241] Bug 1071275. Consolidate silk preferences. r=kats --- b2g/app/b2g.js | 5 +---- mobile/android/app/mobile.js | 5 ----- modules/libpref/init/all.js | 2 -- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index babed14cea63..e18f63753143 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -1124,8 +1124,5 @@ pref("dom.mozSettings.allowForceReadOnly", false); // RequestSync API is enabled by default on B2G. pref("dom.requestSync.enabled", true); -// Use vsync aligned rendering -pref("gfx.vsync.hw-vsync.enabled", true); -pref("gfx.vsync.compositor", true); +// Resample touch events on b2g pref("gfx.touch.resample", true); -pref("gfx.vsync.refreshdriver", true); diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 38a66a090b58..7845a6853545 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -863,11 +863,6 @@ pref("reader.toolbar.vertical", false); // Whether or not to display buttons related to reading list in reader view. pref("browser.readinglist.enabled", true); -// Use software vsync to schedule rendering -pref("gfx.vsync.hw-vsync.enabled", true); -pref("gfx.vsync.compositor", true); -pref("gfx.vsync.refreshdriver", true); - // Selection carets never fall-back to internal LongTap detector. pref("selectioncaret.detects.longtap", false); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 575ea9d2f1c9..e091d7e39f96 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4688,11 +4688,9 @@ pref("media.gmp.insecure.allow", false); // Use vsync aligned rendering. b2g prefs are in b2g.js. // Hardware vsync supported on windows, os x, and b2g. // Linux and fennec will use software vsync. -#if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_LINUX) pref("gfx.vsync.hw-vsync.enabled", true); pref("gfx.vsync.compositor", true); pref("gfx.vsync.refreshdriver", true); -#endif // Secure Element API #ifdef MOZ_SECUREELEMENT From 1fc2dfab0a2eb03dac3354675b4bd8db78c65469 Mon Sep 17 00:00:00 2001 From: Kit Cambridge Date: Tue, 21 Apr 2015 20:10:50 +0200 Subject: [PATCH 005/241] Bug 1150683 - Add XPCOM interfaces for push notifications. r=dougt --- b2g/installer/package-manifest.in | 1 + browser/installer/package-manifest.in | 1 + dom/interfaces/push/moz.build | 12 ++++++ dom/interfaces/push/nsIPushNotificationService.idl | 49 ++++++++++++++++++++++ .../push/nsIPushObserverNotification.idl | 30 +++++++++++++ dom/moz.build | 1 + 6 files changed, 94 insertions(+) create mode 100644 dom/interfaces/push/moz.build create mode 100644 dom/interfaces/push/nsIPushNotificationService.idl create mode 100644 dom/interfaces/push/nsIPushObserverNotification.idl --- b2g/installer/package-manifest.in | 1 + browser/installer/package-manifest.in | 1 + dom/interfaces/push/moz.build | 12 +++++ .../push/nsIPushNotificationService.idl | 49 +++++++++++++++++++ .../push/nsIPushObserverNotification.idl | 30 ++++++++++++ dom/moz.build | 1 + 6 files changed, 94 insertions(+) create mode 100644 dom/interfaces/push/moz.build create mode 100644 dom/interfaces/push/nsIPushNotificationService.idl create mode 100644 dom/interfaces/push/nsIPushObserverNotification.idl diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 25e9d418e461..8e625f0d2fbc 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -209,6 +209,7 @@ @RESPATH@/components/dom_json.xpt @RESPATH@/components/dom_messages.xpt @RESPATH@/components/dom_power.xpt +@RESPATH@/components/dom_push.xpt @RESPATH@/components/dom_quota.xpt @RESPATH@/components/dom_range.xpt @RESPATH@/components/dom_security.xpt diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 0b9103bb411f..3bff7f0fa73b 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -218,6 +218,7 @@ @RESPATH@/components/dom_offline.xpt @RESPATH@/components/dom_json.xpt @RESPATH@/components/dom_power.xpt +@RESPATH@/components/dom_push.xpt @RESPATH@/components/dom_quota.xpt @RESPATH@/components/dom_range.xpt @RESPATH@/components/dom_security.xpt diff --git a/dom/interfaces/push/moz.build b/dom/interfaces/push/moz.build new file mode 100644 index 000000000000..879a078c1657 --- /dev/null +++ b/dom/interfaces/push/moz.build @@ -0,0 +1,12 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +XPIDL_SOURCES += [ + 'nsIPushNotificationService.idl', + 'nsIPushObserverNotification.idl', +] + +XPIDL_MODULE = 'dom_push' diff --git a/dom/interfaces/push/nsIPushNotificationService.idl b/dom/interfaces/push/nsIPushNotificationService.idl new file mode 100644 index 000000000000..7d5ca9f00d89 --- /dev/null +++ b/dom/interfaces/push/nsIPushNotificationService.idl @@ -0,0 +1,49 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +/** + * A service for components to subscribe and receive push messages from web + * services. This functionality is exposed to content via the Push API, which + * uses service workers to notify applications. This interface exists to allow + * privileged code to receive messages without migrating to service workers. + */ +[scriptable, uuid(32028e38-903b-4a64-a180-5857eb4cb3dd)] +interface nsIPushNotificationService : nsISupports +{ + /** + * Creates a push subscription for the given |scope| URL and |pageURL|. + * Returns a promise for the new subscription record, or the existing + * record if this |scope| already has a subscription. + * + * The |pushEndpoint| property of the subscription record is a URL string + * that can be used to send push messages to subscribers. For details, + * please see the Simple Push protocol docs. + * + * Each incoming message fires a `push-notification` observer + * notification, with an `nsIPushObserverNotification` as the subject and + * the |scope| as the data. + * + * If the server drops a subscription, a `push-subscription-change` observer + * will be fired, with the subject set to `null` and the data set to |scope|. + * Servers may drop subscriptions at any time, so callers should recreate + * subscriptions if desired. + */ + jsval register(in string scope, [optional] in string pageURL); + + /** + * Revokes a push subscription for the given |scope|. Returns a promise + * for the revoked subscription record, or `null` if the |scope| is not + * subscribed to receive notifications. + */ + jsval unregister(in string scope); + + /** + * Returns a promise for the subscription record associated with the + * given |scope|, or `null` if the |scope| does not have a subscription. + */ + jsval registration(in string scope); +}; diff --git a/dom/interfaces/push/nsIPushObserverNotification.idl b/dom/interfaces/push/nsIPushObserverNotification.idl new file mode 100644 index 000000000000..7f6eb362be8b --- /dev/null +++ b/dom/interfaces/push/nsIPushObserverNotification.idl @@ -0,0 +1,30 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +/** + * A push message received by an `nsIPushNotificationService`, used as the + * subject of a `push-notification` observer notification. + */ +[scriptable, uuid(66a87970-6dc9-46e0-ac61-adb4a13791de)] +interface nsIPushObserverNotification : nsISupports +{ + /* The URL that receives push messages from an application server. */ + attribute string pushEndpoint; + + /** + * The notification version sent by the application server. This is a + * monotonically increasing number. + */ + attribute long long version; + + /** + * The notification payload. Delivery is not guaranteed; if the browser is + * offline when the application server sends the push message, the payload + * may be discarded. + */ + attribute string data; +}; diff --git a/dom/moz.build b/dom/moz.build index 16738a9c931e..0855743eeec9 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -26,6 +26,7 @@ interfaces = [ 'storage', 'json', 'offline', + 'push', 'geolocation', 'notification', 'permission', From 1e06bb992cbd9989118b2f741501ad8845f6583e Mon Sep 17 00:00:00 2001 From: Kit Cambridge Date: Tue, 21 Apr 2015 20:10:50 +0200 Subject: [PATCH 006/241] Bug 1150683 - Implement nsIPushNotificationService. r=dougt --- b2g/installer/package-manifest.in | 2 +- browser/installer/package-manifest.in | 2 +- dom/push/Push.manifest | 11 +- dom/push/PushNotificationService.js | 81 +++++++++ dom/push/PushService.jsm | 324 ++++++++++++++++++++-------------- dom/push/PushServiceLauncher.js | 50 ------ dom/push/moz.build | 2 +- 7 files changed, 285 insertions(+), 187 deletions(-) create mode 100644 dom/push/PushNotificationService.js delete mode 100644 dom/push/PushServiceLauncher.js --- b2g/installer/package-manifest.in | 2 +- browser/installer/package-manifest.in | 2 +- dom/push/Push.manifest | 11 +- dom/push/PushNotificationService.js | 81 +++++++ dom/push/PushService.jsm | 324 +++++++++++++++----------- dom/push/PushServiceLauncher.js | 50 ---- dom/push/moz.build | 2 +- 7 files changed, 285 insertions(+), 187 deletions(-) create mode 100644 dom/push/PushNotificationService.js delete mode 100644 dom/push/PushServiceLauncher.js diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 8e625f0d2fbc..c020e8a080b6 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -630,7 +630,7 @@ @RESPATH@/components/AppsService.manifest @RESPATH@/components/Push.js @RESPATH@/components/Push.manifest -@RESPATH@/components/PushServiceLauncher.js +@RESPATH@/components/PushNotificationService.js @RESPATH@/components/InterAppComm.manifest @RESPATH@/components/InterAppCommService.js diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 3bff7f0fa73b..3bc00abafee9 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -557,7 +557,7 @@ @RESPATH@/components/AlarmsManager.manifest @RESPATH@/components/Push.js @RESPATH@/components/Push.manifest -@RESPATH@/components/PushServiceLauncher.js +@RESPATH@/components/PushNotificationService.js @RESPATH@/components/SlowScriptDebug.manifest @RESPATH@/components/SlowScriptDebug.js diff --git a/dom/push/Push.manifest b/dom/push/Push.manifest index 1527fbba237c..d20f13e93287 100644 --- a/dom/push/Push.manifest +++ b/dom/push/Push.manifest @@ -5,7 +5,10 @@ contract @mozilla.org/push/PushManager;1 {cde1d019-fad8-4044-b141-65fb4fb7a245} component {CA86B665-BEDA-4212-8D0F-5C9F65270B58} Push.js contract @mozilla.org/push/PushSubscription;1 {CA86B665-BEDA-4212-8D0F-5C9F65270B58} -# Component to initialize PushService on startup. -component {4b8caa3b-3c58-4f3c-a7f5-7bd9cb24c11d} PushServiceLauncher.js -contract @mozilla.org/push/ServiceLauncher;1 {4b8caa3b-3c58-4f3c-a7f5-7bd9cb24c11d} -category app-startup PushServiceLauncher @mozilla.org/push/ServiceLauncher;1 +# XPCOM component; initializes the PushService on startup. +component {32028e38-903b-4a64-a180-5857eb4cb3dd} PushNotificationService.js +contract @mozilla.org/push/NotificationService;1 {32028e38-903b-4a64-a180-5857eb4cb3dd} +category app-startup PushNotificationService @mozilla.org/push/NotificationService;1 + +component {66a87970-6dc9-46e0-ac61-adb4a13791de} PushNotificationService.js +contract @mozilla.org/push/ObserverNotification;1 {66a87970-6dc9-46e0-ac61-adb4a13791de} diff --git a/dom/push/PushNotificationService.js b/dom/push/PushNotificationService.js new file mode 100644 index 000000000000..41084a93127b --- /dev/null +++ b/dom/push/PushNotificationService.js @@ -0,0 +1,81 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; +const Cr = Components.results; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +let isParent = Cc["@mozilla.org/xre/runtime;1"] + .getService(Ci.nsIXULRuntime) + .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; + +XPCOMUtils.defineLazyGetter(this, "PushService", function() { + // Lazily initialize the PushService on + // `sessionstore-windows-restored` or first use. + const {PushService} = Cu.import("resource://gre/modules/PushService.jsm", {}); + if (isParent) { + PushService.init(); + } + return PushService; +}); + +this.PushNotificationService = function PushNotificationService() {}; + +PushNotificationService.prototype = { + classID: Components.ID("{32028e38-903b-4a64-a180-5857eb4cb3dd}"), + + contractID: "@mozilla.org/push/NotificationService;1", + + _xpcom_factory: XPCOMUtils.generateSingletonFactory(PushNotificationService), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsISupportsWeakReference, + Ci.nsIPushNotificationService]), + + register: function register(scope, pageURL) { + return PushService._register({scope, pageURL}); + }, + + unregister: function unregister(scope) { + return PushService._unregister({scope}); + }, + + registration: function registration(scope) { + return PushService._registration({scope}); + }, + + observe: function observe(subject, topic, data) { + switch (topic) { + case "app-startup": + Services.obs.addObserver(this, "sessionstore-windows-restored", true); + break; + case "sessionstore-windows-restored": + Services.obs.removeObserver(this, "sessionstore-windows-restored"); + if (isParent) { + PushService.init(); + } + break; + } + } +}; + +this.PushObserverNotification = function PushObserverNotification() {}; + +PushObserverNotification.prototype = { + classID: Components.ID("{66a87970-6dc9-46e0-ac61-adb4a13791de}"), + + contractID: "@mozilla.org/push/ObserverNotification;1", + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIPushObserverNotification]) +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ + PushNotificationService, + PushObserverNotification +]); diff --git a/dom/push/PushService.jsm b/dom/push/PushService.jsm index 94311456e7c4..1bcffbeb1943 100644 --- a/dom/push/PushService.jsm +++ b/dom/push/PushService.jsm @@ -294,6 +294,7 @@ this.PushService = { */ case "xpcom-shutdown": this.uninit(); + break; case "network-active-changed": /* On B2G. */ case "network:offline-status-changed": /* On desktop. */ // In case of network-active-changed, always disconnect existing @@ -348,9 +349,12 @@ this.PushService = { .deferred.reject({status: 0, error: "TimeoutError"}); delete this._pendingRequests[channelID]; - for (let i = this._requestQueue.length - 1; i >= 0; --i) - if (this._requestQueue[i].channelID == channelID) + for (let i = this._requestQueue.length - 1; i >= 0; --i) { + let [, data] = this._requestQueue[i]; + if (data && data.channelID == channelID) { this._requestQueue.splice(i, 1); + } + } } } @@ -493,6 +497,9 @@ this.PushService = { init: function() { debug("init()"); + if (this._started) { + return; + } var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] .getService(Ci.nsIFrameScriptLoader); @@ -564,6 +571,7 @@ this.PushService = { this._waitingForPong = false; this._stopAlarm(); + this._cancelPendingRequests(); }, uninit: function() { @@ -603,6 +611,7 @@ this.PushService = { this._requestTimeoutTimer.cancel(); } + this._started = false; debug("shutdown complete!"); }, @@ -880,6 +889,10 @@ this.PushService = { _startListeningIfChannelsPresent: function() { // Check to see if we need to do anything. + if (this._requestQueue.length > 0) { + this._beginWSSetup(); + return; + } this._db.getAllChannelIDs(function(channelIDs) { if (channelIDs.length > 0) { this._beginWSSetup(); @@ -1163,11 +1176,9 @@ this.PushService = { debug("sendRequest() " + action); if (typeof data.channelID !== "string") { debug("Received non-string channelID"); - return Promise.reject("Received non-string channelID"); + return Promise.reject({error: "Received non-string channelID"}); } - let deferred = Promise.defer(); - if (Object.keys(this._pendingRequests).length == 0) { // start the timer since we now have at least one request if (!this._requestTimeoutTimer) @@ -1178,8 +1189,18 @@ this.PushService = { Ci.nsITimer.TYPE_REPEATING_SLACK); } - this._pendingRequests[data.channelID] = { deferred: deferred, - ctime: Date.now() }; + let deferred; + let request = this._pendingRequests[data.channelID]; + if (request) { + // If a request is already pending for this channel ID, assume it's a + // retry. Use the existing deferred, but update the send time and re-send + // the request. + deferred = request.deferred; + } else { + deferred = Promise.defer(); + request = this._pendingRequests[data.channelID] = {deferred}; + } + request.ctime = Date.now(); this._send(action, data); return deferred.promise; @@ -1201,6 +1222,11 @@ this.PushService = { } if (this._currentState != STATE_READY) { + if (!this._started) { + // The component hasn't been initialized yet. Return early; init() + // will dequeue all pending requests. + return; + } if (!this._ws) { // This will end up calling processNextRequestInQueue(). this._beginWSSetup(); @@ -1269,52 +1295,49 @@ this.PushService = { // registration. _notifyAllAppsRegister: function() { debug("notifyAllAppsRegister()"); - let deferred = Promise.defer(); - - // records are objects describing the registration as stored in IndexedDB. - function wakeupRegisteredApps(records) { - // Pages to be notified. - // wakeupTable[scope] -> [ pageURL ] - let wakeupTable = {}; - for (let i = 0; i < records.length; i++) { - let record = records[i]; - if (!(record.scope in wakeupTable)) - wakeupTable[record.scope] = []; - - wakeupTable[record.scope].push(record.pageURL); - } - - // TODO -- test needed. E10s support needed. - - let globalMM = Cc['@mozilla.org/globalmessagemanager;1'].getService(Ci.nsIMessageListenerManager); - for (let scope in wakeupTable) { - wakeupTable[scope].forEach(function(pageURL) { - globalMM.broadcastAsyncMessage('pushsubscriptionchanged', aPushRecord.scope); - }); - } - deferred.resolve(); - } - - this._db.getAllChannelIDs(wakeupRegisteredApps, deferred.reject); - - return deferred.promise; + return new Promise((resolve, reject) => { + // records are objects describing the registration as stored in IndexedDB. + this._db.getAllChannelIDs(records => { + let scopes = new Set(); + for (let record of records) { + scopes.add(record.scope); + } + let globalMM = Cc['@mozilla.org/globalmessagemanager;1'].getService(Ci.nsIMessageListenerManager); + for (let scope of scopes) { + // Notify XPCOM observers. + Services.obs.notifyObservers( + null, + "push-subscription-change", + scope + ); + // TODO -- test needed. E10s support needed. + globalMM.broadcastAsyncMessage('pushsubscriptionchanged', scope); + } + resolve(); + }, reject); + }); }, _notifyApp: function(aPushRecord) { - if (!aPushRecord || !aPushRecord.pageURL || !aPushRecord.scope) { + if (!aPushRecord || !aPushRecord.scope) { debug("notifyApp() something is undefined. Dropping notification: " + JSON.stringify(aPushRecord) ); return; } - debug("notifyApp() " + aPushRecord.pageURL + - " " + aPushRecord.scope); - let pageURI = Services.io.newURI(aPushRecord.pageURL, null, null); + debug("notifyApp() " + aPushRecord.scope); let scopeURI = Services.io.newURI(aPushRecord.scope, null, null); - let message = { - pushEndpoint: aPushRecord.pushEndpoint, - version: aPushRecord.version - }; + // Notify XPCOM observers. + let notification = Cc["@mozilla.org/push/ObserverNotification;1"] + .createInstance(Ci.nsIPushObserverNotification); + notification.pushEndpoint = aPushRecord.pushEndpoint; + notification.version = aPushRecord.version; + notification.data = ""; + Services.obs.notifyObservers( + notification, + "push-notification", + aPushRecord.scope + ); // If permission has been revoked, trash the message. if(Services.perms.testExactPermission(scopeURI, "push") != Ci.nsIPermissionManager.ALLOW_ACTION) { @@ -1363,24 +1386,38 @@ this.PushService = { * Called on message from the child process. aPageRecord is an object sent by * navigator.push, identifying the sending page and other fields. */ + _registerWithServer: function(channelID, aPageRecord) { + debug("registerWithServer()"); - _registerWithServer: function(aPageRecord, aMessageManager) { + return this._sendRequest("register", {channelID: channelID}) + .then( + this._onRegisterSuccess.bind(this, aPageRecord, channelID), + this._onRegisterError.bind(this) + ); + }, + + _generateID: function() { let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] .getService(Ci.nsIUUIDGenerator); // generateUUID() gives a UUID surrounded by {...}, slice them off. - let channelID = uuidGenerator.generateUUID().toString().slice(1, -1); + return uuidGenerator.generateUUID().toString().slice(1, -1); + }, - this._sendRequest("register", {channelID: channelID}) - .then( - this._onRegisterSuccess.bind(this, aPageRecord, channelID), - this._onRegisterError.bind(this, aPageRecord, aMessageManager) - ) - .then( - function(message) { - aMessageManager.sendAsyncMessage("PushService:Register:OK", message); - }, - function(message) { - aMessageManager.sendAsyncMessage("PushService:Register:KO", message); + _register: function(aPageRecord) { + let recordPromise = new Promise((resolve, reject) => + this._db.getByScope(aPageRecord.scope, resolve, reject)); + + return recordPromise.then( + pushRecord => { + if (pushRecord == null) { + let channelID = this._generateID(); + return this._registerWithServer(channelID, aPageRecord); + } + return pushRecord; + }, + error => { + debug("getByScope failed"); + throw "Database error"; } ); }, @@ -1388,17 +1425,20 @@ this.PushService = { register: function(aPageRecord, aMessageManager) { debug("register(): " + JSON.stringify(aPageRecord)); - this._db.getByScope(aPageRecord.scope, + this._register(aPageRecord).then( function(aPageRecord, aMessageManager, pushRecord) { - if (pushRecord == null) { - this._registerWithServer(aPageRecord, aMessageManager); - } - else { - this._onRegistrationSuccess(aPageRecord, aMessageManager, pushRecord); - } + let message = { + requestID: aPageRecord.requestID, + pushEndpoint: pushRecord.pushEndpoint + }; + aMessageManager.sendAsyncMessage("PushService:Register:OK", message); }.bind(this, aPageRecord, aMessageManager), - function () { - debug("getByScope failed"); + function(error) { + let message = { + requestID: aPageRecord.requestID, + error + }; + aMessageManager.sendAsyncMessage("PushService:Register:KO", message); } ); }, @@ -1409,19 +1449,15 @@ this.PushService = { */ _onRegisterSuccess: function(aPageRecord, generatedChannelID, data) { debug("_onRegisterSuccess()"); - let deferred = Promise.defer(); - let message = { requestID: aPageRecord.requestID }; if (typeof data.channelID !== "string") { - debug("Invalid channelID " + message); - message["error"] = "Invalid channelID received"; - throw message; + debug("Invalid channelID " + data.channelID); + throw "Invalid channelID received"; } else if (data.channelID != generatedChannelID) { debug("Server replied with different channelID " + data.channelID + " than what UA generated " + generatedChannelID); - message["error"] = "Server sent 200 status code but different channelID"; - throw message; + throw "Server sent 200 status code but different channelID"; } try { @@ -1429,8 +1465,7 @@ this.PushService = { } catch (e) { debug("Invalid pushEndpoint " + data.pushEndpoint); - message["error"] = "Invalid pushEndpoint " + data.pushEndpoint; - throw message; + throw "Invalid pushEndpoint " + data.pushEndpoint; } let record = { @@ -1443,33 +1478,30 @@ this.PushService = { debug("scope in _onRegisterSuccess: " + aPageRecord.scope) - this._updatePushRecord(record) + return this._updatePushRecord(record) .then( function() { - message["pushEndpoint"] = data.pushEndpoint; - deferred.resolve(message); + return record; }, function(error) { // Unable to save. this._send("unregister", {channelID: record.channelID}); - message["error"] = error; - deferred.reject(message); + throw error; }.bind(this) ); - - return deferred.promise; }, /** * Exceptions thrown in _onRegisterError are caught by the promise obtained * from _sendRequest, causing the promise to be rejected instead. */ - _onRegisterError: function(aPageRecord, aMessageManager, reply) { + _onRegisterError: function(reply) { debug("_onRegisterError()"); if (!reply.error) { debug("Called without valid error message!"); + throw "Registration error"; } - throw { requestID: aPageRecord.requestID, error: reply.error }; + throw reply.error; }, /** @@ -1496,78 +1528,99 @@ this.PushService = { * messages from the server, and have the client acknowledge. On a server, * data is cheap, reliable notification is not. */ - unregister: function(aPageRecord, aMessageManager) { - debug("unregister() " + JSON.stringify(aPageRecord)); + _unregister: function(aPageRecord) { + debug("unregisterWithServer()"); + let deferred = Promise.defer(); let fail = function(error) { debug("unregister() fail() error " + error); - let message = {requestID: aPageRecord.requestID, error: error}; - aMessageManager.sendAsyncMessage("PushService:Unregister:KO", message); + deferred.reject(error); + }; + + if (!aPageRecord.scope) { + fail("NotFoundError"); + return deferred.promise; } - this._db.getByPushEndpoint(aPageRecord.pushEndpoint, function(record) { + this._db.getByScope(aPageRecord.scope, function(record) { // If the endpoint didn't exist, let's just fail. if (record === undefined) { fail("NotFoundError"); return; } - // Non-owner tried to unregister, say success, but don't do anything. - if (record.scope !== aPageRecord.scope) { - aMessageManager.sendAsyncMessage("PushService:Unregister:OK", { - requestID: aPageRecord.requestID, - pushEndpoint: aPageRecord.pushEndpoint - }); - return; - } - this._db.delete(record.channelID, function() { // Let's be nice to the server and try to inform it, but we don't care // about the reply. this._send("unregister", {channelID: record.channelID}); + deferred.resolve(); + }.bind(this), fail); + }.bind(this), fail); + + return deferred.promise; + }, + + unregister: function(aPageRecord, aMessageManager) { + debug("unregister() " + JSON.stringify(aPageRecord)); + + this._unregister(aPageRecord).then( + () => { aMessageManager.sendAsyncMessage("PushService:Unregister:OK", { requestID: aPageRecord.requestID, pushEndpoint: aPageRecord.pushEndpoint }); - }.bind(this), fail); - }.bind(this), fail); + }, + error => { + aMessageManager.sendAsyncMessage("PushService:Unregister:KO", { + requestID: aPageRecord.requestID, + error + }); + } + ); }, /** * Called on message from the child process */ + _registration: function(aPageRecord) { + return new Promise((resolve, reject) => { + if (!aPageRecord.scope) { + reject("Database error"); + return; + } + this._db.getByScope(aPageRecord.scope, + pushRecord => { + let registration = null; + if (pushRecord) { + registration = { + pushEndpoint: pushRecord.pushEndpoint, + version: pushRecord.version + }; + } + resolve(registration); + }, + () => reject("Database error") + ); + }); + }, + registration: function(aPageRecord, aMessageManager) { debug("registration()"); - this._db.getByScope(aPageRecord.scope, - this._onRegistrationSuccess.bind(this, aPageRecord, aMessageManager), - this._onRegistrationError.bind(this, aPageRecord, aMessageManager)); - }, - _onRegistrationSuccess: function(aPageRecord, - aMessageManager, - pushRecord) { - - - let registration = null; - - if (pushRecord) { - registration = { - pushEndpoint: pushRecord.pushEndpoint, - version: pushRecord.version - }; - } - - aMessageManager.sendAsyncMessage("PushService:Registration:OK", { - requestID: aPageRecord.requestID, - registration: registration - }); - }, - - _onRegistrationError: function(aPageRecord, aMessageManager) { - aMessageManager.sendAsyncMessage("PushService:Registration:KO", { - requestID: aPageRecord.requestID, - error: "Database error" - }); + return this._registration(aPageRecord).then( + registration => { + aMessageManager.sendAsyncMessage("PushService:Registration:OK", { + requestID: aPageRecord.requestID, + registration + }); + }, + error => { + aMessageManager.sendAsyncMessage("PushService:Registration:KO", { + requestID: aPageRecord.requestID, + error + }); + } + ); }, // begin Push protocol handshake @@ -1730,6 +1783,17 @@ this.PushService = { } }, + /** + * Rejects all pending requests with errors. + */ + _cancelPendingRequests: function() { + for (let channelID in this._pendingRequests) { + let request = this._pendingRequests[channelID]; + delete this._pendingRequests[channelID]; + request.deferred.reject({status: 0, error: "CancelledError"}); + } + }, + /** * This method should be called only if the device is on a mobile network! */ @@ -1904,4 +1968,4 @@ this.PushService = { ".mcc" + ("00" + networkInfo.mcc).slice(-3) + ".3gppnetwork.org"; queryDNSForDomain(netidAddress, callback); } -} +}; diff --git a/dom/push/PushServiceLauncher.js b/dom/push/PushServiceLauncher.js deleted file mode 100644 index e9ec4015c147..000000000000 --- a/dom/push/PushServiceLauncher.js +++ /dev/null @@ -1,50 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -function PushServiceLauncher() { -}; - -PushServiceLauncher.prototype = { - classID: Components.ID("{4b8caa3b-3c58-4f3c-a7f5-7bd9cb24c11d}"), - - contractID: "@mozilla.org/push/ServiceLauncher;1", - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, - Ci.nsISupportsWeakReference]), - - observe: function observe(subject, topic, data) { - switch (topic) { - case "app-startup": - Services.obs.addObserver(this, "final-ui-startup", true); - break; - case "final-ui-startup": - Services.obs.removeObserver(this, "final-ui-startup"); - if (!Services.prefs.getBoolPref("dom.push.enabled")) { - return; - } - - let isParent = Cc["@mozilla.org/xre/runtime;1"] - .getService(Ci.nsIXULRuntime) - .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; - - if (isParent) { - Cu.import("resource://gre/modules/PushService.jsm"); - PushService.init(); - } - break; - } - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PushServiceLauncher]); diff --git a/dom/push/moz.build b/dom/push/moz.build index 96b273fa818f..a912350af0b4 100644 --- a/dom/push/moz.build +++ b/dom/push/moz.build @@ -6,7 +6,7 @@ EXTRA_COMPONENTS += [ 'Push.js', 'Push.manifest', - 'PushServiceLauncher.js', + 'PushNotificationService.js', ] EXTRA_JS_MODULES += [ From c32f94ac3c61515d9b3700bbed96a9a177f820c4 Mon Sep 17 00:00:00 2001 From: Kit Cambridge Date: Tue, 21 Apr 2015 20:10:50 +0200 Subject: [PATCH 007/241] Bug 1150683 - Add xpcshell test hooks to PushService.jsm. r=dougt --- dom/push/PushService.jsm | 156 ++++++++++++++++++++++++++++++++--------------- dom/push/moz.build | 2 +- 2 files changed, 108 insertions(+), 50 deletions(-) --- dom/push/PushService.jsm | 156 +++++++++++++++++++++++++++------------ dom/push/moz.build | 2 +- 2 files changed, 108 insertions(+), 50 deletions(-) diff --git a/dom/push/PushService.jsm b/dom/push/PushService.jsm index 1bcffbeb1943..c4d10a372fb4 100644 --- a/dom/push/PushService.jsm +++ b/dom/push/PushService.jsm @@ -33,9 +33,11 @@ XPCOMUtils.defineLazyServiceGetter(this, "gDNSService", XPCOMUtils.defineLazyModuleGetter(this, "AlarmService", "resource://gre/modules/AlarmService.jsm"); +#ifdef MOZ_B2G XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService", "@mozilla.org/power/powermanagerservice;1", "nsIPowerManagerService"); +#endif var threadManager = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager); @@ -217,8 +219,8 @@ this.PushDB.prototype = { function txnCb(aTxn, aStore) { aStore.clear(); }, - aSuccessCb(), - aErrorCb() + aSuccessCb, + aErrorCb ); } }; @@ -495,19 +497,42 @@ this.PushService = { this._ws.sendMsg(msg); }, - init: function() { + init: function(options = {}) { debug("init()"); if (this._started) { return; } + // Override the backing store for testing. + this._db = options.db; + if (!this._db) { + this._db = new PushDB(); + } + + // Override the default WebSocket factory function. The returned object + // must be null or satisfy the nsIWebSocketChannel interface. Used by + // the tests to provide a mock WebSocket implementation. + if (options.makeWebSocket) { + this._makeWebSocket = options.makeWebSocket; + } + + // Override the default UDP socket factory function. The returned object + // must be null or satisfy the nsIUDPSocket interface. Used by the + // UDP tests. + if (options.makeUDPSocket) { + this._makeUDPSocket = options.makeUDPSocket; + } + + this._networkInfo = options.networkInfo; + if (!this._networkInfo) { + this._networkInfo = PushNetworkInfo; + } + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] .getService(Ci.nsIFrameScriptLoader); globalMM.loadFrameScript("chrome://global/content/PushServiceChildPreload.js", true); - this._db = new PushDB(); - let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"] .getService(Ci.nsIMessageBroadcaster); @@ -544,7 +569,8 @@ this.PushService = { // On B2G both events fire, one after the other, when the network goes // online, so we explicitly check for the presence of NetworkManager and // don't add an observer for offline-status-changed on B2G. - Services.obs.addObserver(this, this._getNetworkStateChangeEventName(), false); + this._networkStateChangeEventName = this._networkInfo.getNetworkStateChangeEventName(); + Services.obs.addObserver(this, this._networkStateChangeEventName, false); // This is only used for testing. Different tests require connecting to // slightly different URLs. @@ -583,7 +609,7 @@ this.PushService = { prefs.ignore("debug", this); prefs.ignore("connection.enabled", this); prefs.ignore("serverURL", this); - Services.obs.removeObserver(this, this._getNetworkStateChangeEventName()); + Services.obs.removeObserver(this, this._networkStateChangeEventName); Services.obs.removeObserver(this, "webapps-clear-data", false); Services.obs.removeObserver(this, "xpcom-shutdown", false); @@ -697,7 +723,7 @@ this.PushService = { } // Save actual state of the network - let ns = this._getNetworkInformation(); + let ns = this._networkInfo.getNetworkInformation(); if (ns.ip) { // mobile @@ -815,27 +841,7 @@ this.PushService = { } }, - _beginWSSetup: function() { - debug("beginWSSetup()"); - if (this._currentState != STATE_SHUT_DOWN) { - debug("_beginWSSetup: Not in shutdown state! Current state " + - this._currentState); - return; - } - - if (!prefs.get("connection.enabled")) { - debug("_beginWSSetup: connection.enabled is not set to true. Aborting."); - return; - } - - // Stop any pending reconnects scheduled for the near future. - this._stopAlarm(); - - if (Services.io.offline) { - debug("Network is offline."); - return; - } - + _getServerURI: function() { let serverURL = prefs.get("serverURL"); if (!serverURL) { debug("No dom.push.serverURL found!"); @@ -850,26 +856,63 @@ this.PushService = { serverURL + ")"); return; } + return uri; + }, + _makeWebSocket: function(uri) { + if (!prefs.get("connection.enabled")) { + debug("_makeWebSocket: connection.enabled is not set to true. Aborting."); + return null; + } + + if (Services.io.offline) { + debug("Network is offline."); + return null; + } + + let socket; if (uri.scheme === "wss") { - this._ws = Cc["@mozilla.org/network/protocol;1?name=wss"] - .createInstance(Ci.nsIWebSocketChannel); + socket = Cc["@mozilla.org/network/protocol;1?name=wss"] + .createInstance(Ci.nsIWebSocketChannel); - this._ws.initLoadInfo(null, // aLoadingNode - Services.scriptSecurityManager.getSystemPrincipal(), - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_NORMAL, - Ci.nsIContentPolicy.TYPE_WEBSOCKET); + socket.initLoadInfo(null, // aLoadingNode + Services.scriptSecurityManager.getSystemPrincipal(), + null, // aTriggeringPrincipal + Ci.nsILoadInfo.SEC_NORMAL, + Ci.nsIContentPolicy.TYPE_WEBSOCKET); } else if (uri.scheme === "ws") { debug("Push over an insecure connection (ws://) is not allowed!"); - return; + return null; } else { debug("Unsupported websocket scheme " + uri.scheme); + return null; + } + return socket; + }, + + _beginWSSetup: function() { + debug("beginWSSetup()"); + if (this._currentState != STATE_SHUT_DOWN) { + debug("_beginWSSetup: Not in shutdown state! Current state " + + this._currentState); return; } + // Stop any pending reconnects scheduled for the near future. + this._stopAlarm(); + + let uri = this._getServerURI(); + if (!uri) { + return; + } + let socket = this._makeWebSocket(uri); + if (!socket) { + return; + } + this._ws = socket.QueryInterface(Ci.nsIWebSocketChannel); + debug("serverURL: " + uri.spec); this._wsListener = new PushWebSocketListener(this); this._ws.protocol = "push-notification"; @@ -877,7 +920,7 @@ this.PushService = { try { // Grab a wakelock before we open the socket to ensure we don't go to sleep // before connection the is opened. - this._ws.asyncOpen(uri, serverURL, this._wsListener, null); + this._ws.asyncOpen(uri, uri.spec, this._wsListener, null); this._acquireWakeLock(); this._currentState = STATE_WAITING_FOR_WS_START; } catch(e) { @@ -1012,6 +1055,8 @@ this.PushService = { }, _acquireWakeLock: function() { +#ifdef MOZ_B2G + // Disable the wake lock on non-B2G platforms to work around bug 1154492. if (!this._socketWakeLock) { debug("Acquiring Socket Wakelock"); this._socketWakeLock = gPowerManagerService.newWakeLock("cpu"); @@ -1029,10 +1074,12 @@ this.PushService = { // timers can be a little off and we don't want to go // to sleep just as the socket connected. this._requestTimeout + 1000, - Ci.nsITimer.ONE_SHOT); + Ci.nsITimer.TYPE_ONE_SHOT); +#endif }, _releaseWakeLock: function() { +#ifdef MOZ_B2G debug("Releasing Socket WakeLock"); if (this._socketWakeLockTimer) { this._socketWakeLockTimer.cancel(); @@ -1041,6 +1088,7 @@ this.PushService = { this._socketWakeLock.unlock(); this._socketWakeLock = null; } +#endif }, /** @@ -1652,7 +1700,7 @@ this.PushService = { this._currentState = STATE_WAITING_FOR_HELLO; } - this._getNetworkState((networkState) => { + this._networkInfo.getNetworkState((networkState) => { if (networkState.ip) { // Opening an available UDP port. this._listenForUDPWakeup(); @@ -1790,10 +1838,15 @@ this.PushService = { for (let channelID in this._pendingRequests) { let request = this._pendingRequests[channelID]; delete this._pendingRequests[channelID]; - request.deferred.reject({status: 0, error: "CancelledError"}); + request.deferred.reject({status: 0, error: "AbortError"}); } }, + _makeUDPSocket: function() { + return Cc["@mozilla.org/network/udp-socket;1"] + .createInstance(Ci.nsIUDPSocket); + }, + /** * This method should be called only if the device is on a mobile network! */ @@ -1810,9 +1863,12 @@ this.PushService = { return; } - this._udpServer = Cc["@mozilla.org/network/udp-socket;1"] - .createInstance(Ci.nsIUDPSocket); - this._udpServer.init(-1, false); + let socket = this._makeUDPSocket(); + if (!socket) { + return; + } + this._udpServer = socket.QueryInterface(Ci.nsIUDPSocket); + this._udpServer.init(-1, false, Services.scriptSecurityManager.getSystemPrincipal()); this._udpServer.asyncListen(this); debug("listenForUDPWakeup listening on " + this._udpServer.port); @@ -1838,12 +1894,14 @@ this.PushService = { debug("UDP Server socket was shutdown. Status: " + aStatus); this._udpServer = undefined; this._beginWSSetup(); - }, + } +}; +let PushNetworkInfo = { /** * Returns information about MCC-MNC and the IP of the current connection. */ - _getNetworkInformation: function() { + getNetworkInformation: function() { debug("getNetworkInformation()"); try { @@ -1894,14 +1952,14 @@ this.PushService = { * woken up by UDP (which currently just means having an mcc and mnc along * with an IP, and optionally a netid). */ - _getNetworkState: function(callback) { + getNetworkState: function(callback) { debug("getNetworkState()"); if (typeof callback !== 'function') { throw new Error("No callback method. Aborting push agent !"); } - var networkInfo = this._getNetworkInformation(); + var networkInfo = this.getNetworkInformation(); if (networkInfo.ip) { this._getMobileNetworkId(networkInfo, function(netid) { @@ -1919,7 +1977,7 @@ this.PushService = { }, // utility function used to add/remove observers in init() and shutdown() - _getNetworkStateChangeEventName: function() { + getNetworkStateChangeEventName: function() { try { Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager); return "network-active-changed"; diff --git a/dom/push/moz.build b/dom/push/moz.build index a912350af0b4..e14b182fc484 100644 --- a/dom/push/moz.build +++ b/dom/push/moz.build @@ -9,7 +9,7 @@ EXTRA_COMPONENTS += [ 'PushNotificationService.js', ] -EXTRA_JS_MODULES += [ +EXTRA_PP_JS_MODULES += [ 'PushService.jsm', ] From 47b180edd677a92f282c93727bc955d322e80477 Mon Sep 17 00:00:00 2001 From: Kit Cambridge Date: Tue, 21 Apr 2015 20:10:50 +0200 Subject: [PATCH 008/241] Bug 1150683 - Add xpcshell tests for nsIPushNotificationService. r=dougt --- dom/push/moz.build | 4 + dom/push/test/xpcshell/head.js | 450 +++++++++++++++++++++ dom/push/test/xpcshell/test_notification_ack.js | 127 ++++++ .../test/xpcshell/test_notification_duplicate.js | 82 ++++ dom/push/test/xpcshell/test_notification_error.js | 127 ++++++ .../test/xpcshell/test_notification_incomplete.js | 109 +++++ .../xpcshell/test_notification_version_string.js | 72 ++++ dom/push/test/xpcshell/test_register_case.js | 64 +++ dom/push/test/xpcshell/test_register_flush.js | 103 +++++ .../test/xpcshell/test_register_invalid_channel.js | 60 +++ .../xpcshell/test_register_invalid_endpoint.js | 62 +++ .../test/xpcshell/test_register_invalid_json.js | 61 +++ dom/push/test/xpcshell/test_register_no_id.js | 65 +++ .../test/xpcshell/test_register_request_queue.js | 65 +++ dom/push/test/xpcshell/test_register_rollback.js | 88 ++++ dom/push/test/xpcshell/test_register_success.js | 76 ++++ dom/push/test/xpcshell/test_register_timeout.js | 102 +++++ dom/push/test/xpcshell/test_register_wrong_id.js | 71 ++++ dom/push/test/xpcshell/test_register_wrong_type.js | 67 +++ dom/push/test/xpcshell/test_registration_error.js | 39 ++ .../xpcshell/test_registration_missing_scope.js | 28 ++ dom/push/test/xpcshell/test_registration_none.js | 28 ++ .../test/xpcshell/test_registration_success.js | 67 +++ .../test/xpcshell/test_unregister_empty_scope.js | 37 ++ dom/push/test/xpcshell/test_unregister_error.js | 65 +++ .../test/xpcshell/test_unregister_invalid_json.js | 78 ++++ .../test/xpcshell/test_unregister_not_found.js | 35 ++ dom/push/test/xpcshell/test_unregister_success.js | 60 +++ dom/push/test/xpcshell/xpcshell.ini | 32 ++ 29 files changed, 2324 insertions(+) create mode 100644 dom/push/test/xpcshell/head.js create mode 100644 dom/push/test/xpcshell/test_notification_ack.js create mode 100644 dom/push/test/xpcshell/test_notification_duplicate.js create mode 100644 dom/push/test/xpcshell/test_notification_error.js create mode 100644 dom/push/test/xpcshell/test_notification_incomplete.js create mode 100644 dom/push/test/xpcshell/test_notification_version_string.js create mode 100644 dom/push/test/xpcshell/test_register_case.js create mode 100644 dom/push/test/xpcshell/test_register_flush.js create mode 100644 dom/push/test/xpcshell/test_register_invalid_channel.js create mode 100644 dom/push/test/xpcshell/test_register_invalid_endpoint.js create mode 100644 dom/push/test/xpcshell/test_register_invalid_json.js create mode 100644 dom/push/test/xpcshell/test_register_no_id.js create mode 100644 dom/push/test/xpcshell/test_register_request_queue.js create mode 100644 dom/push/test/xpcshell/test_register_rollback.js create mode 100644 dom/push/test/xpcshell/test_register_success.js create mode 100644 dom/push/test/xpcshell/test_register_timeout.js create mode 100644 dom/push/test/xpcshell/test_register_wrong_id.js create mode 100644 dom/push/test/xpcshell/test_register_wrong_type.js create mode 100644 dom/push/test/xpcshell/test_registration_error.js create mode 100644 dom/push/test/xpcshell/test_registration_missing_scope.js create mode 100644 dom/push/test/xpcshell/test_registration_none.js create mode 100644 dom/push/test/xpcshell/test_registration_success.js create mode 100644 dom/push/test/xpcshell/test_unregister_empty_scope.js create mode 100644 dom/push/test/xpcshell/test_unregister_error.js create mode 100644 dom/push/test/xpcshell/test_unregister_invalid_json.js create mode 100644 dom/push/test/xpcshell/test_unregister_not_found.js create mode 100644 dom/push/test/xpcshell/test_unregister_success.js create mode 100644 dom/push/test/xpcshell/xpcshell.ini --- dom/push/moz.build | 4 + dom/push/test/xpcshell/head.js | 450 ++++++++++++++++++ .../test/xpcshell/test_notification_ack.js | 127 +++++ .../xpcshell/test_notification_duplicate.js | 82 ++++ .../test/xpcshell/test_notification_error.js | 127 +++++ .../xpcshell/test_notification_incomplete.js | 109 +++++ .../test_notification_version_string.js | 72 +++ dom/push/test/xpcshell/test_register_case.js | 64 +++ dom/push/test/xpcshell/test_register_flush.js | 103 ++++ .../xpcshell/test_register_invalid_channel.js | 60 +++ .../test_register_invalid_endpoint.js | 62 +++ .../xpcshell/test_register_invalid_json.js | 61 +++ dom/push/test/xpcshell/test_register_no_id.js | 65 +++ .../xpcshell/test_register_request_queue.js | 65 +++ .../test/xpcshell/test_register_rollback.js | 88 ++++ .../test/xpcshell/test_register_success.js | 76 +++ .../test/xpcshell/test_register_timeout.js | 102 ++++ .../test/xpcshell/test_register_wrong_id.js | 71 +++ .../test/xpcshell/test_register_wrong_type.js | 67 +++ .../test/xpcshell/test_registration_error.js | 39 ++ .../test_registration_missing_scope.js | 28 ++ .../test/xpcshell/test_registration_none.js | 28 ++ .../xpcshell/test_registration_success.js | 67 +++ .../xpcshell/test_unregister_empty_scope.js | 37 ++ .../test/xpcshell/test_unregister_error.js | 65 +++ .../xpcshell/test_unregister_invalid_json.js | 78 +++ .../xpcshell/test_unregister_not_found.js | 35 ++ .../test/xpcshell/test_unregister_success.js | 60 +++ dom/push/test/xpcshell/xpcshell.ini | 32 ++ 29 files changed, 2324 insertions(+) create mode 100644 dom/push/test/xpcshell/head.js create mode 100644 dom/push/test/xpcshell/test_notification_ack.js create mode 100644 dom/push/test/xpcshell/test_notification_duplicate.js create mode 100644 dom/push/test/xpcshell/test_notification_error.js create mode 100644 dom/push/test/xpcshell/test_notification_incomplete.js create mode 100644 dom/push/test/xpcshell/test_notification_version_string.js create mode 100644 dom/push/test/xpcshell/test_register_case.js create mode 100644 dom/push/test/xpcshell/test_register_flush.js create mode 100644 dom/push/test/xpcshell/test_register_invalid_channel.js create mode 100644 dom/push/test/xpcshell/test_register_invalid_endpoint.js create mode 100644 dom/push/test/xpcshell/test_register_invalid_json.js create mode 100644 dom/push/test/xpcshell/test_register_no_id.js create mode 100644 dom/push/test/xpcshell/test_register_request_queue.js create mode 100644 dom/push/test/xpcshell/test_register_rollback.js create mode 100644 dom/push/test/xpcshell/test_register_success.js create mode 100644 dom/push/test/xpcshell/test_register_timeout.js create mode 100644 dom/push/test/xpcshell/test_register_wrong_id.js create mode 100644 dom/push/test/xpcshell/test_register_wrong_type.js create mode 100644 dom/push/test/xpcshell/test_registration_error.js create mode 100644 dom/push/test/xpcshell/test_registration_missing_scope.js create mode 100644 dom/push/test/xpcshell/test_registration_none.js create mode 100644 dom/push/test/xpcshell/test_registration_success.js create mode 100644 dom/push/test/xpcshell/test_unregister_empty_scope.js create mode 100644 dom/push/test/xpcshell/test_unregister_error.js create mode 100644 dom/push/test/xpcshell/test_unregister_invalid_json.js create mode 100644 dom/push/test/xpcshell/test_unregister_not_found.js create mode 100644 dom/push/test/xpcshell/test_unregister_success.js create mode 100644 dom/push/test/xpcshell/xpcshell.ini diff --git a/dom/push/moz.build b/dom/push/moz.build index e14b182fc484..bd344d0b0968 100644 --- a/dom/push/moz.build +++ b/dom/push/moz.build @@ -16,3 +16,7 @@ EXTRA_PP_JS_MODULES += [ MOCHITEST_MANIFESTS += [ 'test/mochitest.ini', ] + +XPCSHELL_TESTS_MANIFESTS += [ + 'test/xpcshell/xpcshell.ini', +] diff --git a/dom/push/test/xpcshell/head.js b/dom/push/test/xpcshell/head.js new file mode 100644 index 000000000000..7d5c3f70067d --- /dev/null +++ b/dom/push/test/xpcshell/head.js @@ -0,0 +1,450 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import('resource://gre/modules/XPCOMUtils.jsm'); +Cu.import('resource://gre/modules/Services.jsm'); +Cu.import('resource://gre/modules/Timer.jsm'); +Cu.import('resource://gre/modules/Promise.jsm'); +Cu.import('resource://gre/modules/Preferences.jsm'); + +const serviceExports = Cu.import('resource://gre/modules/PushService.jsm', {}); +const servicePrefs = new Preferences('dom.push.'); + +XPCOMUtils.defineLazyServiceGetter( + this, + "PushNotificationService", + "@mozilla.org/push/NotificationService;1", + "nsIPushNotificationService" +); + +const DEFAULT_TIMEOUT = 5000; + +const WEBSOCKET_CLOSE_GOING_AWAY = 1001; + +// Stop and clean up after the PushService. +Services.obs.addObserver(function observe(subject, topic, data) { + Services.obs.removeObserver(observe, topic, false); + serviceExports.PushService.uninit(); + // Occasionally, `profile-change-teardown` and `xpcom-shutdown` will fire + // before the PushService and AlarmService finish writing to IndexedDB. This + // causes spurious errors and crashes, so we spin the event loop to let the + // writes finish. + let done = false; + setTimeout(() => done = true, 1000); + let thread = Services.tm.mainThread; + while (!done) { + try { + thread.processNextEvent(true); + } catch (e) { + Cu.reportError(e); + } + } +}, 'profile-change-net-teardown', false); + +/** + * Gates a function so that it is called only after the wrapper is called a + * given number of times. + * + * @param {Number} times The number of wrapper calls before |func| is called. + * @param {Function} func The function to gate. + * @returns {Function} The gated function wrapper. + */ +function after(times, func) { + return function afterFunc() { + if (--times <= 0) { + return func.apply(this, arguments); + } + }; +} + +/** + * Wraps a Push database in a proxy that returns promises for all asynchronous + * methods. This makes it easier to test the database code with Task.jsm. + * + * @param {PushDB} db A Push database. + * @returns {Proxy} A proxy that traps function property gets and returns + * promisified functions. + */ +function promisifyDatabase(db) { + return new Proxy(db, { + get(target, property) { + let method = target[property]; + if (typeof method != 'function') { + return method; + } + return function(...params) { + return new Promise((resolve, reject) => { + method.call(target, ...params, resolve, reject); + }); + }; + } + }); +} + +/** + * Clears and closes an open Push database. + * + * @param {PushDB} db A Push database. + * @returns {Promise} A promise that fulfills when the database is closed. + */ +function cleanupDatabase(db) { + return new Promise(resolve => { + function close() { + db.close(); + resolve(); + } + db.drop(close, close); + }); +} + +/** + * Defers one or more callbacks until the next turn of the event loop. Multiple + * callbacks are executed in order. + * + * @param {Function[]} callbacks The callbacks to execute. One callback will be + * executed per tick. + */ +function waterfall(...callbacks) { + callbacks.reduce((promise, callback) => promise.then(() => { + callback(); + }), Promise.resolve()).catch(Cu.reportError); +} + +/** + * Waits for an observer notification to fire. + * + * @param {String} topic The notification topic. + * @returns {Promise} A promise that fulfills when the notification is fired. + */ +function promiseObserverNotification(topic, matchFunc) { + return new Promise((resolve, reject) => { + Services.obs.addObserver(function observe(subject, topic, data) { + let matches = typeof matchFunc != 'function' || matchFunc(subject, data); + if (!matches) { + return; + } + Services.obs.removeObserver(observe, topic, false); + resolve({subject, data}); + }, topic, false); + }); +} + +/** + * Waits for a promise to settle. Returns a rejected promise if the promise + * is not resolved or rejected within the given delay. + * + * @param {Promise} promise The pending promise. + * @param {Number} delay The time to wait before rejecting the promise. + * @param {String} [message] The rejection message if the promise times out. + * @returns {Promise} A promise that settles with the value of the pending + * promise, or rejects if the pending promise times out. + */ +function waitForPromise(promise, delay, message = 'Timed out waiting on promise') { + let timeoutDefer = Promise.defer(); + let id = setTimeout(() => timeoutDefer.reject(new Error(message)), delay); + return Promise.race([ + promise.then(value => { + clearTimeout(id); + return value; + }, error => { + clearTimeout(id); + throw error; + }), + timeoutDefer.promise + ]); +} + +/** + * Wraps an object in a proxy that traps property gets and returns stubs. If + * the stub is a function, the original value will be passed as the first + * argument. If the original value is a function, the proxy returns a wrapper + * that calls the stub; otherwise, the stub is called as a getter. + * + * @param {Object} target The object to wrap. + * @param {Object} stubs An object containing stubbed values and functions. + * @returns {Proxy} A proxy that returns stubs for property gets. + */ +function makeStub(target, stubs) { + return new Proxy(target, { + get(target, property) { + if (!stubs || typeof stubs != 'object' || !(property in stubs)) { + return target[property]; + } + let stub = stubs[property]; + if (typeof stub != 'function') { + return stub; + } + let original = target[property]; + if (typeof original != 'function') { + return stub.call(this, original); + } + return function callStub(...params) { + return stub.call(this, original, ...params); + }; + } + }); +} + +/** + * Disables `push` and `pushsubscriptionchange` service worker events for the + * given scopes. These events cause crashes in xpcshell, so we disable them + * for testing nsIPushNotificationService. + * + * @param {String[]} scopes A list of scope URLs. + */ +function disableServiceWorkerEvents(...scopes) { + for (let scope of scopes) { + Services.perms.add( + Services.io.newURI(scope, null, null), + 'push', + Ci.nsIPermissionManager.DENY_ACTION + ); + } +} + +/** + * Sets default PushService preferences. All pref names are prefixed with + * `dom.push.`; any additional preferences will override the defaults. + * + * @param {Object} [prefs] Additional preferences to set. + */ +function setPrefs(prefs = {}) { + let defaultPrefs = Object.assign({ + debug: true, + serverURL: 'wss://push.example.org', + 'connection.enabled': true, + userAgentID: '', + enabled: true, + // Disable adaptive pings and UDP wake-up by default; these are + // tested separately. + 'adaptive.enabled': false, + 'udp.wakeupEnabled': false, + // Defaults taken from /b2g/app/b2g.js. + requestTimeout: 10000, + retryBaseInterval: 5000, + pingInterval: 30 * 60 * 1000, + 'pingInterval.default': 3 * 60 * 1000, + 'pingInterval.mobile': 3 * 60 * 1000, + 'pingInterval.wifi': 3 * 60 * 1000, + 'adaptive.lastGoodPingInterval': 3 * 60 * 1000, + 'adaptive.lastGoodPingInterval.mobile': 3 * 60 * 1000, + 'adaptive.lastGoodPingInterval.wifi': 3 * 60 * 1000, + 'adaptive.gap': 60000, + 'adaptive.upperLimit': 29 * 60 * 1000, + // Misc. defaults. + 'adaptive.mobile': '' + }, prefs); + for (let pref in defaultPrefs) { + servicePrefs.set(pref, defaultPrefs[pref]); + } +} + +function compareAscending(a, b) { + return a > b ? 1 : a < b ? -1 : 0; +} + +/** + * Creates a mock WebSocket object that implements a subset of the + * nsIWebSocketChannel interface used by the PushService. + * + * The given protocol handlers are invoked for each Simple Push command sent + * by the PushService. The ping handler is optional; all others will throw if + * the PushService sends a command for which no handler is registered. + * + * All nsIWebSocketListener methods will be called asynchronously. + * serverSendMsg() and serverClose() can be used to respond to client messages + * and close the "server" end of the connection, respectively. + * + * @param {nsIURI} originalURI The original WebSocket URL. + * @param {Function} options.onHello The "hello" handshake command handler. + * @param {Function} options.onRegister The "register" command handler. + * @param {Function} options.onUnregister The "unregister" command handler. + * @param {Function} options.onACK The "ack" command handler. + * @param {Function} [options.onPing] An optional ping handler. + */ +function MockWebSocket(originalURI, handlers = {}) { + this._originalURI = originalURI; + this._onHello = handlers.onHello; + this._onRegister = handlers.onRegister; + this._onUnregister = handlers.onUnregister; + this._onACK = handlers.onACK; + this._onPing = handlers.onPing; +} + +MockWebSocket.prototype = { + _originalURI: null, + _onHello: null, + _onRegister: null, + _onUnregister: null, + _onACK: null, + _onPing: null, + + _listener: null, + _context: null, + + QueryInterface: XPCOMUtils.generateQI([ + Ci.nsISupports, + Ci.nsIWebSocketChannel + ]), + + get originalURI() { + return this._originalURI; + }, + + asyncOpen(uri, origin, listener, context) { + this._listener = listener; + this._context = context; + waterfall(() => this._listener.onStart(this._context)); + }, + + _handleMessage(msg) { + let messageType, request; + if (msg == '{}') { + request = {}; + messageType = 'ping'; + } else { + request = JSON.parse(msg); + messageType = request.messageType; + } + switch (messageType) { + case 'hello': + if (typeof this._onHello != 'function') { + throw new Error('Unexpected handshake request'); + } + this._onHello(request); + break; + + case 'register': + if (typeof this._onRegister != 'function') { + throw new Error('Unexpected register request'); + } + this._onRegister(request); + break; + + case 'unregister': + if (typeof this._onUnregister != 'function') { + throw new Error('Unexpected unregister request'); + } + this._onUnregister(request); + break; + + case 'ack': + if (typeof this._onACK != 'function') { + throw new Error('Unexpected acknowledgement'); + } + this._onACK(request); + break; + + case 'ping': + if (typeof this._onPing == 'function') { + this._onPing(request); + } else { + // Echo ping packets. + this.serverSendMsg('{}'); + } + break; + + default: + throw new Error('Unexpected message: ' + messageType); + } + }, + + sendMsg(msg) { + this._handleMessage(msg); + }, + + close(code, reason) { + waterfall(() => this._listener.onStop(this._context, Cr.NS_OK)); + }, + + /** + * Responds with the given message, calling onMessageAvailable() and + * onAcknowledge() synchronously. Throws if the message is not a string. + * Used by the tests to respond to client commands. + * + * @param {String} msg The message to send to the client. + */ + serverSendMsg(msg) { + if (typeof msg != 'string') { + throw new Error('Invalid response message'); + } + waterfall( + () => this._listener.onMessageAvailable(this._context, msg), + () => this._listener.onAcknowledge(this._context, 0) + ); + }, + + /** + * Closes the server end of the connection, calling onServerClose() + * followed by onStop(). Used to test abrupt connection termination + * and UDP wake-up. + * + * @param {Number} [statusCode] The WebSocket connection close code. + * @param {String} [reason] The connection close reason. + */ + serverClose(statusCode, reason = '') { + if (!isFinite(statusCode)) { + statusCode = WEBSOCKET_CLOSE_GOING_AWAY; + } + waterfall( + () => this._listener.onServerClose(this._context, statusCode, reason), + () => this._listener.onStop(this._context, Cr.NS_BASE_STREAM_CLOSED) + ); + } +}; + +/** + * Creates an object that exposes the same interface as NetworkInfo, used + * to simulate network status changes on Desktop. All methods returns empty + * carrier data. + */ +function MockDesktopNetworkInfo() {} + +MockDesktopNetworkInfo.prototype = { + getNetworkInformation() { + return {mcc: '', mnc: '', ip: ''}; + }, + + getNetworkState(callback) { + callback({mcc: '', mnc: '', ip: '', netid: ''}); + }, + + getNetworkStateChangeEventName() { + return 'network:offline-status-changed'; + } +}; + +/** + * Creates an object that exposes the same interface as NetworkInfo, used + * to simulate network status changes on B2G. + * + * @param {String} [info.mcc] The mobile country code. + * @param {String} [info.mnc] The mobile network code. + * @param {String} [info.ip] The carrier IP address. + * @param {String} [info.netid] The resolved network ID for UDP wake-up. + */ +function MockMobileNetworkInfo(info = {}) { + this._info = info; +} + +MockMobileNetworkInfo.prototype = { + _info: null, + + getNetworkInformation() { + let {mcc, mnc, ip} = this._info; + return {mcc, mnc, ip}; + }, + + getNetworkState(callback) { + let {mcc, mnc, ip, netid} = this._info; + callback({mcc, mnc, ip, netid}); + }, + + getNetworkStateChangeEventName() { + return 'network-active-changed'; + } +}; diff --git a/dom/push/test/xpcshell/test_notification_ack.js b/dom/push/test/xpcshell/test_notification_ack.js new file mode 100644 index 000000000000..48fd90ab8e5c --- /dev/null +++ b/dom/push/test/xpcshell/test_notification_ack.js @@ -0,0 +1,127 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +let userAgentID = '5ab1d1df-7a3d-4024-a469-b9e1bb399fad'; + +function run_test() { + do_get_profile(); + setPrefs({userAgentID}); + disableServiceWorkerEvents( + 'https://example.org/1', + 'https://example.org/2', + 'https://example.org/3' + ); + run_next_test(); +} + +add_task(function* test_notification_ack() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + let records = [{ + channelID: '21668e05-6da8-42c9-b8ab-9cc3f4d5630c', + pushEndpoint: 'https://example.com/update/1', + scope: 'https://example.org/1', + version: 1 + }, { + channelID: '9a5ff87f-47c9-4215-b2b8-0bdd38b4b305', + pushEndpoint: 'https://example.com/update/2', + scope: 'https://example.org/2', + version: 2 + }, { + channelID: '5477bfda-22db-45d4-9614-fee369630260', + pushEndpoint: 'https://example.com/update/3', + scope: 'https://example.org/3', + version: 3 + }]; + for (let record of records) { + yield promiseDB.put(record); + } + + let notifyPromise = Promise.all([ + promiseObserverNotification('push-notification'), + promiseObserverNotification('push-notification'), + promiseObserverNotification('push-notification') + ]); + + let acks = 0; + let ackDefer = Promise.defer(); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + equal(request.uaid, userAgentID, + 'Should send matching device IDs in handshake'); + deepEqual(request.channelIDs.sort(), [ + '21668e05-6da8-42c9-b8ab-9cc3f4d5630c', + '5477bfda-22db-45d4-9614-fee369630260', + '9a5ff87f-47c9-4215-b2b8-0bdd38b4b305' + ], 'Should send matching channel IDs in handshake'); + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + uaid: userAgentID, + status: 200 + })); + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: [{ + channelID: '21668e05-6da8-42c9-b8ab-9cc3f4d5630c', + version: 2 + }] + })); + }, + onACK(request) { + equal(request.messageType, 'ack', 'Should send acknowledgements'); + let updates = request.updates; + ok(Array.isArray(updates), + 'Should send an array of acknowledged updates'); + equal(updates.length, 1, + 'Should send one acknowledged update per packet'); + switch (++acks) { + case 1: + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: [{ + channelID: '9a5ff87f-47c9-4215-b2b8-0bdd38b4b305', + version: 4 + }, { + channelID: '5477bfda-22db-45d4-9614-fee369630260', + version: 6 + }] + })); + break; + + case 2: + deepEqual([{ + channelID: '9a5ff87f-47c9-4215-b2b8-0bdd38b4b305', + version: 4 + }], updates, 'Wrong updates for acknowledgement 2'); + break; + + case 3: + deepEqual([{ + channelID: '5477bfda-22db-45d4-9614-fee369630260', + version: 6 + }], updates, 'Wrong updates for acknowledgement 3'); + ackDefer.resolve(); + break; + + default: + ok(false, 'Unexpected acknowledgement ' + acks); + } + } + }); + } + }); + + yield waitForPromise(notifyPromise, DEFAULT_TIMEOUT, + 'Timed out waiting for notifications'); + yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for multiple acknowledgements'); +}); diff --git a/dom/push/test/xpcshell/test_notification_duplicate.js b/dom/push/test/xpcshell/test_notification_duplicate.js new file mode 100644 index 000000000000..05af29d36600 --- /dev/null +++ b/dom/push/test/xpcshell/test_notification_duplicate.js @@ -0,0 +1,82 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs(); + disableServiceWorkerEvents( + 'https://example.com/1', + 'https://example.com/2' + ); + run_next_test(); +} + +// Should acknowledge duplicate notifications, but not notify apps. +add_task(function* test_notification_duplicate() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + let records = [{ + channelID: '8d2d9400-3597-4c5a-8a38-c546b0043bcc', + pushEndpoint: 'https://example.org/update/1', + scope: 'https://example.com/1', + version: 2 + }, { + channelID: '27d1e393-03ef-4c72-a5e6-9e890dfccad0', + pushEndpoint: 'https://example.org/update/2', + scope: 'https://example.com/2', + version: 2 + }]; + for (let record of records) { + yield promiseDB.put(record); + } + + let notifyPromise = promiseObserverNotification('push-notification'); + + let acks = 0; + let ackDefer = Promise.defer(); + let ackDone = after(2, ackDefer.resolve); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: '1500e7d9-8cbe-4ee6-98da-7fa5d6a39852' + })); + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: [{ + channelID: '8d2d9400-3597-4c5a-8a38-c546b0043bcc', + version: 2 + }, { + channelID: '27d1e393-03ef-4c72-a5e6-9e890dfccad0', + version: 3 + }] + })); + }, + onACK: ackDone + }); + } + }); + + yield waitForPromise(notifyPromise, DEFAULT_TIMEOUT, + 'Timed out waiting for notifications'); + yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for stale acknowledgement'); + + let staleRecord = yield promiseDB.getByChannelID( + '8d2d9400-3597-4c5a-8a38-c546b0043bcc'); + strictEqual(staleRecord.version, 2, 'Wrong stale record version'); + + let updatedRecord = yield promiseDB.getByChannelID( + '27d1e393-03ef-4c72-a5e6-9e890dfccad0'); + strictEqual(updatedRecord.version, 3, 'Wrong updated record version'); +}); diff --git a/dom/push/test/xpcshell/test_notification_error.js b/dom/push/test/xpcshell/test_notification_error.js new file mode 100644 index 000000000000..5b5b64c849cb --- /dev/null +++ b/dom/push/test/xpcshell/test_notification_error.js @@ -0,0 +1,127 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs(); + disableServiceWorkerEvents( + 'https://example.com/a', + 'https://example.com/b', + 'https://example.com/c' + ); + run_next_test(); +} + +add_task(function* test_notification_error() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + let records = [{ + channelID: 'f04f1e46-9139-4826-b2d1-9411b0821283', + pushEndpoint: 'https://example.org/update/success-1', + scope: 'https://example.com/a', + version: 1 + }, { + channelID: '3c3930ba-44de-40dc-a7ca-8a133ec1a866', + pushEndpoint: 'https://example.org/update/error', + scope: 'https://example.com/b', + version: 2 + }, { + channelID: 'b63f7bef-0a0d-4236-b41e-086a69dfd316', + pushEndpoint: 'https://example.org/update/success-2', + scope: 'https://example.com/c', + version: 3 + }]; + for (let record of records) { + yield promiseDB.put(record); + } + + let notifyPromise = Promise.all([ + promiseObserverNotification( + 'push-notification', + (subject, data) => data == 'https://example.com/a' + ), + promiseObserverNotification( + 'push-notification', + (subject, data) => data == 'https://example.com/c' + ) + ]); + + let ackDefer = Promise.defer(); + let ackDone = after(records.length, ackDefer.resolve); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db: makeStub(db, { + getByChannelID(prev, channelID, successCb, failureCb) { + if (channelID == '3c3930ba-44de-40dc-a7ca-8a133ec1a866') { + return failureCb('splines not reticulated'); + } + return prev.call(this, channelID, successCb, failureCb); + } + }), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + deepEqual(request.channelIDs.sort(), [ + '3c3930ba-44de-40dc-a7ca-8a133ec1a866', + 'b63f7bef-0a0d-4236-b41e-086a69dfd316', + 'f04f1e46-9139-4826-b2d1-9411b0821283' + ], 'Wrong channel list'); + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: '3c7462fc-270f-45be-a459-b9d631b0d093' + })); + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: records.map(({channelID, version}) => + ({channelID, version: ++version})) + })); + }, + // Should acknowledge all received updates, even if updating + // IndexedDB fails. + onACK: ackDone + }); + } + }); + + let [a, c] = yield waitForPromise( + notifyPromise, + DEFAULT_TIMEOUT, + 'Timed out waiting for notifications' + ); + let aPush = a.subject.QueryInterface(Ci.nsIPushObserverNotification); + equal(aPush.pushEndpoint, 'https://example.org/update/success-1', + 'Wrong endpoint for notification A'); + equal(aPush.version, 2, 'Wrong version for notification A'); + + let cPush = c.subject.QueryInterface(Ci.nsIPushObserverNotification); + equal(cPush.pushEndpoint, 'https://example.org/update/success-2', + 'Wrong endpoint for notification C'); + equal(cPush.version, 4, 'Wrong version for notification C'); + + yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for acknowledgements'); + + let aRecord = yield promiseDB.getByScope('https://example.com/a'); + equal(aRecord.channelID, 'f04f1e46-9139-4826-b2d1-9411b0821283', + 'Wrong channel ID for record A'); + strictEqual(aRecord.version, 2, + 'Should return the new version for record A'); + + let bRecord = yield promiseDB.getByScope('https://example.com/b'); + equal(bRecord.channelID, '3c3930ba-44de-40dc-a7ca-8a133ec1a866', + 'Wrong channel ID for record B'); + strictEqual(bRecord.version, 2, + 'Should return the previous version for record B'); + + let cRecord = yield promiseDB.getByScope('https://example.com/c'); + equal(cRecord.channelID, 'b63f7bef-0a0d-4236-b41e-086a69dfd316', + 'Wrong channel ID for record C'); + strictEqual(cRecord.version, 4, + 'Should return the new version for record C'); +}); diff --git a/dom/push/test/xpcshell/test_notification_incomplete.js b/dom/push/test/xpcshell/test_notification_incomplete.js new file mode 100644 index 000000000000..b7f065f5ac6e --- /dev/null +++ b/dom/push/test/xpcshell/test_notification_incomplete.js @@ -0,0 +1,109 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs(); + disableServiceWorkerEvents( + 'https://example.com/page/1', + 'https://example.com/page/2', + 'https://example.com/page/3', + 'https://example.com/page/4' + ); + run_next_test(); +} + +add_task(function* test_notification_incomplete() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + let records = [{ + channelID: '123', + pushEndpoint: 'https://example.org/update/1', + scope: 'https://example.com/page/1', + version: 1 + }, { + channelID: '3ad1ed95-d37a-4d88-950f-22cbe2e240d7', + pushEndpoint: 'https://example.org/update/2', + scope: 'https://example.com/page/2', + version: 1 + }, { + channelID: 'd239498b-1c85-4486-b99b-205866e82d1f', + pushEndpoint: 'https://example.org/update/3', + scope: 'https://example.com/page/3', + version: 3 + }, { + channelID: 'a50de97d-b496-43ce-8b53-05522feb78db', + pushEndpoint: 'https://example.org/update/4', + scope: 'https://example.com/page/4', + version: 10 + }]; + for (let record of records) { + promiseDB.put(record); + } + + Services.obs.addObserver(function observe(subject, topic, data) { + ok(false, 'Should not deliver malformed updates'); + }, 'push-notification', false); + + let notificationDefer = Promise.defer(); + let notificationDone = after(2, notificationDefer.resolve); + let prevHandler = PushService._handleNotificationReply; + PushService._handleNotificationReply = function _handleNotificationReply() { + notificationDone(); + return prevHandler.apply(this, arguments); + }; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: '1ca1cf66-eeb4-4df7-87c1-d5c92906ab90' + })); + this.serverSendMsg(JSON.stringify({ + // Missing "updates" field; should ignore message. + messageType: 'notification' + })); + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: [{ + // Wrong channel ID field type. + channelID: 123, + version: 3 + }, { + // Missing version field. + channelID: '3ad1ed95-d37a-4d88-950f-22cbe2e240d7' + }, { + // Wrong version field type. + channelID: 'd239498b-1c85-4486-b99b-205866e82d1f', + version: true + }, { + // Negative versions should be ignored. + channelID: 'a50de97d-b496-43ce-8b53-05522feb78db', + version: -5 + }] + })); + }, + onACK() { + ok(false, 'Should not acknowledge malformed updates'); + } + }); + } + }); + + yield waitForPromise(notificationDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for incomplete notifications'); + + let storeRecords = yield promiseDB.getAllChannelIDs(); + storeRecords.sort(({pushEndpoint: a}, {pushEndpoint: b}) => + compareAscending(a, b)); + deepEqual(records, storeRecords, 'Should not update malformed records'); +}); diff --git a/dom/push/test/xpcshell/test_notification_version_string.js b/dom/push/test/xpcshell/test_notification_version_string.js new file mode 100644 index 000000000000..345346b56110 --- /dev/null +++ b/dom/push/test/xpcshell/test_notification_version_string.js @@ -0,0 +1,72 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs(); + disableServiceWorkerEvents( + 'https://example.net/case' + ); + run_next_test(); +} + +add_task(function* test_notification_version_string() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + yield promiseDB.put({ + channelID: '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b', + pushEndpoint: 'https://example.org/updates/1', + scope: 'https://example.com/page/1', + version: 2 + }); + + let notifyPromise = promiseObserverNotification('push-notification'); + + let ackDefer = Promise.defer(); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: 'ba31ac13-88d4-4984-8e6b-8731315a7cf8' + })); + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: [{ + channelID: '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b', + version: '4' + }] + })); + }, + onACK: ackDefer.resolve + }); + } + }); + + let {subject: notification, data: scope} = yield waitForPromise( + notifyPromise, + DEFAULT_TIMEOUT, + 'Timed out waiting for string notification' + ); + let message = notification.QueryInterface(Ci.nsIPushObserverNotification); + equal(scope, 'https://example.com/page/1', 'Wrong scope'); + equal(message.pushEndpoint, 'https://example.org/updates/1', + 'Wrong push endpoint'); + strictEqual(message.version, 4, 'Wrong version'); + + yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for string acknowledgement'); + + let storeRecord = yield promiseDB.getByChannelID( + '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b'); + strictEqual(storeRecord.version, 4, 'Wrong record version'); +}); diff --git a/dom/push/test/xpcshell/test_register_case.js b/dom/push/test/xpcshell/test_register_case.js new file mode 100644 index 000000000000..230c1bf1ced8 --- /dev/null +++ b/dom/push/test/xpcshell/test_register_case.js @@ -0,0 +1,64 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = '1760b1f5-c3ba-40e3-9344-adef7c18ab12'; + +function run_test() { + do_get_profile(); + setPrefs(); + disableServiceWorkerEvents( + 'https://example.net/case' + ); + run_next_test(); +} + +add_task(function* test_register_case() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'HELLO', + uaid: userAgentID, + status: 200 + })); + }, + onRegister(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'ReGiStEr', + uaid: userAgentID, + channelID: request.channelID, + status: 200, + pushEndpoint: 'https://example.com/update/case' + })); + } + }); + } + }); + + let newRecord = yield waitForPromise( + PushNotificationService.register('https://example.net/case'), + DEFAULT_TIMEOUT, + 'Mixed-case register response timed out' + ); + equal(newRecord.pushEndpoint, 'https://example.com/update/case', + 'Wrong push endpoint in registration record'); + equal(newRecord.scope, 'https://example.net/case', + 'Wrong scope in registration record'); + + let record = yield promiseDB.getByChannelID(newRecord.channelID); + equal(record.pushEndpoint, 'https://example.com/update/case', + 'Wrong push endpoint in database record'); + equal(record.scope, 'https://example.net/case', + 'Wrong scope in database record'); +}); diff --git a/dom/push/test/xpcshell/test_register_flush.js b/dom/push/test/xpcshell/test_register_flush.js new file mode 100644 index 000000000000..e747958898cf --- /dev/null +++ b/dom/push/test/xpcshell/test_register_flush.js @@ -0,0 +1,103 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = '9ce1e6d3-7bdb-4fe9-90a5-def1d64716f1'; +const channelID = 'c26892c5-6e08-4c16-9f0c-0044697b4d85'; + +function run_test() { + do_get_profile(); + setPrefs({ + userAgentID, + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.com/page/1', + 'https://example.com/page/2' + ); + run_next_test(); +} + +add_task(function* test_register_flush() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + let record = { + channelID: '9bcc7efb-86c7-4457-93ea-e24e6eb59b74', + pushEndpoint: 'https://example.org/update/1', + scope: 'https://example.com/page/1', + version: 2 + }; + yield promiseDB.put(record); + + let notifyPromise = promiseObserverNotification('push-notification'); + + let ackDefer = Promise.defer(); + let ackDone = after(2, ackDefer.resolve); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + }, + onRegister(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'notification', + updates: [{ + channelID: request.channelID, + version: 2 + }, { + channelID: '9bcc7efb-86c7-4457-93ea-e24e6eb59b74', + version: 3 + }] + })); + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200, + channelID: request.channelID, + uaid: userAgentID, + pushEndpoint: 'https://example.org/update/2' + })); + }, + onACK: ackDone + }); + } + }); + + let newRecord = yield PushNotificationService.register( + 'https://example.com/page/2' + ); + equal(newRecord.pushEndpoint, 'https://example.org/update/2', + 'Wrong push endpoint in record'); + equal(newRecord.scope, 'https://example.com/page/2', + 'Wrong scope in record'); + + let {data: scope} = yield waitForPromise(notifyPromise, DEFAULT_TIMEOUT, + 'Timed out waiting for notification'); + equal(scope, 'https://example.com/page/1', 'Wrong notification scope'); + + yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for acknowledgements'); + + let prevRecord = yield promiseDB.getByChannelID( + '9bcc7efb-86c7-4457-93ea-e24e6eb59b74'); + equal(prevRecord.pushEndpoint, 'https://example.org/update/1', + 'Wrong existing push endpoint'); + strictEqual(prevRecord.version, 3, + 'Should record version updates sent before register responses'); + + let registeredRecord = yield promiseDB.getByChannelID(newRecord.channelID); + equal(registeredRecord.pushEndpoint, 'https://example.org/update/2', + 'Wrong new push endpoint'); + ok(!registeredRecord.version, 'Should not record premature updates'); +}); diff --git a/dom/push/test/xpcshell/test_register_invalid_channel.js b/dom/push/test/xpcshell/test_register_invalid_channel.js new file mode 100644 index 000000000000..1eb0332e2f7e --- /dev/null +++ b/dom/push/test/xpcshell/test_register_invalid_channel.js @@ -0,0 +1,60 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = '52b2b04c-b6cc-42c6-abdf-bef9cbdbea00'; +const channelID = 'cafed00d'; + +function run_test() { + do_get_profile(); + setPrefs(); + disableServiceWorkerEvents( + 'https://example.com/invalid-channel' + ); + run_next_test(); +} + +add_task(function* test_register_invalid_channel() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + + PushService._generateID = () => channelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + uaid: userAgentID, + status: 200 + })); + }, + onRegister(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 403, + channelID, + error: 'Invalid channel ID' + })); + } + }); + } + }); + + yield rejects( + PushNotificationService.register('https://example.com/invalid-channel'), + function(error) { + return error == 'Invalid channel ID'; + }, + 'Wrong error for invalid channel ID' + ); + + let record = yield promiseDB.getByChannelID(channelID); + ok(!record, 'Should not store records for error responses'); +}); diff --git a/dom/push/test/xpcshell/test_register_invalid_endpoint.js b/dom/push/test/xpcshell/test_register_invalid_endpoint.js new file mode 100644 index 000000000000..cf5e0fa55270 --- /dev/null +++ b/dom/push/test/xpcshell/test_register_invalid_endpoint.js @@ -0,0 +1,62 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = 'c9a12e81-ea5e-40f9-8bf4-acee34621671'; +const channelID = 'c0660af8-b532-4931-81f0-9fd27a12d6ab'; + +function run_test() { + do_get_profile(); + setPrefs(); + disableServiceWorkerEvents( + 'https://example.net/page/invalid-endpoint' + ); + run_next_test(); +} + +add_task(function* test_register_invalid_endpoint() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + + PushService._generateID = () => channelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID, + })); + }, + onRegister(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200, + channelID, + uaid: userAgentID, + pushEndpoint: '!@#$%^&*' + })); + } + }); + } + }); + + yield rejects( + PushNotificationService.register( + 'https://example.net/page/invalid-endpoint'), + function(error) { + return error && error.contains('Invalid pushEndpoint'); + }, + 'Wrong error for invalid endpoint' + ); + + let record = yield promiseDB.getByChannelID(channelID); + ok(!record, 'Should not store records with invalid endpoints'); +}); diff --git a/dom/push/test/xpcshell/test_register_invalid_json.js b/dom/push/test/xpcshell/test_register_invalid_json.js new file mode 100644 index 000000000000..778a1985b054 --- /dev/null +++ b/dom/push/test/xpcshell/test_register_invalid_json.js @@ -0,0 +1,61 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = '8271186b-8073-43a3-adf6-225bd44a8b0a'; +const channelID = '2d08571e-feab-48a0-9f05-8254c3c7e61f'; + +function run_test() { + do_get_profile(); + setPrefs({ + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.net/page/invalid-json' + ); + run_next_test(); +} + +add_task(function* test_register_invalid_json() { + let helloDefer = Promise.defer(); + let helloDone = after(2, helloDefer.resolve); + let registers = 0; + + PushService._generateID = () => channelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + helloDone(); + }, + onRegister(request) { + equal(request.channelID, channelID, 'Register: wrong channel ID'); + this.serverSendMsg(');alert(1);('); + registers++; + } + }); + } + }); + + yield rejects( + PushNotificationService.register('https://example.net/page/invalid-json'), + function(error) { + return error == 'TimeoutError'; + }, + 'Wrong error for invalid JSON response' + ); + + yield waitForPromise(helloDefer.promise, DEFAULT_TIMEOUT, + 'Reconnect after invalid JSON response timed out'); + equal(registers, 1, 'Wrong register count'); +}); diff --git a/dom/push/test/xpcshell/test_register_no_id.js b/dom/push/test/xpcshell/test_register_no_id.js new file mode 100644 index 000000000000..b7658b5af0eb --- /dev/null +++ b/dom/push/test/xpcshell/test_register_no_id.js @@ -0,0 +1,65 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +let userAgentID = '9a2f9efe-2ebb-4bcb-a5d9-9e2b73d30afe'; +let channelID = '264c2ba0-f6db-4e84-acdb-bd225b62d9e3'; + +function run_test() { + do_get_profile(); + setPrefs({ + userAgentID, + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.com/incomplete' + ); + run_next_test(); +} + +add_task(function* test_register_no_id() { + let registers = 0; + let helloDefer = Promise.defer(); + let helloDone = after(2, helloDefer.resolve); + + PushService._generateID = () => channelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + helloDone(); + }, + onRegister(request) { + registers++; + equal(request.channelID, channelID, 'Register: wrong channel ID'); + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200 + })); + } + }); + } + }); + + yield rejects( + PushNotificationService.register('https://example.com/incomplete'), + function(error) { + return error == 'TimeoutError'; + }, + 'Wrong error for incomplete register response' + ); + + yield waitForPromise(helloDefer.promise, DEFAULT_TIMEOUT, + 'Reconnect after incomplete register response timed out'); + equal(registers, 1, 'Wrong register count'); +}); diff --git a/dom/push/test/xpcshell/test_register_request_queue.js b/dom/push/test/xpcshell/test_register_request_queue.js new file mode 100644 index 000000000000..46e1a97e8c93 --- /dev/null +++ b/dom/push/test/xpcshell/test_register_request_queue.js @@ -0,0 +1,65 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs({ + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.com/page/1' + ); + run_next_test(); +} + +add_task(function* test_register_request_queue() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + + let helloDefer = Promise.defer(); + let onHello = after(2, function onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: '54b08a9e-59c6-4ed7-bb54-f4fd60d6f606' + })); + helloDefer.resolve(); + }); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello, + onRegister() { + ok(false, 'Should cancel timed-out requests'); + } + }); + } + }); + + let firstRegister = PushNotificationService.register( + 'https://example.com/page/1' + ); + let secondRegister = PushNotificationService.register( + 'https://example.com/page/1' + ); + + yield waitForPromise(Promise.all([ + rejects(firstRegister, function(error) { + return error == 'TimeoutError'; + }, 'Should time out the first request'), + rejects(secondRegister, function(error) { + return error == 'TimeoutError'; + }, 'Should time out the second request') + ]), DEFAULT_TIMEOUT, 'Queued requests did not time out'); + + yield waitForPromise(helloDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for reconnect'); +}); diff --git a/dom/push/test/xpcshell/test_register_rollback.js b/dom/push/test/xpcshell/test_register_rollback.js new file mode 100644 index 000000000000..077ff2105c92 --- /dev/null +++ b/dom/push/test/xpcshell/test_register_rollback.js @@ -0,0 +1,88 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = 'b2546987-4f63-49b1-99f7-739cd3c40e44'; +const channelID = '35a820f7-d7dd-43b3-af21-d65352212ae3'; + +function run_test() { + do_get_profile(); + setPrefs({ + userAgentID, + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.com/storage-error' + ); + run_next_test(); +} + +add_task(function* test_register_rollback() { + let db = new PushDB(); + do_register_cleanup(() => cleanupDatabase(db)); + + let handshakes = 0; + let registers = 0; + let unregisterDefer = Promise.defer(); + PushService._generateID = () => channelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db: makeStub(db, { + put(prev, record, successCb, failureCb) { + failureCb('universe has imploded'); + } + }), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + handshakes++; + equal(request.uaid, userAgentID, 'Handshake: wrong device ID'); + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + }, + onRegister(request) { + equal(request.channelID, channelID, 'Register: wrong channel ID'); + registers++; + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200, + uaid: userAgentID, + channelID, + pushEndpoint: 'https://example.com/update/rollback' + })); + }, + onUnregister(request) { + equal(request.channelID, channelID, 'Unregister: wrong channel ID'); + this.serverSendMsg(JSON.stringify({ + messageType: 'unregister', + status: 200, + channelID + })); + unregisterDefer.resolve(); + } + }); + } + }); + + // Should return a rejected promise if storage fails. + yield rejects( + PushNotificationService.register('https://example.com/storage-error'), + function(error) { + return error == 'universe has imploded'; + }, + 'Wrong error for unregister database failure' + ); + + // Should send an out-of-band unregister request. + yield waitForPromise(unregisterDefer.promise, DEFAULT_TIMEOUT, + 'Unregister request timed out'); + equal(handshakes, 1, 'Wrong handshake count'); + equal(registers, 1, 'Wrong register count'); +}); diff --git a/dom/push/test/xpcshell/test_register_success.js b/dom/push/test/xpcshell/test_register_success.js new file mode 100644 index 000000000000..34493051196e --- /dev/null +++ b/dom/push/test/xpcshell/test_register_success.js @@ -0,0 +1,76 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = 'bd744428-f125-436a-b6d0-dd0c9845837f'; +const channelID = '0ef2ad4a-6c49-41ad-af6e-95d2425276bf'; + +function run_test() { + do_get_profile(); + setPrefs({ + userAgentID, + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.org/1' + ); + run_next_test(); +} + +add_task(function* test_register_success() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + + PushService._generateID = () => channelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(data) { + equal(data.messageType, 'hello', 'Handshake: wrong message type'); + equal(data.uaid, userAgentID, 'Handshake: wrong device ID'); + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + }, + onRegister(data) { + equal(data.messageType, 'register', 'Register: wrong message type'); + equal(data.channelID, channelID, 'Register: wrong channel ID'); + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200, + channelID: channelID, + uaid: userAgentID, + pushEndpoint: 'https://example.com/update/1', + })); + } + }); + } + }); + + let newRecord = yield PushNotificationService.register( + 'https://example.org/1' + ); + equal(newRecord.channelID, channelID, + 'Wrong channel ID in registration record'); + equal(newRecord.pushEndpoint, 'https://example.com/update/1', + 'Wrong push endpoint in registration record'); + equal(newRecord.scope, 'https://example.org/1', + 'Wrong scope in registration record'); + + let record = yield promiseDB.getByChannelID(channelID); + equal(record.channelID, channelID, + 'Wrong channel ID in database record'); + equal(record.pushEndpoint, 'https://example.com/update/1', + 'Wrong push endpoint in database record'); + equal(record.scope, 'https://example.org/1', + 'Wrong scope in database record'); +}); diff --git a/dom/push/test/xpcshell/test_register_timeout.js b/dom/push/test/xpcshell/test_register_timeout.js new file mode 100644 index 000000000000..28017d727530 --- /dev/null +++ b/dom/push/test/xpcshell/test_register_timeout.js @@ -0,0 +1,102 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = 'a4be0df9-b16d-4b5f-8f58-0f93b6f1e23d'; +const channelID = 'e1944e0b-48df-45e7-bdc0-d1fbaa7986d3'; + +function run_test() { + do_get_profile(); + setPrefs({ + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.net/page/timeout' + ); + run_next_test(); +} + +add_task(function* test_register_timeout() { + let handshakes = 0; + let timeoutDefer = Promise.defer(); + let registers = 0; + + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + + PushService._generateID = () => channelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + switch (handshakes) { + case 0: + equal(request.uaid, null, 'Should not include device ID'); + deepEqual(request.channelIDs, [], + 'Should include empty channel list'); + break; + + case 1: + // Should use the previously-issued device ID when reconnecting, + // but should not include the timed-out channel ID. + equal(request.uaid, userAgentID, + 'Should include device ID on reconnect'); + deepEqual(request.channelIDs, [], + 'Should not include failed channel ID'); + break; + + default: + ok(false, 'Unexpected reconnect attempt ' + handshakes); + } + handshakes++; + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID, + })); + }, + onRegister(request) { + equal(request.channelID, channelID, + 'Wrong channel ID in register request'); + setTimeout(() => { + // Should ignore replies for timed-out requests. + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200, + channelID: channelID, + uaid: userAgentID, + pushEndpoint: 'https://example.com/update/timeout', + })); + timeoutDefer.resolve(); + }, 2000); + registers++; + } + }); + } + }); + + yield rejects( + PushNotificationService.register('https://example.net/page/timeout'), + function(error) { + return error == 'TimeoutError'; + }, + 'Wrong error for request timeout' + ); + + let record = yield promiseDB.getByChannelID(channelID); + ok(!record, 'Should not store records for timed-out responses'); + + yield waitForPromise( + timeoutDefer.promise, + DEFAULT_TIMEOUT, + 'Reconnect timed out' + ); + equal(registers, 1, 'Should not handle timed-out register requests'); +}); diff --git a/dom/push/test/xpcshell/test_register_wrong_id.js b/dom/push/test/xpcshell/test_register_wrong_id.js new file mode 100644 index 000000000000..9ad15edeab68 --- /dev/null +++ b/dom/push/test/xpcshell/test_register_wrong_id.js @@ -0,0 +1,71 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = '84afc774-6995-40d1-9c90-8c34ddcd0cb4'; +const clientChannelID = '4b42a681c99e4dfbbb166a7e01a09b8b'; +const serverChannelID = '3f5aeb89c6e8405a9569619522783436'; + +function run_test() { + do_get_profile(); + setPrefs({ + userAgentID, + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.com/mismatched' + ); + run_next_test(); +} + +add_task(function* test_register_wrong_id() { + // Should reconnect after the register request times out. + let registers = 0; + let helloDefer = Promise.defer(); + let helloDone = after(2, helloDefer.resolve); + + PushService._generateID = () => clientChannelID; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + helloDone(); + }, + onRegister(request) { + equal(request.channelID, clientChannelID, + 'Register: wrong channel ID'); + registers++; + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200, + // Reply with a different channel ID. Since the ID is used as a + // nonce, the registration request will time out. + channelID: serverChannelID + })); + } + }); + } + }); + + yield rejects( + PushNotificationService.register('https://example.com/mismatched'), + function(error) { + return error == 'TimeoutError'; + }, + 'Wrong error for mismatched register reply' + ); + + yield waitForPromise(helloDefer.promise, DEFAULT_TIMEOUT, + 'Reconnect after mismatched register reply timed out'); + equal(registers, 1, 'Wrong register count'); +}); diff --git a/dom/push/test/xpcshell/test_register_wrong_type.js b/dom/push/test/xpcshell/test_register_wrong_type.js new file mode 100644 index 000000000000..b42b87f59cab --- /dev/null +++ b/dom/push/test/xpcshell/test_register_wrong_type.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = 'c293fdc5-a75e-4eb1-af88-a203991c0787'; + +function run_test() { + do_get_profile(); + setPrefs({ + requestTimeout: 1000, + retryBaseInterval: 150 + }); + disableServiceWorkerEvents( + 'https://example.com/mistyped' + ); + run_next_test(); +} + +add_task(function* test_register_wrong_type() { + let registers = 0; + let helloDefer = Promise.defer(); + let helloDone = after(2, helloDefer.resolve); + + PushService._generateID = () => '1234'; + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + helloDone(); + }, + onRegister(request) { + registers++; + this.serverSendMsg(JSON.stringify({ + messageType: 'register', + status: 200, + channelID: 1234, + uaid: userAgentID, + pushEndpoint: 'https://example.org/update/wrong-type' + })); + } + }); + } + }); + + let promise = + + yield rejects( + PushNotificationService.register('https://example.com/mistyped'), + function(error) { + return error == 'TimeoutError'; + }, + 'Wrong error for non-string channel ID' + ); + + yield waitForPromise(helloDefer.promise, DEFAULT_TIMEOUT, + 'Reconnect after sending non-string channel ID timed out'); + equal(registers, 1, 'Wrong register count'); +}); diff --git a/dom/push/test/xpcshell/test_registration_error.js b/dom/push/test/xpcshell/test_registration_error.js new file mode 100644 index 000000000000..0e32ab003d8c --- /dev/null +++ b/dom/push/test/xpcshell/test_registration_error.js @@ -0,0 +1,39 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs({ + userAgentID: '6faed1f0-1439-4aac-a978-db21c81cd5eb' + }); + run_next_test(); +} + +add_task(function* test_registrations_error() { + let db = new PushDB(); + do_register_cleanup(() => cleanupDatabase(db)); + + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db: makeStub(db, { + getByScope(prev, scope, successCb, failureCb) { + failureCb('oops'); + } + }), + makeWebSocket(uri) { + return new MockWebSocket(uri); + } + }); + + yield rejects( + PushNotificationService.registration('https://example.net/1'), + function(error) { + return error == 'Database error'; + }, + 'Wrong message' + ); +}); diff --git a/dom/push/test/xpcshell/test_registration_missing_scope.js b/dom/push/test/xpcshell/test_registration_missing_scope.js new file mode 100644 index 000000000000..4de4de82b9f1 --- /dev/null +++ b/dom/push/test/xpcshell/test_registration_missing_scope.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs(); + run_next_test(); +} + +add_task(function* test_registration_missing_scope() { + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri); + } + }); + yield rejects( + PushNotificationService.registration(''), + function(error) { + return error == 'Database error'; + }, + 'Record missing page and manifest URLs' + ); +}); diff --git a/dom/push/test/xpcshell/test_registration_none.js b/dom/push/test/xpcshell/test_registration_none.js new file mode 100644 index 000000000000..5fff063cc39b --- /dev/null +++ b/dom/push/test/xpcshell/test_registration_none.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = 'a722e448-c481-4c48-aea0-fc411cb7c9ed'; + +function run_test() { + do_get_profile(); + setPrefs({userAgentID}); + run_next_test(); +} + +// Should not open a connection if the client has no registrations. +add_task(function* test_registration_none() { + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri); + } + }); + + let registration = yield PushNotificationService.registration( + 'https://example.net/1'); + ok(!registration, 'Should not open a connection without registration'); +}); diff --git a/dom/push/test/xpcshell/test_registration_success.js b/dom/push/test/xpcshell/test_registration_success.js new file mode 100644 index 000000000000..b3c03e730e2e --- /dev/null +++ b/dom/push/test/xpcshell/test_registration_success.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = '997ee7ba-36b1-4526-ae9e-2d3f38d6efe8'; + +function run_test() { + do_get_profile(); + setPrefs({userAgentID}); + run_next_test(); +} + +add_task(function* test_registration_success() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + let records = [{ + channelID: 'bf001fe0-2684-42f2-bc4d-a3e14b11dd5b', + pushEndpoint: 'https://example.com/update/same-manifest/1', + scope: 'https://example.net/a', + version: 5 + }, { + channelID: 'f6edfbcd-79d6-49b8-9766-48b9dcfeff0f', + pushEndpoint: 'https://example.com/update/same-manifest/2', + scope: 'https://example.net/b', + version: 10 + }, { + channelID: 'b1cf38c9-6836-4d29-8a30-a3e98d59b728', + pushEndpoint: 'https://example.org/update/different-manifest', + scope: 'https://example.org/c', + version: 15 + }]; + for (let record of records) { + yield promiseDB.put(record); + } + + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + equal(request.uaid, userAgentID, 'Wrong device ID in handshake'); + deepEqual(request.channelIDs.sort(), [ + 'b1cf38c9-6836-4d29-8a30-a3e98d59b728', + 'bf001fe0-2684-42f2-bc4d-a3e14b11dd5b', + 'f6edfbcd-79d6-49b8-9766-48b9dcfeff0f', + ], 'Wrong channel list in handshake'); + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + } + }); + } + }); + + let registration = yield PushNotificationService.registration( + 'https://example.net/a'); + deepEqual(registration, { + pushEndpoint: 'https://example.com/update/same-manifest/1', + version: 5 + }, 'Should include registrations for all pages with this manifest'); +}); diff --git a/dom/push/test/xpcshell/test_unregister_empty_scope.js b/dom/push/test/xpcshell/test_unregister_empty_scope.js new file mode 100644 index 000000000000..0d874f299af3 --- /dev/null +++ b/dom/push/test/xpcshell/test_unregister_empty_scope.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs(); + run_next_test(); +} + +add_task(function* test_unregister_empty_scope() { + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: '5619557c-86fe-4711-8078-d1fd6987aef7' + })); + } + }); + } + }); + + yield rejects( + PushNotificationService.unregister(''), + function(error) { + return error == 'NotFoundError'; + }, + 'Wrong error for empty endpoint' + ); +}); diff --git a/dom/push/test/xpcshell/test_unregister_error.js b/dom/push/test/xpcshell/test_unregister_error.js new file mode 100644 index 000000000000..484b11a95506 --- /dev/null +++ b/dom/push/test/xpcshell/test_unregister_error.js @@ -0,0 +1,65 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const channelID = '00c7fa13-7b71-447d-bd27-a91abc09d1b2'; + +function run_test() { + do_get_profile(); + setPrefs(); + run_next_test(); +} + +add_task(function* test_unregister_error() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + yield promiseDB.put({ + channelID: channelID, + pushEndpoint: 'https://example.org/update/failure', + scope: 'https://example.net/page/failure', + version: 1 + }); + + let unregisterDefer = Promise.defer(); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: '083e6c17-1063-4677-8638-ab705aebebc2' + })); + }, + onUnregister(request) { + // The server is notified out-of-band. Since channels may be pruned, + // any failures are swallowed. + equal(request.channelID, channelID, 'Unregister: wrong channel ID'); + this.serverSendMsg(JSON.stringify({ + messageType: 'unregister', + status: 500, + error: 'omg, everything is exploding', + channelID + })); + unregisterDefer.resolve(); + } + }); + } + }); + + yield PushNotificationService.unregister( + 'https://example.net/page/failure'); + + let result = yield promiseDB.getByChannelID(channelID); + ok(!result, 'Deleted push record exists'); + + // Make sure we send a request to the server. + yield waitForPromise(unregisterDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for unregister'); +}); diff --git a/dom/push/test/xpcshell/test_unregister_invalid_json.js b/dom/push/test/xpcshell/test_unregister_invalid_json.js new file mode 100644 index 000000000000..81bc1754231e --- /dev/null +++ b/dom/push/test/xpcshell/test_unregister_invalid_json.js @@ -0,0 +1,78 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const userAgentID = '7f0af1bb-7e1f-4fb8-8e4a-e8de434abde3'; + +function run_test() { + do_get_profile(); + setPrefs({ + userAgentID, + requestTimeout: 150, + retryBaseInterval: 150 + }); + run_next_test(); +} + +add_task(function* test_unregister_invalid_json() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + let records = [{ + channelID: '87902e90-c57e-4d18-8354-013f4a556559', + pushEndpoint: 'https://example.org/update/1', + scope: 'https://example.edu/page/1', + version: 1 + }, { + channelID: '057caa8f-9b99-47ff-891c-adad18ce603e', + pushEndpoint: 'https://example.com/update/2', + scope: 'https://example.net/page/1', + version: 1 + }]; + for (let record of records) { + yield promiseDB.put(record); + } + + let unregisterDefer = Promise.defer(); + let unregisterDone = after(2, unregisterDefer.resolve); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: userAgentID + })); + }, + onUnregister(request) { + this.serverSendMsg(');alert(1);('); + unregisterDone(); + } + }); + } + }); + + // "unregister" is fire-and-forget: it's sent via _send(), not + // _sendRequest(). + yield PushNotificationService.unregister( + 'https://example.edu/page/1'); + let record = yield promiseDB.getByChannelID( + '87902e90-c57e-4d18-8354-013f4a556559'); + ok(!record, 'Failed to delete unregistered record'); + + yield PushNotificationService.unregister( + 'https://example.net/page/1'); + record = yield promiseDB.getByChannelID( + '057caa8f-9b99-47ff-891c-adad18ce603e'); + ok(!record, + 'Failed to delete unregistered record after receiving invalid JSON'); + + yield waitForPromise(unregisterDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for unregister'); +}); diff --git a/dom/push/test/xpcshell/test_unregister_not_found.js b/dom/push/test/xpcshell/test_unregister_not_found.js new file mode 100644 index 000000000000..442e90a141ea --- /dev/null +++ b/dom/push/test/xpcshell/test_unregister_not_found.js @@ -0,0 +1,35 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +function run_test() { + do_get_profile(); + setPrefs(); + run_next_test(); +} + +add_task(function* test_unregister_not_found() { + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: 'f074ed80-d479-44fa-ba65-792104a79ea9' + })); + } + }); + } + }); + + let promise = PushNotificationService.unregister( + 'https://example.net/nonexistent'); + yield rejects(promise, function(error) { + return error == 'NotFoundError'; + }, 'Wrong error for nonexistent scope'); +}); diff --git a/dom/push/test/xpcshell/test_unregister_success.js b/dom/push/test/xpcshell/test_unregister_success.js new file mode 100644 index 000000000000..0cf28dc5aabd --- /dev/null +++ b/dom/push/test/xpcshell/test_unregister_success.js @@ -0,0 +1,60 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const channelID = 'db0a7021-ec2d-4bd3-8802-7a6966f10ed8'; + +function run_test() { + do_get_profile(); + setPrefs(); + run_next_test(); +} + +add_task(function* test_unregister_success() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + yield promiseDB.put({ + channelID, + pushEndpoint: 'https://example.org/update/unregister-success', + scope: 'https://example.com/page/unregister-success', + version: 1 + }); + + let unregisterDefer = Promise.defer(); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: 'fbe865a6-aeb8-446f-873c-aeebdb8d493c' + })); + }, + onUnregister(request) { + equal(request.channelID, channelID, 'Should include the channel ID'); + this.serverSendMsg(JSON.stringify({ + messageType: 'unregister', + status: 200, + channelID + })); + unregisterDefer.resolve(); + } + }); + } + }); + + yield PushNotificationService.unregister( + 'https://example.com/page/unregister-success'); + let record = yield promiseDB.getByChannelID(channelID); + ok(!record, 'Unregister did not remove record'); + + yield waitForPromise(unregisterDefer.promise, DEFAULT_TIMEOUT, + 'Timed out waiting for unregister'); +}); diff --git a/dom/push/test/xpcshell/xpcshell.ini b/dom/push/test/xpcshell/xpcshell.ini new file mode 100644 index 000000000000..a9cf90544ada --- /dev/null +++ b/dom/push/test/xpcshell/xpcshell.ini @@ -0,0 +1,32 @@ +[DEFAULT] +head = head.js +tail = +# Push notifications and alarms are currently disabled on Android. +skip-if = toolkit == 'android' + +[test_notification_ack.js] +[test_notification_duplicate.js] +[test_notification_error.js] +[test_notification_incomplete.js] +[test_notification_version_string.js] +[test_register_case.js] +[test_register_flush.js] +[test_register_invalid_channel.js] +[test_register_invalid_endpoint.js] +[test_register_invalid_json.js] +[test_register_no_id.js] +[test_register_request_queue.js] +[test_register_rollback.js] +[test_register_success.js] +[test_register_timeout.js] +[test_register_wrong_id.js] +[test_register_wrong_type.js] +[test_registration_error.js] +[test_registration_missing_scope.js] +[test_registration_none.js] +[test_registration_success.js] +[test_unregister_empty_scope.js] +[test_unregister_error.js] +[test_unregister_invalid_json.js] +[test_unregister_not_found.js] +[test_unregister_success.js] From 0d32e44fa342548d415d4897de7d023fcb1f90a7 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Tue, 21 Apr 2015 20:10:50 +0200 Subject: [PATCH 009/241] Bug 1156063 - Intermittent application crashed [@ mozilla::dom::indexedDB::::ConnectionPool::Start] in various tests. r=janv --- dom/indexedDB/ActorsParent.cpp | 92 ++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 179bf8379ae3..66ffc5ed672a 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -5102,13 +5102,10 @@ public: AssertIsOnOwningThread() const { AssertIsOnBackgroundThread(); - -#ifdef DEBUG MOZ_ASSERT(mOwningThread); - bool current; + DebugOnly current; MOZ_ASSERT(NS_SUCCEEDED(mOwningThread->IsOnCurrentThread(¤t))); MOZ_ASSERT(current); -#endif } void @@ -5128,7 +5125,8 @@ public: return mActorDestroyed; } - // May be called on any thread. + // May be called on any thread, but you should call IsActorDestroyed() if + // you know you're on the background thread because it is slightly faster. bool OperationMayProceed() const { @@ -6628,6 +6626,9 @@ private: nsresult EnsureDatabaseActorIsAlive(); + void + CleanupBackgroundThreadObjects(bool aInvalidate); + void MetadataToSpec(DatabaseSpec& aSpec); @@ -7737,7 +7738,7 @@ public: MOZ_ASSERT(NS_IsMainThread()); if (sInstance) { - return sInstance->mShutdownRequested; + return sInstance->IsShuttingDown(); } return QuotaManager::IsShuttingDown(); @@ -7812,13 +7813,11 @@ class QuotaClient::ShutdownWorkThreadsRunnable final : public nsRunnable { nsRefPtr mQuotaClient; - bool mHasRequestedShutDown; public: explicit ShutdownWorkThreadsRunnable(QuotaClient* aQuotaClient) : mQuotaClient(aQuotaClient) - , mHasRequestedShutDown(false) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aQuotaClient); @@ -15318,7 +15317,6 @@ QuotaClient:: ShutdownWorkThreadsRunnable::Run() { if (NS_IsMainThread()) { - MOZ_ASSERT(mHasRequestedShutDown); MOZ_ASSERT(QuotaClient::GetInstance() == mQuotaClient); MOZ_ASSERT(mQuotaClient->mShutdownRunnable == this); @@ -15330,16 +15328,11 @@ ShutdownWorkThreadsRunnable::Run() AssertIsOnBackgroundThread(); - if (!mHasRequestedShutDown) { - mHasRequestedShutDown = true; - - nsRefPtr connectionPool = gConnectionPool.get(); - if (connectionPool) { - connectionPool->Shutdown(); - - gConnectionPool = nullptr; - } + nsRefPtr connectionPool = gConnectionPool.get(); + if (connectionPool) { + connectionPool->Shutdown(); + gConnectionPool = nullptr; } MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(this))); @@ -17124,15 +17117,15 @@ OpenDatabaseOp::ActorDestroy(ActorDestroyReason aWhy) { AssertIsOnOwningThread(); - if (mDatabase && aWhy != Deletion) { - mDatabase->Invalidate(); + FactoryOp::ActorDestroy(aWhy); + + if (aWhy != Deletion) { + CleanupBackgroundThreadObjects(/* aInvalidate */ true); } if (mVersionChangeOp) { mVersionChangeOp->NoteActorDestroyed(); } - - FactoryOp::ActorDestroy(aWhy); } nsresult @@ -17645,7 +17638,6 @@ OpenDatabaseOp::BeginVersionChange() MOZ_ASSERT(!mVersionChangeTransaction); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) || - !OperationMayProceed() || IsActorDestroyed()) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -17763,7 +17755,8 @@ OpenDatabaseOp::DispatchToWorkThread() IDBTransaction::VERSION_CHANGE); MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty()); - if (IsActorDestroyed()) { + if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) || + IsActorDestroyed()) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } @@ -17811,7 +17804,6 @@ OpenDatabaseOp::SendUpgradeNeeded() MOZ_ASSERT_IF(!IsActorDestroyed(), mDatabase); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) || - !OperationMayProceed() || IsActorDestroyed()) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -17872,7 +17864,11 @@ OpenDatabaseOp::SendResults() mVersionChangeTransaction = nullptr; } - if (!IsActorDestroyed()) { + if (IsActorDestroyed()) { + if (NS_SUCCEEDED(mResultCode)) { + mResultCode = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + } + } else { FactoryRequestResponse response; if (NS_SUCCEEDED(mResultCode)) { @@ -17907,20 +17903,7 @@ OpenDatabaseOp::SendResults() PBackgroundIDBFactoryRequestParent::Send__delete__(this, response); } - if (NS_FAILED(mResultCode) && mOfflineStorage) { - mOfflineStorage->CloseOnOwningThread(); - - nsCOMPtr callback = - NS_NewRunnableMethod(this, &OpenDatabaseOp::ConnectionClosedCallback); - - nsRefPtr helper = - new WaitForTransactionsHelper(mDatabaseId, callback); - helper->WaitForTransactions(); - } - - // Make sure to release the database on this thread. - nsRefPtr database; - mDatabase.swap(database); + CleanupBackgroundThreadObjects(NS_FAILED(mResultCode)); FinishSendResults(); } @@ -18012,6 +17995,33 @@ OpenDatabaseOp::EnsureDatabaseActorIsAlive() return NS_OK; } +void +OpenDatabaseOp::CleanupBackgroundThreadObjects(bool aInvalidate) +{ + AssertIsOnOwningThread(); + MOZ_ASSERT(IsActorDestroyed()); + + if (mDatabase) { + MOZ_ASSERT(!mOfflineStorage); + + if (aInvalidate) { + mDatabase->Invalidate(); + } + + // Make sure to release the database on this thread. + mDatabase = nullptr; + } else if (mOfflineStorage) { + mOfflineStorage->CloseOnOwningThread(); + + nsCOMPtr callback = + NS_NewRunnableMethod(this, &OpenDatabaseOp::ConnectionClosedCallback); + + nsRefPtr helper = + new WaitForTransactionsHelper(mDatabaseId, callback); + helper->WaitForTransactions(); + } +} + void OpenDatabaseOp::MetadataToSpec(DatabaseSpec& aSpec) { @@ -18520,7 +18530,6 @@ DeleteDatabaseOp::BeginVersionChange() MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty()); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) || - !OperationMayProceed() || IsActorDestroyed()) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -18560,7 +18569,6 @@ DeleteDatabaseOp::DispatchToWorkThread() MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty()); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) || - !OperationMayProceed() || IsActorDestroyed()) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; From 91f963df6693e86b9fc98954365207f0d5bbe22c Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Tue, 21 Apr 2015 20:10:51 +0200 Subject: [PATCH 010/241] Bug 1149274 - Clear site-permissions should clear all registered push notifications. r=nsm --- browser/base/content/sanitize.js | 5 ++ .../push/nsIPushNotificationService.idl | 7 ++- dom/push/PushNotificationService.js | 4 ++ dom/push/PushService.jsm | 20 ++++++++ .../test/xpcshell/test_clearAll_successful.js | 47 +++++++++++++++++++ dom/push/test/xpcshell/xpcshell.ini | 2 + 6 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 dom/push/test/xpcshell/test_clearAll_successful.js diff --git a/browser/base/content/sanitize.js b/browser/base/content/sanitize.js index 0930b739ce11..99d207176af9 100644 --- a/browser/base/content/sanitize.js +++ b/browser/base/content/sanitize.js @@ -486,6 +486,11 @@ Sanitizer.prototype = { .getService(Ci.nsISiteSecurityService); sss.clearAll(); + // Clear all push notification subscriptions + var push = Cc["@mozilla.org/push/NotificationService;1"] + .getService(Ci.nsIPushNotificationService); + push.clearAll(); + TelemetryStopwatch.finish("FX_SANITIZE_SITESETTINGS"); }, diff --git a/dom/interfaces/push/nsIPushNotificationService.idl b/dom/interfaces/push/nsIPushNotificationService.idl index 7d5ca9f00d89..19619ce0f0a7 100644 --- a/dom/interfaces/push/nsIPushNotificationService.idl +++ b/dom/interfaces/push/nsIPushNotificationService.idl @@ -11,7 +11,7 @@ * uses service workers to notify applications. This interface exists to allow * privileged code to receive messages without migrating to service workers. */ -[scriptable, uuid(32028e38-903b-4a64-a180-5857eb4cb3dd)] +[scriptable, uuid(3da6a16c-69f8-4843-9149-1e89d58a53e2)] interface nsIPushNotificationService : nsISupports { /** @@ -46,4 +46,9 @@ interface nsIPushNotificationService : nsISupports * given |scope|, or `null` if the |scope| does not have a subscription. */ jsval registration(in string scope); + + /** + * Clear all subscriptions + */ + jsval clearAll(); }; diff --git a/dom/push/PushNotificationService.js b/dom/push/PushNotificationService.js index 41084a93127b..9229ef6c6bc4 100644 --- a/dom/push/PushNotificationService.js +++ b/dom/push/PushNotificationService.js @@ -50,6 +50,10 @@ PushNotificationService.prototype = { return PushService._registration({scope}); }, + clearAll: function clearAll() { + return PushService._clearAll(); + }, + observe: function observe(subject, topic, data) { switch (topic) { case "app-startup": diff --git a/dom/push/PushService.jsm b/dom/push/PushService.jsm index c4d10a372fb4..60ae0d4351d0 100644 --- a/dom/push/PushService.jsm +++ b/dom/push/PushService.jsm @@ -135,6 +135,19 @@ this.PushDB.prototype = { ); }, + clearAll: function clear(aSuccessCb, aErrorCb) { + this.newTxn( + "readwrite", + kPUSHDB_STORE_NAME, + function (aTxn, aStore) { + debug("Going to clear all!"); + aStore.clear(); + }, + aSuccessCb, + aErrorCb + ); + }, + getByPushEndpoint: function(aPushEndpoint, aSuccessCb, aErrorCb) { debug("getByPushEndpoint()"); @@ -1627,6 +1640,13 @@ this.PushService = { ); }, + _clearAll: function _clearAll() { + return new Promise((resolve, reject) => { + this._db.clearAll(() => resolve(), + () => reject("Database error")); + }); + }, + /** * Called on message from the child process */ diff --git a/dom/push/test/xpcshell/test_clearAll_successful.js b/dom/push/test/xpcshell/test_clearAll_successful.js new file mode 100644 index 000000000000..bf16f6434c67 --- /dev/null +++ b/dom/push/test/xpcshell/test_clearAll_successful.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +const {PushDB, PushService} = serviceExports; + +const channelID = 'db0a7021-ec2d-4bd3-8802-7a6966f10ed8'; + +function run_test() { + do_get_profile(); + setPrefs(); + run_next_test(); +} + +add_task(function* test_unregister_success() { + let db = new PushDB(); + let promiseDB = promisifyDatabase(db); + do_register_cleanup(() => cleanupDatabase(db)); + yield promiseDB.put({ + channelID, + pushEndpoint: 'https://example.org/update/unregister-success', + scope: 'https://example.com/page/unregister-success', + version: 1 + }); + + let unregisterDefer = Promise.defer(); + PushService.init({ + networkInfo: new MockDesktopNetworkInfo(), + db, + makeWebSocket(uri) { + return new MockWebSocket(uri, { + onHello(request) { + this.serverSendMsg(JSON.stringify({ + messageType: 'hello', + status: 200, + uaid: 'fbe865a6-aeb8-446f-873c-aeebdb8d493c' + })); + } + }); + } + }); + + yield PushNotificationService.clearAll(); + let record = yield promiseDB.getByChannelID(channelID); + ok(!record, 'Unregister did not remove record'); +}); diff --git a/dom/push/test/xpcshell/xpcshell.ini b/dom/push/test/xpcshell/xpcshell.ini index a9cf90544ada..aa9d99a2b436 100644 --- a/dom/push/test/xpcshell/xpcshell.ini +++ b/dom/push/test/xpcshell/xpcshell.ini @@ -4,6 +4,8 @@ tail = # Push notifications and alarms are currently disabled on Android. skip-if = toolkit == 'android' +[test_clearAll_successful.js] +run-sequentially = This will delete all existing push subscritions. [test_notification_ack.js] [test_notification_duplicate.js] [test_notification_error.js] From 8d746505476413b3872f32c9a9cd3a8bd1b2af9a Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Tue, 21 Apr 2015 20:10:51 +0200 Subject: [PATCH 011/241] Bug 1156052 - Add push information to about:serviceworkers. r=baku --- toolkit/content/aboutServiceWorkers.js | 16 ++++++++++++++++ .../chrome/global/aboutServiceWorkers.properties | 2 ++ 2 files changed, 18 insertions(+) diff --git a/toolkit/content/aboutServiceWorkers.js b/toolkit/content/aboutServiceWorkers.js index 8f36bba7b5a3..f77a687d8711 100644 --- a/toolkit/content/aboutServiceWorkers.js +++ b/toolkit/content/aboutServiceWorkers.js @@ -9,6 +9,13 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import('resource://gre/modules/XPCOMUtils.jsm'); +XPCOMUtils.defineLazyServiceGetter( + this, + "PushNotificationService", + "@mozilla.org/push/NotificationService;1", + "nsIPushNotificationService" +); + const bundle = Services.strings.createBundle( "chrome://global/locale/aboutServiceWorkers.properties"); @@ -101,6 +108,15 @@ function display(info) { createItem(bundle.GetStringFromName('activeCacheName'), info.activeCacheName); createItem(bundle.GetStringFromName('waitingCacheName'), info.waitingCacheName); + PushNotificationService.registration(info.scope).then( + pushRecord => { + createItem(bundle.GetStringFromName('pushEndpoint'), JSON.stringify(pushRecord)); + }, + error => { + dump("about:serviceworkers - push registration failed\n"); + } + ); + let updateButton = document.createElement("button"); updateButton.appendChild(document.createTextNode(bundle.GetStringFromName('update'))); updateButton.onclick = function() { diff --git a/toolkit/locales/en-US/chrome/global/aboutServiceWorkers.properties b/toolkit/locales/en-US/chrome/global/aboutServiceWorkers.properties index 4b8998de8df8..cb7afc49eea4 100644 --- a/toolkit/locales/en-US/chrome/global/aboutServiceWorkers.properties +++ b/toolkit/locales/en-US/chrome/global/aboutServiceWorkers.properties @@ -31,3 +31,5 @@ waiting = Waiting… # LOCALIZATION NODE the term "Service Worker" should not translated. unregisterError = Failed to unregister this Service Worker. + +pushEndpoint = Push Endpoint: \ No newline at end of file From bb428151a70ca36875a9bb1ead40d20e347b8e57 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Tue, 14 Apr 2015 13:28:39 -0700 Subject: [PATCH 012/241] Bug 1154101 - Remove PushMarkStack indirection; r=sfink --HG-- extra : rebase_source : 338200fcb26df111b3bbc667d8971db5c83a9fbf --- js/src/gc/Marking.cpp | 151 +++++++++++++++++++++--------------------- js/src/gc/Tracer.h | 34 +--------- 2 files changed, 77 insertions(+), 108 deletions(-) diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 8b8f38c8f4ae..d246a0a8b06d 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -42,53 +42,6 @@ void * const js::NullPtr::constNullValue = nullptr; JS_PUBLIC_DATA(void * const) JS::NullPtr::constNullValue = nullptr; -static void -PushMarkStack(GCMarker* gcmarker, JSObject* thing) { - gcmarker->traverse(thing); -} -static void -PushMarkStack(GCMarker* gcmarker, ObjectGroup* thing) { - gcmarker->traverse(thing); -} -static void -PushMarkStack(GCMarker* gcmarker, jit::JitCode* thing) { - gcmarker->traverse(thing); -} -static void -PushMarkStack(GCMarker* gcmarker, JSScript* thing) { - gcmarker->traverse(thing); -} -static void -PushMarkStack(GCMarker* gcmarker, LazyScript* thing) { - gcmarker->traverse(thing); -} -static void -PushMarkStack(GCMarker* gcmarker, Shape* thing) { - gcmarker->traverse(thing); -} -static void -PushMarkStack(GCMarker* gcmarker, BaseShape* thing) { - gcmarker->traverse(thing); -} -static void -PushMarkStack(GCMarker* gcmarker, JSString* str) { - // Permanent atoms might not be associated with this runtime. - if (str->isPermanentAtom()) - return; - - gcmarker->traverse(str); -} -static void -PushMarkStack(GCMarker* gcmarker, JS::Symbol* sym) { - // Well-known symbols might not be associated with this runtime. - if (sym->isWellKnownSymbol()) - return; - - gcmarker->traverse(sym); -} - -/*** Object Marking ***/ - #if defined(DEBUG) template static inline bool @@ -467,7 +420,7 @@ bool MustSkipMarking(JSString* str) { // Don't mark permanent atoms, as they may be associated with another - // runtime. Note that PushMarkStack() also checks this, but we need to not + // runtime. Note that traverse() also checks this, but we need to not // run the isGCMarking test from off-main-thread, so have to check it here // too. return str->isPermanentAtom() || @@ -492,7 +445,7 @@ DoMarking(GCMarker* gcmarker, T thing) if (MustSkipMarking(thing)) return; - PushMarkStack(gcmarker, thing); + gcmarker->traverse(thing); // Mark the compartment as live. SetMaybeAliveFlag(thing); @@ -520,6 +473,68 @@ DoMarking(GCMarker* gcmarker, jsid id) DoMarking(gcmarker, JSID_TO_SYMBOL(id)); } +// The default traversal calls out to the fully generic traceChildren function +// to visit the child edges. In the absense of other traversal mechanisms, this +// function will rapidly grow the stack past its bounds and crash the process. +// Thus, this generic tracing should only be used in cases where subsequent +// tracing will not recurse. +template +void +js::GCMarker::traverse(T* thing) +{ + auto asBase = static_cast::type*>(thing); + MOZ_ASSERT(!ThingIsPermanentAtomOrWellKnownSymbol(asBase)); + if (mark(asBase)) + thing->traceChildren(this); +} + +// Shape, BaseShape, String, and Symbol are extremely common, but have simple +// patterns of recursion. We traverse trees of these edges immediately, with +// aggressive, manual inlining, implemented by eagerlyTraceChildren. +template +void +js::GCMarker::markAndScan(T* thing) +{ + if (ThingIsPermanentAtomOrWellKnownSymbol(thing)) + return; + if (mark(thing)) + eagerlyMarkChildren(thing); +} +namespace js { +template <> void GCMarker::traverse(Shape* thing) { markAndScan(thing); } +template <> void GCMarker::traverse(BaseShape* thing) { markAndScan(thing); } +template <> void GCMarker::traverse(JSString* thing) { markAndScan(thing); } +template <> void GCMarker::traverse(JS::Symbol* thing) { markAndScan(thing); } +} // namespace js + +// Object and ObjectGroup are extremely common and can contain arbitrarily +// nested graphs, so are not trivially inlined. In this case we use a mark +// stack to control recursion. JitCode shares none of these properties, but is +// included for historical reasons. +template +void +js::GCMarker::markAndPush(StackTag tag, T* thing) +{ + if (mark(thing)) + pushTaggedPtr(tag, thing); +} +namespace js { +template <> void GCMarker::traverse(JSObject* thing) { markAndPush(ObjectTag, thing); } +template <> void GCMarker::traverse(ObjectGroup* thing) { markAndPush(GroupTag, thing); } +template <> void GCMarker::traverse(jit::JitCode* thing) { markAndPush(JitCodeTag, thing); } +} // namespace js + +template +bool +js::GCMarker::mark(T* thing) +{ + JS_COMPARTMENT_ASSERT(runtime(), thing); + MOZ_ASSERT(!IsInsideNursery(gc::TenuredCell::fromPointer(thing))); + return gc::ParticipatesInCC::value + ? gc::TenuredCell::fromPointer(thing)->markIfUnmarked(markColor()) + : gc::TenuredCell::fromPointer(thing)->markIfUnmarked(gc::BLACK); +} + namespace js { namespace gc { @@ -926,7 +941,7 @@ gc::MarkIdForBarrier(JSTracer* trc, jsid* idp, const char* name) /*** Push Mark Stack ***/ /* - * PushMarkStack for BaseShape unpacks its children directly onto the mark + * GCMarker::traverse for BaseShape unpacks its children directly onto the mark * stack. For a pre-barrier between incremental slices, this may result in * objects in the nursery getting pushed onto the mark stack. It is safe to * ignore these objects because they will be marked by the matching @@ -956,13 +971,13 @@ inline void GCMarker::eagerlyMarkChildren(Shape* shape) { restart: - PushMarkStack(this, shape->base()); + traverse(shape->base()); const BarrieredBase& id = shape->propidRef(); if (JSID_IS_STRING(id)) - PushMarkStack(this, JSID_TO_STRING(id)); + traverse(JSID_TO_STRING(id)); else if (JSID_IS_SYMBOL(id)) - PushMarkStack(this, JSID_TO_SYMBOL(id)); + traverse(JSID_TO_SYMBOL(id)); if (shape->hasGetterObject()) MaybePushMarkStackBetweenSlices(this, shape->getterObject()); @@ -1087,7 +1102,7 @@ inline void GCMarker::eagerlyMarkChildren(JS::Symbol* sym) { if (JSString* desc = sym->description()) - PushMarkStack(this, desc); + traverse(desc); } /* @@ -1148,7 +1163,7 @@ ScanObjectGroup(GCMarker* gcmarker, ObjectGroup* group) group->compartment()->mark(); if (GlobalObject* global = group->compartment()->unsafeUnbarrieredMaybeGlobal()) - PushMarkStack(gcmarker, global); + gcmarker->traverse(global); if (group->newScript()) group->newScript()->trace(gcmarker); @@ -1160,7 +1175,7 @@ ScanObjectGroup(GCMarker* gcmarker, ObjectGroup* group) group->unboxedLayout().trace(gcmarker); if (ObjectGroup* unboxedGroup = group->maybeOriginalUnboxedGroup()) - PushMarkStack(gcmarker, unboxedGroup); + gcmarker->traverse(unboxedGroup); if (TypeDescr* descr = group->maybeTypeDescr()) gcmarker->traverse(descr); @@ -1211,7 +1226,7 @@ static void PushArenaTyped(GCMarker* gcmarker, ArenaHeader* aheader) { for (ArenaCellIterUnderGC i(aheader); !i.done(); i.next()) - PushMarkStack(gcmarker, i.get()); + gcmarker->traverse(i.get()); } void @@ -1532,7 +1547,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget) clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS); if (clasp->trace == InlineTypedObject::obj_trace) { Shape* shape = obj->as().shapeFromGC(); - PushMarkStack(this, shape); + traverse(shape); TypeDescr* descr = &obj->as().typeDescr(); if (!descr->hasTraceList()) return; @@ -1560,7 +1575,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget) NativeObject* nobj = &obj->as(); Shape* shape = nobj->lastProperty(); - PushMarkStack(this, shape); + traverse(shape); unsigned nslots = nobj->slotSpan(); @@ -1642,24 +1657,6 @@ GCMarker::drainMarkStack(SliceBudget& budget) return true; } -template -void -GCMarker::dispatchToTraceChildren(T* thing) -{ - thing->traceChildren(this); -} - -template -bool -GCMarker::mark(T* thing) -{ - JS_COMPARTMENT_ASSERT(runtime(), thing); - MOZ_ASSERT(!IsInsideNursery(gc::TenuredCell::fromPointer(thing))); - return gc::ParticipatesInCC::value - ? gc::TenuredCell::fromPointer(thing)->markIfUnmarked(markColor()) - : gc::TenuredCell::fromPointer(thing)->markIfUnmarked(gc::BLACK); -} - struct TraceChildrenFunctor { template void operator()(JSTracer* trc, void* thing) { diff --git a/js/src/gc/Tracer.h b/js/src/gc/Tracer.h index e7dd4cda268f..a2885ebe460d 100644 --- a/js/src/gc/Tracer.h +++ b/js/src/gc/Tracer.h @@ -158,20 +158,7 @@ class GCMarker : public JSTracer void reset(); // Mark the given GC thing and traverse its children at some point. - void traverse(JSObject* thing) { markAndPush(ObjectTag, thing); } - void traverse(ObjectGroup* thing) { markAndPush(GroupTag, thing); } - void traverse(jit::JitCode* thing) { markAndPush(JitCodeTag, thing); } - // Mark the given GC thing and then eagerly mark all children. - void traverse(Shape* thing) { markAndScan(thing); } - void traverse(BaseShape* thing) { markAndScan(thing); } - void traverse(JSString* thing) { markAndScan(thing); } - void traverse(JS::Symbol* thing) { markAndScan(thing); } - // The following traverse methods traverse immediately, go out-of-line to do so. - void traverse(JSScript* thing) { markAndTraverse(thing); } - void traverse(LazyScript* thing) { markAndTraverse(thing); } - // The other types are marked immediately and inline via a ScanFoo shared - // between PushMarkStack and the processMarkStackTop. Since ScanFoo is - // inline in Marking.cpp, we cannot inline it here, yet. + template void traverse(T* thing); /* * Care must be taken changing the mark color from gray to black. The cycle @@ -249,28 +236,13 @@ class GCMarker : public JSTracer pushTaggedPtr(ObjectTag, obj); } - template - void markAndPush(StackTag tag, T* thing) { - if (mark(thing)) - pushTaggedPtr(tag, thing); - } - - template - void markAndScan(T* thing) { - if (mark(thing)) - eagerlyMarkChildren(thing); - } + template void markAndPush(StackTag tag, T* thing); + template void markAndScan(T* thing); void eagerlyMarkChildren(Shape* shape); void eagerlyMarkChildren(BaseShape* base); void eagerlyMarkChildren(JSString* str); void eagerlyMarkChildren(JS::Symbol* sym); - template - void markAndTraverse(T* thing) { - if (mark(thing)) - dispatchToTraceChildren(thing); - } - // We may not have concrete types yet, so this has to be out of the header. template void dispatchToTraceChildren(T* thing); From 2ccef0beed6611e7bbb8da40d70c289f9c7a9f94 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Tue, 14 Apr 2015 13:28:46 -0700 Subject: [PATCH 013/241] Bug 1154950 - Share permanent atom and well-known symbol marking; r=sfink --HG-- extra : rebase_source : 900f7055dbd7e8509e1cac83a6fe12e48ac85a6d --- js/src/gc/Barrier.h | 3 ++- js/src/gc/Marking.cpp | 62 +++++++++++++++++-------------------------- js/src/gc/Marking.h | 15 +++++------ js/src/jsatom.cpp | 4 +-- js/src/vm/String.cpp | 6 ++--- 5 files changed, 39 insertions(+), 51 deletions(-) diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 95a65916c425..06e928847b64 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -590,7 +590,8 @@ class ImmutableTenuredPtr value = ptr; } - const T * address() { return &value; } + T get() const { return value; } + const T* address() { return &value; } }; /* diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index d246a0a8b06d..9c705de9acbf 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -369,6 +369,28 @@ js::TraceCrossCompartmentEdge(JSTracer* trc, JSObject* src, BarrieredBase* ds template void js::TraceCrossCompartmentEdge(JSTracer*, JSObject*, BarrieredBase*, const char*); +template +void +js::TraceProcessGlobalRoot(JSTracer* trc, T* thing, const char* name) +{ + JS_ROOT_MARKING_ASSERT(trc); + MOZ_ASSERT(ThingIsPermanentAtomOrWellKnownSymbol(thing)); + + // We have to mark permanent atoms and well-known symbols through a special + // method because the default DoMarking implementation automatically skips + // them. Fortunately, atoms (permanent and non) cannot refer to other GC + // things so they do not need to go through the mark stack and may simply + // be marked directly. Moreover, well-known symbols can refer only to + // permanent atoms, so likewise require no subsquent marking. + CheckMarkedThing(trc, thing); + if (trc->isMarkingTracer()) + thing->markIfUnmarked(gc::BLACK); + else + DoCallback(trc->asCallbackTracer(), ConvertToBase(&thing), name); +} +template void js::TraceProcessGlobalRoot(JSTracer*, JSAtom*, const char*); +template void js::TraceProcessGlobalRoot(JSTracer*, JS::Symbol*, const char*); + // This method is responsible for dynamic dispatch to the real tracer // implementation. Consider replacing this choke point with virtual dispatch: // a sufficiently smart C++ compiler may be able to devirtualize some paths. @@ -535,43 +557,6 @@ js::GCMarker::mark(T* thing) : gc::TenuredCell::fromPointer(thing)->markIfUnmarked(gc::BLACK); } -namespace js { -namespace gc { - -void -MarkPermanentAtom(JSTracer* trc, JSAtom* atom, const char* name) -{ - MOZ_ASSERT(atom->isPermanent()); - - // We have to mark permanent atoms through a special method because the - // default DoMarking implementation automatically skips them. Fortunatly, - // atoms cannot refer to other GC things, so they do not need to go through - // the mark stack and may simply be marked directly. - CheckMarkedThing(trc, atom); - if (trc->isMarkingTracer()) - atom->markIfUnmarked(); - else - DoCallback(trc->asCallbackTracer(), reinterpret_cast(&atom), name); -} - -void -MarkWellKnownSymbol(JSTracer* trc, JS::Symbol* sym) -{ - if (!sym) - return; - MOZ_ASSERT(sym->isWellKnownSymbol()); - - // As per permanent atoms, the normal marking path is not adequate. - CheckMarkedThing(trc, sym); - if (trc->isMarkingTracer()) { - // Permanent atoms are marked before well-known symbols. - MOZ_ASSERT(sym->description()->isMarked()); - sym->markIfUnmarked(); - } else { - DoCallback(trc->asCallbackTracer(), &sym, "wellKnownSymbol"); - } -} - template static inline void CheckIsMarkedThing(T* thingp) @@ -722,6 +707,9 @@ IsAboutToBeFinalizedInternal(jsid* idp) return rv; } +namespace js { +namespace gc { + template bool IsMarkedUnbarriered(T* thingp) diff --git a/js/src/gc/Marking.h b/js/src/gc/Marking.h index 18ad3c2a06c1..88fac633c7fc 100644 --- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -56,16 +56,15 @@ void TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc, JSObject* src, T* dst, const char* name); +// Permanent atoms and well-known symbols are shared between runtimes and must +// use a separate marking path so that we can filter them out of normal heap +// tracing. +template +void +TraceProcessGlobalRoot(JSTracer* trc, T* thing, const char* name); + namespace gc { -/*** Object Marking ***/ - -void -MarkPermanentAtom(JSTracer* trc, JSAtom* atom, const char* name); - -void -MarkWellKnownSymbol(JSTracer* trc, JS::Symbol* sym); - /* Return true if the pointer is nullptr, or if it is a tagged pointer to * nullptr. */ diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index ef2a0c27de99..09928dd0fb80 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -226,7 +226,7 @@ js::MarkPermanentAtoms(JSTracer* trc) const AtomStateEntry& entry = r.front(); JSAtom* atom = entry.asPtr(); - MarkPermanentAtom(trc, atom, "permanent_table"); + TraceProcessGlobalRoot(trc, atom, "permanent_table"); } } } @@ -241,7 +241,7 @@ js::MarkWellKnownSymbols(JSTracer* trc) if (WellKnownSymbols* wks = rt->wellKnownSymbols) { for (size_t i = 0; i < JS::WellKnownSymbolLimit; i++) - MarkWellKnownSymbol(trc, wks->get(i)); + TraceProcessGlobalRoot(trc, wks->get(i).get(), "well_known_symbol"); } } diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index 191b75725425..20096e8b26e0 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -809,14 +809,14 @@ StaticStrings::trace(JSTracer* trc) /* These strings never change, so barriers are not needed. */ for (uint32_t i = 0; i < UNIT_STATIC_LIMIT; i++) - MarkPermanentAtom(trc, unitStaticTable[i], "unit-static-string"); + TraceProcessGlobalRoot(trc, unitStaticTable[i], "unit-static-string"); for (uint32_t i = 0; i < NUM_SMALL_CHARS * NUM_SMALL_CHARS; i++) - MarkPermanentAtom(trc, length2StaticTable[i], "length2-static-string"); + TraceProcessGlobalRoot(trc, length2StaticTable[i], "length2-static-string"); /* This may mark some strings more than once, but so be it. */ for (uint32_t i = 0; i < INT_STATIC_LIMIT; i++) - MarkPermanentAtom(trc, intStaticTable[i], "int-static-string"); + TraceProcessGlobalRoot(trc, intStaticTable[i], "int-static-string"); } template From f9d798bcbdeca79460d2dd2058a9f379022ade48 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sat, 18 Apr 2015 20:12:27 -0400 Subject: [PATCH 014/241] Bug 1156030 - Remove some obsolete static assertion macros from the tree; r=Waldo --- dom/plugins/test/testplugin/nptest.cpp | 7 +++---- js/public/Utility.h | 14 -------------- js/src/jit/arm/Assembler-arm.cpp | 3 ++- xpcom/glue/nsDebug.h | 7 ------- 4 files changed, 5 insertions(+), 26 deletions(-) diff --git a/dom/plugins/test/testplugin/nptest.cpp b/dom/plugins/test/testplugin/nptest.cpp index 6271f33ba989..9378b6f94686 100644 --- a/dom/plugins/test/testplugin/nptest.cpp +++ b/dom/plugins/test/testplugin/nptest.cpp @@ -62,8 +62,6 @@ using namespace std; #define PLUGIN_VERSION "1.0.0.0" #define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0])) -#define STATIC_ASSERT(condition) \ - extern void np_static_assert(int arg[(condition) ? 1 : -1]) extern const char *sPluginName; extern const char *sPluginDescription; @@ -305,8 +303,9 @@ static const ScriptableFunction sPluginMethodFunctions[] = { echoString, }; -STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) == - ARRAY_LENGTH(sPluginMethodFunctions)); +static_assert(ARRAY_LENGTH(sPluginMethodIdentifierNames) == + ARRAY_LENGTH(sPluginMethodFunctions), + "Arrays should have the same size"); static const NPUTF8* sPluginPropertyIdentifierNames[] = { "propertyAndMethod" diff --git a/js/public/Utility.h b/js/public/Utility.h index 0c0e6e961e55..dff6a093c316 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -405,23 +405,11 @@ ScrambleHashCode(HashNumber h) # define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND))) # define STATIC_INVARIANT(COND) __attribute__((invariant(#COND))) # define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND))) -# define STATIC_PASTE2(X,Y) X ## Y -# define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y) -# define STATIC_ASSERT(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assert_static(#COND), unused)) \ - int STATIC_PASTE1(assert_static_, __COUNTER__); \ - JS_END_MACRO # define STATIC_ASSUME(COND) \ JS_BEGIN_MACRO \ __attribute__((assume_static(#COND), unused)) \ int STATIC_PASTE1(assume_static_, __COUNTER__); \ JS_END_MACRO -# define STATIC_ASSERT_RUNTIME(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assert_static_runtime(#COND), unused)) \ - int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \ - JS_END_MACRO # else /* XGILL_PLUGIN */ # define STATIC_PRECONDITION(COND) /* nothing */ # define STATIC_PRECONDITION_ASSUME(COND) /* nothing */ @@ -429,9 +417,7 @@ ScrambleHashCode(HashNumber h) # define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */ # define STATIC_INVARIANT(COND) /* nothing */ # define STATIC_INVARIANT_ASSUME(COND) /* nothing */ -# define STATIC_ASSERT(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO # define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO -# define STATIC_ASSERT_RUNTIME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO # endif /* XGILL_PLUGIN */ # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) #endif /* HAVE_STATIC_ANNOTATIONS */ diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index 4e12aeabf4f5..d51303b4b79a 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -2722,7 +2722,8 @@ struct PoolHeader : Instruction { void Assembler::WritePoolHeader(uint8_t* start, Pool* p, bool isNatural) { - STATIC_ASSERT(sizeof(PoolHeader) == 4); + static_assert(sizeof(PoolHeader) == 4, + "PoolHandler must have the correct size."); uint8_t* pool = start + 4; // Go through the usual rigmarole to get the size of the pool. pool += p->getPoolSize(); diff --git a/xpcom/glue/nsDebug.h b/xpcom/glue/nsDebug.h index 40a201c631b0..9e2571590e78 100644 --- a/xpcom/glue/nsDebug.h +++ b/xpcom/glue/nsDebug.h @@ -197,12 +197,6 @@ inline void MOZ_PretendNoReturn() #define STATIC_PASTE2(X,Y) X ## Y #define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y) -#define STATIC_ASSERT(COND) \ - do { \ - __attribute__((assert_static(#COND), unused)) \ - int STATIC_PASTE1(assert_static_, __COUNTER__); \ - } while(0) - #define STATIC_ASSUME(COND) \ do { \ __attribute__((assume_static(#COND), unused)) \ @@ -224,7 +218,6 @@ inline void MOZ_PretendNoReturn() #define STATIC_INVARIANT(COND) /* nothing */ #define STATIC_INVARIANT_ASSUME(COND) /* nothing */ -#define STATIC_ASSERT(COND) do { /* nothing */ } while(0) #define STATIC_ASSUME(COND) do { /* nothing */ } while(0) #define STATIC_ASSERT_RUNTIME(COND) do { /* nothing */ } while(0) From c65d93b69c5fedf749846308dfa67f7f0889738a Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 21 Apr 2015 14:09:03 -0400 Subject: [PATCH 015/241] Bug 1156880 - Null check the prescontext in nsDOMWindowUtils::AdvanceTimeAndRefresh; r=mstange --- dom/base/nsDOMWindowUtils.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 1e6d9eb2667a..f2363309bfca 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2354,12 +2354,15 @@ nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds) } } - nsRefreshDriver* driver = GetPresContext()->RefreshDriver(); - driver->AdvanceTimeAndRefresh(aMilliseconds); + nsPresContext* presContext = GetPresContext(); + if (presContext) { + nsRefreshDriver* driver = presContext->RefreshDriver(); + driver->AdvanceTimeAndRefresh(aMilliseconds); - RefPtr transaction = GetLayerTransaction(); - if (transaction && transaction->IPCOpen()) { - transaction->SendSetTestSampleTime(driver->MostRecentRefresh()); + RefPtr transaction = GetLayerTransaction(); + if (transaction && transaction->IPCOpen()) { + transaction->SendSetTestSampleTime(driver->MostRecentRefresh()); + } } return NS_OK; From ccd0c74313aa2f0a7e18a2051858a9f73b1a5e71 Mon Sep 17 00:00:00 2001 From: Nicholas Hurley Date: Mon, 20 Apr 2015 11:07:16 -0700 Subject: [PATCH 016/241] Bug 1130822 - properly decode arbitrarily aligned data for non-tier1 platforms. r=mcmanus Modified from original patch by Martin Husemann --- netwerk/protocol/http/Http2Session.cpp | 96 ++++++++++---------------- 1 file changed, 37 insertions(+), 59 deletions(-) diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index 0dc9189c478e..ed025666be61 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -19,6 +19,7 @@ #include "Http2Stream.h" #include "Http2Push.h" +#include "mozilla/Endian.h" #include "mozilla/Telemetry.h" #include "mozilla/Preferences.h" #include "nsHttp.h" @@ -137,30 +138,6 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio mNegotiatedToken.AssignLiteral(HTTP2_DRAFT_LATEST_TOKEN); } -// Copy the 32 bit number into the destination, using network byte order -// in the destination. -template static void -CopyAsNetwork32(charType dest, // where to store it - uint32_t number) // the 32 bit number in native format -{ - number = PR_htonl(number); - memcpy(dest, &number, sizeof(number)); -} - -template void CopyAsNetwork32(char *dest, uint32_t number); -template void CopyAsNetwork32(uint8_t *dest, uint32_t number); - -template static void -CopyAsNetwork16(charType dest, // where to store it - uint16_t number) // the 16 bit number in native format -{ - number = PR_htons(number); - memcpy(dest, &number, sizeof(number)); -} - -template void CopyAsNetwork16(char *dest, uint16_t number); -template void CopyAsNetwork16(uint8_t *dest, uint16_t number); - PLDHashOperator Http2Session::ShutdownEnumerator(nsAHttpTransaction *key, nsAutoPtr &stream, @@ -679,10 +656,10 @@ Http2Session::CreateFrameHeader(charType dest, uint16_t frameLength, MOZ_ASSERT(!(streamID & 0x80000000)); dest[0] = 0x00; - CopyAsNetwork16(dest + 1, frameLength); + NetworkEndian::writeUint16(dest + 1, frameLength); dest[3] = frameType; dest[4] = frameFlags; - CopyAsNetwork32(dest + 5, streamID); + NetworkEndian::writeUint32(dest + 5, streamID); } char * @@ -789,7 +766,7 @@ Http2Session::GeneratePriority(uint32_t aID, uint8_t aPriorityWeight) mOutputQueueUsed += frameSize; CreateFrameHeader(packet, 5, FRAME_TYPE_PRIORITY, 0, aID); - CopyAsNetwork32(packet + kFrameHeaderBytes, 0); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes, 0); memcpy(packet + frameSize - 1, &aPriorityWeight, 1); LogIO(this, nullptr, "Generate Priority", packet, frameSize); FlushOutputQueue(); @@ -816,7 +793,7 @@ Http2Session::GenerateRstStream(uint32_t aStatusCode, uint32_t aID) mOutputQueueUsed += frameSize; CreateFrameHeader(packet, 4, FRAME_TYPE_RST_STREAM, 0, aID); - CopyAsNetwork32(packet + kFrameHeaderBytes, aStatusCode); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes, aStatusCode); LogIO(this, nullptr, "Generate Reset", packet, frameSize); FlushOutputQueue(); @@ -835,10 +812,10 @@ Http2Session::GenerateGoAway(uint32_t aStatusCode) CreateFrameHeader(packet, 8, FRAME_TYPE_GOAWAY, 0, 0); // last-good-stream-id are bytes 9-12 reflecting pushes - CopyAsNetwork32(packet + kFrameHeaderBytes, mOutgoingGoAwayID); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes, mOutgoingGoAwayID); // bytes 13-16 are the status code. - CopyAsNetwork32(packet + frameSize - 4, aStatusCode); + NetworkEndian::writeUint32(packet + frameSize - 4, aStatusCode); LogIO(this, nullptr, "Generate GoAway", packet, frameSize); FlushOutputQueue(); @@ -884,11 +861,11 @@ Http2Session::SendHello() if (!gHttpHandler->AllowPush()) { // If we don't support push then set MAX_CONCURRENT to 0 and also // set ENABLE_PUSH to 0 - CopyAsNetwork16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_ENABLE_PUSH); + NetworkEndian::writeUint16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_ENABLE_PUSH); // The value portion of the setting pair is already initialized to 0 numberOfEntries++; - CopyAsNetwork16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_MAX_CONCURRENT); + NetworkEndian::writeUint16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_MAX_CONCURRENT); // The value portion of the setting pair is already initialized to 0 numberOfEntries++; @@ -897,14 +874,14 @@ Http2Session::SendHello() // Advertise the Push RWIN for the session, and on each new pull stream // send a window update - CopyAsNetwork16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_INITIAL_WINDOW); - CopyAsNetwork32(packet + kFrameHeaderBytes + (6 * numberOfEntries) + 2, mPushAllowance); + NetworkEndian::writeUint16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_INITIAL_WINDOW); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes + (6 * numberOfEntries) + 2, mPushAllowance); numberOfEntries++; // Make sure the other endpoint knows that we're sticking to the default max // frame size - CopyAsNetwork16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_MAX_FRAME_SIZE); - CopyAsNetwork32(packet + kFrameHeaderBytes + (6 * numberOfEntries) + 2, kMaxFrameData); + NetworkEndian::writeUint16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_MAX_FRAME_SIZE); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes + (6 * numberOfEntries) + 2, kMaxFrameData); numberOfEntries++; MOZ_ASSERT(numberOfEntries <= maxSettings); @@ -923,7 +900,7 @@ Http2Session::SendHello() packet = mOutputQueueBuffer.get() + mOutputQueueUsed; CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, 0); mOutputQueueUsed += kFrameHeaderBytes + 4; - CopyAsNetwork32(packet + kFrameHeaderBytes, sessionWindowBump); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes, sessionWindowBump); LOG3(("Session Window increase at start of session %p %u\n", this, sessionWindowBump)); @@ -963,7 +940,7 @@ Http2Session::CreatePriorityNode(uint32_t streamID, uint32_t dependsOn, uint8_t char *packet = mOutputQueueBuffer.get() + mOutputQueueUsed; CreateFrameHeader(packet, 5, FRAME_TYPE_PRIORITY, 0, streamID); mOutputQueueUsed += kFrameHeaderBytes + 5; - CopyAsNetwork32(packet + kFrameHeaderBytes, dependsOn); // depends on + NetworkEndian::writeUint32(packet + kFrameHeaderBytes, dependsOn); // depends on packet[kFrameHeaderBytes + 4] = weight; // weight LOG3(("Http2Session %p generate Priority Frame 0x%X depends on 0x%X " @@ -1392,8 +1369,8 @@ Http2Session::RecvPriority(Http2Session *self) if (NS_FAILED(rv)) return rv; - uint32_t newPriorityDependency = - PR_ntohl(*reinterpret_cast(self->mInputFrameBuffer.get() + kFrameHeaderBytes)); + uint32_t newPriorityDependency = NetworkEndian::readUint32( + self->mInputFrameBuffer.get() + kFrameHeaderBytes); bool exclusive = !!(newPriorityDependency & 0x80000000); newPriorityDependency &= 0x7fffffff; uint8_t newPriorityWeight = *(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 4); @@ -1423,8 +1400,8 @@ Http2Session::RecvRstStream(Http2Session *self) RETURN_SESSION_ERROR(self, PROTOCOL_ERROR); } - self->mDownstreamRstReason = - PR_ntohl(*reinterpret_cast(self->mInputFrameBuffer.get() + kFrameHeaderBytes)); + self->mDownstreamRstReason = NetworkEndian::readUint32( + self->mInputFrameBuffer.get() + kFrameHeaderBytes); LOG3(("Http2Session::RecvRstStream %p RST_STREAM Reason Code %u ID %x\n", self, self->mDownstreamRstReason, self->mInputFrameID)); @@ -1485,8 +1462,8 @@ Http2Session::RecvSettings(Http2Session *self) uint8_t *setting = reinterpret_cast (self->mInputFrameBuffer.get()) + kFrameHeaderBytes + index * 6; - uint16_t id = PR_ntohs(*reinterpret_cast(setting)); - uint32_t value = PR_ntohl(*reinterpret_cast(setting + 2)); + uint16_t id = NetworkEndian::readUint16(setting); + uint32_t value = NetworkEndian::readUint32(setting + 2); LOG3(("Settings ID %u, Value %u", id, value)); switch (id) @@ -1572,8 +1549,8 @@ Http2Session::RecvPushPromise(Http2Session *self) return rv; } promiseLen = 4; - promisedID = - PR_ntohl(*reinterpret_cast(self->mInputFrameBuffer.get() + kFrameHeaderBytes + paddingControlBytes)); + promisedID = NetworkEndian::readUint32( + self->mInputFrameBuffer.get() + kFrameHeaderBytes + paddingControlBytes); promisedID &= 0x7fffffff; } @@ -1835,12 +1812,12 @@ Http2Session::RecvGoAway(Http2Session *self) } self->mShouldGoAway = true; - self->mGoAwayID = - PR_ntohl(*reinterpret_cast(self->mInputFrameBuffer.get() + kFrameHeaderBytes)); + self->mGoAwayID = NetworkEndian::readUint32( + self->mInputFrameBuffer.get() + kFrameHeaderBytes); self->mGoAwayID &= 0x7fffffff; self->mCleanShutdown = true; - uint32_t statusCode = - PR_ntohl(*reinterpret_cast(self->mInputFrameBuffer.get() + kFrameHeaderBytes + 4)); + uint32_t statusCode = NetworkEndian::readUint32( + self->mInputFrameBuffer.get() + kFrameHeaderBytes + 4); // Find streams greater than the last-good ID and mark them for deletion // in the mGoAwayStreamsToRestart queue with the GoAwayEnumerator. The @@ -1913,8 +1890,8 @@ Http2Session::RecvWindowUpdate(Http2Session *self) RETURN_SESSION_ERROR(self, PROTOCOL_ERROR); } - uint32_t delta = - PR_ntohl(*reinterpret_cast(self->mInputFrameBuffer.get() + kFrameHeaderBytes)); + uint32_t delta = NetworkEndian::readUint32( + self->mInputFrameBuffer.get() + kFrameHeaderBytes); delta &= 0x7fffffff; LOG3(("Http2Session::RecvWindowUpdate %p len=%d Stream 0x%X.\n", @@ -2089,8 +2066,8 @@ Http2Session::RecvAltSvc(Http2Session *self) return NS_OK; } - uint16_t originLen = - PR_ntohs(*reinterpret_cast(self->mInputFrameBuffer.get() + kFrameHeaderBytes)); + uint16_t originLen = NetworkEndian::readUint16( + self->mInputFrameBuffer.get() + kFrameHeaderBytes); if (originLen + 2U > self->mInputFrameDataSize) { LOG3(("Http2Session::RecvAltSvc %p origin len too big for frame", self)); self->ResetDownstreamState(); @@ -2551,15 +2528,16 @@ Http2Session::WriteSegments(nsAHttpSegmentWriter *writer, // 3 bytes of length, 1 type byte, 1 flag byte, 1 unused bit, 31 bits of ID uint8_t totallyWastedByte = mInputFrameBuffer.get()[0]; - mInputFrameDataSize = PR_ntohs(*reinterpret_cast(mInputFrameBuffer.get() + 1)); + mInputFrameDataSize = NetworkEndian::readUint16( + mInputFrameBuffer.get() + 1); if (totallyWastedByte || (mInputFrameDataSize > kMaxFrameData)) { LOG3(("Got frame too large 0x%02X%04X", totallyWastedByte, mInputFrameDataSize)); RETURN_SESSION_ERROR(this, PROTOCOL_ERROR); } mInputFrameType = *reinterpret_cast(mInputFrameBuffer.get() + kFrameLengthBytes); mInputFrameFlags = *reinterpret_cast(mInputFrameBuffer.get() + kFrameLengthBytes + kFrameTypeBytes); - mInputFrameID = - PR_ntohl(*reinterpret_cast(mInputFrameBuffer.get() + kFrameLengthBytes + kFrameTypeBytes + kFrameFlagBytes)); + mInputFrameID = NetworkEndian::readUint32( + mInputFrameBuffer.get() + kFrameLengthBytes + kFrameTypeBytes + kFrameFlagBytes); mInputFrameID &= 0x7fffffff; mInputFrameDataRead = 0; @@ -2906,7 +2884,7 @@ Http2Session::UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes) MOZ_ASSERT(mOutputQueueUsed <= mOutputQueueSize); CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, stream->StreamID()); - CopyAsNetwork32(packet + kFrameHeaderBytes, toack); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes, toack); LogIO(this, stream, "Stream Window Update", packet, kFrameHeaderBytes + 4); // dont flush here, this write can commonly be coalesced with a @@ -2949,7 +2927,7 @@ Http2Session::UpdateLocalSessionWindow(uint32_t bytes) MOZ_ASSERT(mOutputQueueUsed <= mOutputQueueSize); CreateFrameHeader(packet, 4, FRAME_TYPE_WINDOW_UPDATE, 0, 0); - CopyAsNetwork32(packet + kFrameHeaderBytes, toack); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes, toack); LogIO(this, nullptr, "Session Window Update", packet, kFrameHeaderBytes + 4); // dont flush here, this write can commonly be coalesced with others From 472d457bcc871b7b6065fee49c10b5b2b2c5d3b8 Mon Sep 17 00:00:00 2001 From: Mike Kaply Date: Tue, 21 Apr 2015 13:31:09 -0500 Subject: [PATCH 017/241] Bug 916101 - Show entire pref name when wanring about size, r=mossop --- modules/libpref/nsPrefBranch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libpref/nsPrefBranch.cpp b/modules/libpref/nsPrefBranch.cpp index 49d775046319..63ecdb525904 100644 --- a/modules/libpref/nsPrefBranch.cpp +++ b/modules/libpref/nsPrefBranch.cpp @@ -378,7 +378,7 @@ nsresult nsPrefBranch::CheckSanityOfStringLength(const char* aPrefName, const ui } nsAutoCString message(nsPrintfCString("Warning: attempting to write %d bytes to preference %s. This is bad for general performance and memory usage. Such an amount of data should rather be written to an external file.", aLength, - aPrefName)); + getPrefName(aPrefName))); rv = console->LogStringMessage(NS_ConvertUTF8toUTF16(message).get()); if (NS_FAILED(rv)) { return rv; From 489c281fe6d78829be2f44393054e2dc617aa9c2 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Mon, 20 Apr 2015 17:04:33 -0600 Subject: [PATCH 018/241] Bug 1155503: BrowserStreamParent should null out its NPStream pointer and we should check for it; r=jimm --HG-- extra : rebase_source : 5dd15452653114a17e1b9504932cd71934b69c36 --- dom/plugins/ipc/BrowserStreamParent.cpp | 6 +++--- dom/plugins/ipc/PluginInstanceParent.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dom/plugins/ipc/BrowserStreamParent.cpp b/dom/plugins/ipc/BrowserStreamParent.cpp index 7ce3fd612818..9bc243ce1b9d 100644 --- a/dom/plugins/ipc/BrowserStreamParent.cpp +++ b/dom/plugins/ipc/BrowserStreamParent.cpp @@ -35,6 +35,7 @@ BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp, BrowserStreamParent::~BrowserStreamParent() { + mStream->pdata = nullptr; } void @@ -51,7 +52,6 @@ BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv, PluginAsyncSurrogate* surrogate = mNPP->GetAsyncSurrogate(); MOZ_ASSERT(surrogate); surrogate->AsyncCallArriving(); - nsRefPtr streamListener = mStreamListener.forget(); if (mState == DEFERRING_DESTROY) { // We've been asked to destroy ourselves before init was complete. mState = DYING; @@ -61,10 +61,10 @@ BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv, NPError error = rv; if (error == NPERR_NO_ERROR) { - if (!streamListener) { + if (!mStreamListener) { return false; } - if (streamListener->SetStreamType(stype)) { + if (mStreamListener->SetStreamType(stype)) { mState = ALIVE; } else { error = NPERR_GENERIC_ERROR; diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index ac3b925e67fb..e4f52213161b 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -1419,6 +1419,12 @@ PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason) FULLFUNCTION, (void*) stream, (int) reason)); AStream* s = static_cast(stream->pdata); + if (!s) { + // The stream has already been deleted by other means. + // With async plugin init this could happen if async NPP_NewStream + // returns an error code. + return NPERR_NO_ERROR; + } if (s->IsBrowserStream()) { BrowserStreamParent* sp = static_cast(s); From f9d34d3d0210ab8edc11d21eeaead73368c29c30 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Tue, 14 Apr 2015 19:38:50 +0100 Subject: [PATCH 019/241] Bug 1150054, part 1 - Pull down the upstreamed version of EventWatcher from the web-platform-tests js harness into imptests. r=Ms2ger --HG-- extra : rebase_source : bfff7b04ddd146847dc216aba76bf51f3f3ad790 --- dom/imptests/testharness.js | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/dom/imptests/testharness.js b/dom/imptests/testharness.js index a133672f8de4..0862f15653d3 100644 --- a/dom/imptests/testharness.js +++ b/dom/imptests/testharness.js @@ -464,6 +464,74 @@ policies and contribution forms [3]. })); } + /** + * This constructor helper allows DOM events to be handled using Promises, + * which can make it a lot easier to test a very specific series of events, + * including ensuring that unexpected events are not fired at any point. + */ + function EventWatcher(test, watchedNode, eventTypes) + { + if (typeof eventTypes == 'string') { + eventTypes = [eventTypes]; + } + + var waitingFor = null; + + var eventHandler = test.step_func(function(evt) { + assert_true(!!waitingFor, + 'Not expecting event, but got ' + evt.type + ' event'); + assert_equals(evt.type, waitingFor.types[0], + 'Expected ' + waitingFor.types[0] + ' event, but got ' + + evt.type + ' event instead'); + if (waitingFor.types.length > 1) { + // Pop first event from array + waitingFor.types.shift(); + return; + } + // We need to null out waitingFor before calling the resolve function + // since the Promise's resolve handlers may call wait_for() which will + // need to set waitingFor. + var resolveFunc = waitingFor.resolve; + waitingFor = null; + resolveFunc(evt); + }); + + for (var i = 0; i < eventTypes.length; i++) { + watchedNode.addEventListener(eventTypes[i], eventHandler); + } + + /** + * Returns a Promise that will resolve after the specified event or + * series of events has occured. + */ + this.wait_for = function(types) { + if (waitingFor) { + return Promise.reject('Already waiting for an event or events'); + } + if (typeof types == 'string') { + types = [types]; + } + return new Promise(function(resolve, reject) { + waitingFor = { + types: types, + resolve: resolve, + reject: reject + }; + }); + }; + + function stop_watching() { + for (var i = 0; i < eventTypes.length; i++) { + watchedNode.removeEventListener(eventTypes[i], eventHandler); + } + }; + + test.add_cleanup(stop_watching); + + return this; + } + expose(EventWatcher, 'EventWatcher'); + function setup(func_or_properties, maybe_properties) { var func = null; From 70590b52f40d0889ed077c6ac3b2da72918508eb Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Tue, 14 Apr 2015 20:54:10 +0100 Subject: [PATCH 020/241] Bug 1150054, part 2 - Convert the Web Animations tests to use the new EventWatcher constructor from upstream. r=Ms2ger --HG-- extra : rebase_source : 2ba088b32444753ebf1e34b7ccd9c6b22b13b780 --- .../test_animation-currenttime.html | 158 +++--------------- .../test_animation-starttime.html | 158 +++--------------- .../test_animation-currenttime.html | 118 +------------ .../test_animation-starttime.html | 117 +------------ 4 files changed, 51 insertions(+), 500 deletions(-) diff --git a/dom/animation/test/css-animations/test_animation-currenttime.html b/dom/animation/test/css-animations/test_animation-currenttime.html index 2d804c7656e9..72d3de2732b3 100644 --- a/dom/animation/test/css-animations/test_animation-currenttime.html +++ b/dom/animation/test/css-animations/test_animation-currenttime.html @@ -83,112 +83,6 @@ const TEN_PCT_POSITION = 110; const FIFTY_PCT_POSITION = 150; const END_POSITION = 200; -/** - * CSS animation events fire asynchronously after we set 'startTime'. This - * helper class allows us to handle such events using Promises. - * - * To use this class: - * - * var eventWatcher = new EventWatcher(watchedNode, eventTypes); - * eventWatcher.waitForEvent(eventType).then(function() { - * // Promise fulfilled - * checkStuff(); - * makeSomeChanges(); - * return eventWatcher.waitForEvent(nextEventType); - * }).then(function() { - * // Promise fulfilled - * checkMoreStuff(); - * eventWatcher.stopWatching(); // all done - stop listening for events - * }); - * - * This class will assert_unreached() if an event occurs when there is no - * Promise created by a waitForEvent() call waiting to be fulfilled, or if the - * event is of a different type to the type passed to waitForEvent. This helps - * provide test coverage to ensure that only events that are expected occur, in - * the correct order and with the correct timing. It also helps vastly simplify - * the already complex code below by avoiding lots of gnarly error handling - * code. - */ -function EventWatcher(watchedNode, eventTypes) -{ - if (typeof eventTypes == 'string') { - eventTypes = [eventTypes]; - } - - var waitingFor = null; - - function eventHandler(evt) { - if (!waitingFor) { - assert_unreached('Not expecting event, but got: ' + evt.type + - ' targeting element #' + evt.target.getAttribute('id')); - return; - } - if (evt.type != waitingFor.types[0]) { - assert_unreached('Expected ' + waitingFor.types[0] + ' event but got ' + - evt.type + ' event'); - return; - } - if (waitingFor.types.length > 1) { - // Pop first event from array - waitingFor.types.shift(); - return; - } - // We need to null out waitingFor before calling the resolve function since - // the Promise's resolve handlers may call waitForEvent() which will need - // to set waitingFor. - var resolveFunc = waitingFor.resolve; - waitingFor = null; - resolveFunc(evt); - } - - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.addEventListener(eventTypes[i], eventHandler); - } - - this.waitForEvent = function(type) { - if (typeof type != 'string') { - return Promise.reject('Event type not a string'); - } - return this.waitForEvents([type]); - }; - - /** - * This is useful when two events are expected to fire one immediately after - * the other. This happens when we skip over the entire active interval for - * instance. In this case an 'animationstart' and an 'animationend' are fired - * and due to the asynchronous nature of Promise callbacks this won't work: - * - * eventWatcher.waitForEvent('animationstart').then(function() { - * return waitForEvent('animationend'); - * }).then(...); - * - * It doesn't work because the 'animationend' listener is added too late, - * because the resolve handler for the first Promise is called asynchronously - * some time after the 'animationstart' event is called, rather than at the - * time the event reaches the watched element. - */ - this.waitForEvents = function(types) { - if (waitingFor) { - return Promise.reject('Already waiting for an event'); - } - return new Promise(function(resolve, reject) { - waitingFor = { - types: types, - resolve: resolve, - reject: reject - }; - }); - }; - - this.stopWatching = function() { - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.removeEventListener(eventTypes[i], eventHandler); - } - }; - - return this; -} - // The terms used for the naming of the following helper functions refer to // terms used in the Web Animations specification for specific phases of an // animation. The terms can be found here: @@ -336,7 +230,7 @@ test(function(t) async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; @@ -347,7 +241,7 @@ async_test(function(t) { animation.currentTime = currentTimeForStartOfActiveInterval(animation.timeline); - return eventWatcher.waitForEvent('animationstart'); + return eventWatcher.wait_for('animationstart'); })).then(t.step_func(function() { checkStateAtActiveIntervalStartTime(animation); @@ -357,11 +251,9 @@ async_test(function(t) { animation.currentTime = currentTimeForEndOfActiveInterval(animation.timeline); - return eventWatcher.waitForEvent('animationend'); + return eventWatcher.wait_for('animationend'); })).then(t.step_func(function() { checkStateAtActiveIntervalEndTime(animation); - - eventWatcher.stopWatching(); })).catch(t.step_func(function(reason) { assert_unreached(reason); })).then(function() { @@ -372,7 +264,7 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; @@ -389,8 +281,8 @@ async_test(function(t) { // an 'animationend' event. We need to wait for these events before we start // testing going backwards since EventWatcher will fail the test if it gets // an event that we haven't told it about. - eventWatcher.waitForEvents(['animationstart', - 'animationend']).then(t.step_func(function() { + eventWatcher.wait_for(['animationstart', + 'animationend']).then(t.step_func(function() { assert_true(document.timeline.currentTime - previousTimelineTime < ANIM_DUR_MS, 'Sanity check that seeking worked rather than the events ' + @@ -410,9 +302,9 @@ async_test(function(t) { // // Calling checkStateAtFiftyPctOfActiveInterval will check computed style, // causing computed style to be updated and the 'animationstart' event to - // be dispatched synchronously. We need to call waitForEvent first + // be dispatched synchronously. We need to call wait_for first // otherwise eventWatcher will assert that the event was unexpected. - var promise = eventWatcher.waitForEvent('animationstart'); + var promise = eventWatcher.wait_for('animationstart'); checkStateAtFiftyPctOfActiveInterval(animation); return promise; })).then(t.step_func(function() { @@ -424,11 +316,9 @@ async_test(function(t) { // Despite going backwards from just after the active interval starts to // the animation start time, we now expect an animationend event // because we went from inside to outside the active interval. - return eventWatcher.waitForEvent('animationend'); + return eventWatcher.wait_for('animationend'); })).then(t.step_func(function() { checkStateOnReadyPromiseResolved(animation); - - eventWatcher.stopWatching(); })).catch(t.step_func(function(reason) { assert_unreached(reason); })).then(function() { @@ -454,7 +344,7 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; @@ -462,14 +352,13 @@ async_test(function(t) { animation.currentTime = currentTimeForBeforePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }, 'Redundant change, before -> active, then back'); async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; @@ -477,23 +366,21 @@ async_test(function(t) { animation.currentTime = currentTimeForBeforePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }, 'Redundant change, before -> after, then back'); async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvent('animationstart').then(function() { + eventWatcher.wait_for('animationstart').then(function() { animation.currentTime = currentTimeForBeforePhase(animation.timeline); animation.currentTime = currentTimeForActivePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); @@ -503,16 +390,15 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvent('animationstart').then(function() { + eventWatcher.wait_for('animationstart').then(function() { animation.currentTime = currentTimeForAfterPhase(animation.timeline); animation.currentTime = currentTimeForActivePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); @@ -522,17 +408,16 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvents(['animationstart', - 'animationend']).then(function() { + eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { animation.currentTime = currentTimeForBeforePhase(animation.timeline); animation.currentTime = currentTimeForAfterPhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); @@ -542,17 +427,16 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvents(['animationstart', - 'animationend']).then(function() { + eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { animation.currentTime = currentTimeForActivePhase(animation.timeline); animation.currentTime = currentTimeForAfterPhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); diff --git a/dom/animation/test/css-animations/test_animation-starttime.html b/dom/animation/test/css-animations/test_animation-starttime.html index 7fdd9732ce49..0dda2dc33721 100644 --- a/dom/animation/test/css-animations/test_animation-starttime.html +++ b/dom/animation/test/css-animations/test_animation-starttime.html @@ -83,112 +83,6 @@ const TEN_PCT_POSITION = 110; const FIFTY_PCT_POSITION = 150; const END_POSITION = 200; -/** - * CSS animation events fire asynchronously after we set 'startTime'. This - * helper class allows us to handle such events using Promises. - * - * To use this class: - * - * var eventWatcher = new EventWatcher(watchedNode, eventTypes); - * eventWatcher.waitForEvent(eventType).then(function() { - * // Promise fulfilled - * checkStuff(); - * makeSomeChanges(); - * return eventWatcher.waitForEvent(nextEventType); - * }).then(function() { - * // Promise fulfilled - * checkMoreStuff(); - * eventWatcher.stopWatching(); // all done - stop listening for events - * }); - * - * This class will assert_unreached() if an event occurs when there is no - * Promise created by a waitForEvent() call waiting to be fulfilled, or if the - * event is of a different type to the type passed to waitForEvent. This helps - * provide test coverage to ensure that only events that are expected occur, in - * the correct order and with the correct timing. It also helps vastly simplify - * the already complex code below by avoiding lots of gnarly error handling - * code. - */ -function EventWatcher(watchedNode, eventTypes) -{ - if (typeof eventTypes == 'string') { - eventTypes = [eventTypes]; - } - - var waitingFor = null; - - function eventHandler(evt) { - if (!waitingFor) { - assert_unreached('Not expecting event, but got: ' + evt.type + - ' targeting element #' + evt.target.getAttribute('id')); - return; - } - if (evt.type != waitingFor.types[0]) { - assert_unreached('Expected ' + waitingFor.types[0] + ' event but got ' + - evt.type + ' event'); - return; - } - if (waitingFor.types.length > 1) { - // Pop first event from array - waitingFor.types.shift(); - return; - } - // We need to null out waitingFor before calling the resolve function since - // the Promise's resolve handlers may call waitForEvent() which will need - // to set waitingFor. - var resolveFunc = waitingFor.resolve; - waitingFor = null; - resolveFunc(evt); - } - - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.addEventListener(eventTypes[i], eventHandler); - } - - this.waitForEvent = function(type) { - if (typeof type != 'string') { - return Promise.reject('Event type not a string'); - } - return this.waitForEvents([type]); - }; - - /** - * This is useful when two events are expected to fire one immediately after - * the other. This happens when we skip over the entire active interval for - * instance. In this case an 'animationstart' and an 'animationend' are fired - * and due to the asynchronous nature of Promise callbacks this won't work: - * - * eventWatcher.waitForEvent('animationstart').then(function() { - * return waitForEvent('animationend'); - * }).then(...); - * - * It doesn't work because the 'animationend' listener is added too late, - * because the resolve handler for the first Promise is called asynchronously - * some time after the 'animationstart' event is called, rather than at the - * time the event reaches the watched element. - */ - this.waitForEvents = function(types) { - if (waitingFor) { - return Promise.reject('Already waiting for an event'); - } - return new Promise(function(resolve, reject) { - waitingFor = { - types: types, - resolve: resolve, - reject: reject - }; - }); - }; - - this.stopWatching = function() { - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.removeEventListener(eventTypes[i], eventHandler); - } - }; - - return this; -} - // The terms used for the naming of the following helper functions refer to // terms used in the Web Animations specification for specific phases of an // animation. The terms can be found here: @@ -390,7 +284,7 @@ test(function(t) async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; @@ -400,7 +294,7 @@ async_test(function(t) { checkStateOnReadyPromiseResolved(animation); animation.startTime = startTimeForStartOfActiveInterval(animation.timeline); - return eventWatcher.waitForEvent('animationstart'); + return eventWatcher.wait_for('animationstart'); })).then(t.step_func(function() { checkStateAtActiveIntervalStartTime(animation); @@ -409,11 +303,9 @@ async_test(function(t) { checkStateAtFiftyPctOfActiveInterval(animation); animation.startTime = startTimeForEndOfActiveInterval(animation.timeline); - return eventWatcher.waitForEvent('animationend'); + return eventWatcher.wait_for('animationend'); })).then(t.step_func(function() { checkStateAtActiveIntervalEndTime(animation); - - eventWatcher.stopWatching(); })).catch(t.step_func(function(reason) { assert_unreached(reason); })).then(function() { @@ -424,7 +316,7 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; @@ -438,8 +330,8 @@ async_test(function(t) { // an 'animationend' event. We need to wait for these events before we start // testing going backwards since EventWatcher will fail the test if it gets // an event that we haven't told it about. - eventWatcher.waitForEvents(['animationstart', - 'animationend']).then(t.step_func(function() { + eventWatcher.wait_for(['animationstart', + 'animationend']).then(t.step_func(function() { assert_true(document.timeline.currentTime - previousTimelineTime < ANIM_DUR_MS, 'Sanity check that seeking worked rather than the events ' + @@ -459,9 +351,9 @@ async_test(function(t) { // // Calling checkStateAtFiftyPctOfActiveInterval will check computed style, // causing computed style to be updated and the 'animationstart' event to - // be dispatched synchronously. We need to call waitForEvent first + // be dispatched synchronously. We need to call wait_for first // otherwise eventWatcher will assert that the event was unexpected. - var promise = eventWatcher.waitForEvent('animationstart'); + var promise = eventWatcher.wait_for('animationstart'); checkStateAtFiftyPctOfActiveInterval(animation); return promise; })).then(t.step_func(function() { @@ -472,11 +364,9 @@ async_test(function(t) { // Despite going backwards from just after the active interval starts to // the animation start time, we now expect an animationend event // because we went from inside to outside the active interval. - return eventWatcher.waitForEvent('animationend'); + return eventWatcher.wait_for('animationend'); })).then(t.step_func(function() { checkStateOnReadyPromiseResolved(animation); - - eventWatcher.stopWatching(); })).catch(t.step_func(function(reason) { assert_unreached(reason); })).then(function() { @@ -502,7 +392,7 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; @@ -510,14 +400,13 @@ async_test(function(t) { animation.startTime = startTimeForBeforePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }, 'Redundant change, before -> active, then back'); async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; @@ -525,23 +414,21 @@ async_test(function(t) { animation.startTime = startTimeForBeforePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }, 'Redundant change, before -> after, then back'); async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvent('animationstart').then(function() { + eventWatcher.wait_for('animationstart').then(function() { animation.startTime = startTimeForBeforePhase(animation.timeline); animation.startTime = startTimeForActivePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); @@ -551,16 +438,15 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvent('animationstart').then(function() { + eventWatcher.wait_for('animationstart').then(function() { animation.startTime = startTimeForAfterPhase(animation.timeline); animation.startTime = startTimeForActivePhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); @@ -570,17 +456,16 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvents(['animationstart', - 'animationend']).then(function() { + eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { animation.startTime = startTimeForBeforePhase(animation.timeline); animation.startTime = startTimeForAfterPhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); @@ -590,17 +475,16 @@ async_test(function(t) { async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, CSS_ANIM_EVENTS); + var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS); div.style.animation = ANIM_PROPERTY_VAL; var animation = div.getAnimations()[0]; - eventWatcher.waitForEvents(['animationstart', - 'animationend']).then(function() { + eventWatcher.wait_for(['animationstart', + 'animationend']).then(function() { animation.startTime = startTimeForActivePhase(animation.timeline); animation.startTime = startTimeForAfterPhase(animation.timeline); waitForAnimationFrames(2).then(function() { - eventWatcher.stopWatching(); t.done(); }); }); diff --git a/dom/animation/test/css-transitions/test_animation-currenttime.html b/dom/animation/test/css-transitions/test_animation-currenttime.html index e0a106a81611..d50a9af625a3 100644 --- a/dom/animation/test/css-transitions/test_animation-currenttime.html +++ b/dom/animation/test/css-transitions/test_animation-currenttime.html @@ -73,111 +73,6 @@ const TEN_PCT_POSITION = 110; const FIFTY_PCT_POSITION = 150; const END_POSITION = 200; -/** - * CSS animation events fire asynchronously after we set 'startTime'. This - * helper class allows us to handle such events using Promises. - * - * To use this class: - * - * var eventWatcher = new EventWatcher(watchedNode, eventTypes); - * eventWatcher.waitForEvent(eventType).then(function() { - * // Promise fulfilled - * checkStuff(); - * makeSomeChanges(); - * return eventWatcher.waitForEvent(nextEventType); - * }).then(function() { - * // Promise fulfilled - * checkMoreStuff(); - * eventWatcher.stopWatching(); // all done - stop listening for events - * }); - * - * This class will assert_unreached() if an event occurs when there is no - * Promise created by a waitForEvent() call waiting to be fulfilled, or if the - * event is of a different type to the type passed to waitForEvent. This helps - * provide test coverage to ensure that only events that are expected occur, in - * the correct order and with the correct timing. It also helps vastly simplify - * the already complex code below by avoiding lots of gnarly error handling - * code. - */ -function EventWatcher(watchedNode, eventTypes) -{ - if (typeof eventTypes == 'string') { - eventTypes = [eventTypes]; - } - - var waitingFor = null; - - function eventHandler(evt) { - if (!waitingFor) { - assert_unreached('Not expecting event, but got: ' + evt.type + - ' targeting element #' + evt.target.getAttribute('id')); - return; - } - if (evt.type != waitingFor.types[0]) { - assert_unreached('Expected ' + waitingFor.types[0] + ' event but got ' + - evt.type + ' event'); - return; - } - if (waitingFor.types.length > 1) { - // Pop first event from array - waitingFor.types.shift(); - return; - } - // We need to null out waitingFor before calling the resolve function since - // the Promise's resolve handlers may call waitForEvent() which will need - // to set waitingFor. - var resolveFunc = waitingFor.resolve; - waitingFor = null; - resolveFunc(evt); - } - - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.addEventListener(eventTypes[i], eventHandler); - } - - this.waitForEvent = function(type) { - if (typeof type != 'string') { - return Promise.reject('Event type not a string'); - } - return this.waitForEvents([type]); - }; - - /** - * This is useful when two events are expected to fire one immediately after - * the other. This happens when we skip over the entire active interval for - * instance. In this case an 'animationstart' and an 'animationend' are fired - * and due to the asynchronous nature of Promise callbacks this won't work: - * - * eventWatcher.waitForEvent('animationstart').then(function() { - * return waitForEvent('animationend'); - * }).then(...); - * - * It doesn't work because the 'animationend' listener is added too late, - * because the resolve handler for the first Promise is called asynchronously - * some time after the 'animationstart' event is called, rather than at the - * time the event reaches the watched element. - */ - this.waitForEvents = function(types) { - if (waitingFor) { - return Promise.reject('Already waiting for an event'); - } - return new Promise(function(resolve, reject) { - waitingFor = { - types: types, - resolve: resolve, - reject: reject - }; - }); - }; - - this.stopWatching = function() { - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.removeEventListener(eventTypes[i], eventHandler); - } - }; - - return this; -} // The terms used for the naming of the following helper functions refer to // terms used in the Web Animations specification for specific phases of an @@ -300,7 +195,7 @@ test(function(t) async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, 'transitionend'); + var eventWatcher = new EventWatcher(t, div, 'transitionend'); flushComputedStyle(div); div.style.marginLeft = '200px'; // initiate transition @@ -317,11 +212,9 @@ async_test(function(t) { checkStateAtFiftyPctOfActiveInterval(animation); animation.currentTime = currentTimeForEndOfActiveInterval(); - return eventWatcher.waitForEvent('transitionend'); + return eventWatcher.wait_for('transitionend'); })).then(t.step_func(function() { checkStateAtActiveIntervalEndTime(animation); - - eventWatcher.stopWatching(); })).catch(t.step_func(function(reason) { assert_unreached(reason); })).then(function() { @@ -332,7 +225,7 @@ async_test(function(t) { test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, 'transitionend'); + var eventWatcher = new EventWatcher(t, div, 'transitionend'); flushComputedStyle(div); div.style.marginLeft = '200px'; // initiate transition @@ -356,10 +249,9 @@ test(function(t) { // // Calling checkStateAtActiveIntervalStartTime will check computed style, // causing computed style to be updated and the 'transitionend' event to - // be dispatched synchronously. We need to call waitForEvent first + // be dispatched synchronously. We need to call wait_for first // otherwise eventWatcher will assert that the event was unexpected. - eventWatcher.waitForEvent('transitionend').then(function() { - eventWatcher.stopWatching(); + eventWatcher.wait_for('transitionend').then(function() { t.done(); }); checkStateAtActiveIntervalStartTime(animation); diff --git a/dom/animation/test/css-transitions/test_animation-starttime.html b/dom/animation/test/css-transitions/test_animation-starttime.html index 8cf77bdfb842..db99d43b53df 100644 --- a/dom/animation/test/css-transitions/test_animation-starttime.html +++ b/dom/animation/test/css-transitions/test_animation-starttime.html @@ -73,112 +73,6 @@ const TEN_PCT_POSITION = 110; const FIFTY_PCT_POSITION = 150; const END_POSITION = 200; -/** - * CSS animation events fire asynchronously after we set 'startTime'. This - * helper class allows us to handle such events using Promises. - * - * To use this class: - * - * var eventWatcher = new EventWatcher(watchedNode, eventTypes); - * eventWatcher.waitForEvent(eventType).then(function() { - * // Promise fulfilled - * checkStuff(); - * makeSomeChanges(); - * return eventWatcher.waitForEvent(nextEventType); - * }).then(function() { - * // Promise fulfilled - * checkMoreStuff(); - * eventWatcher.stopWatching(); // all done - stop listening for events - * }); - * - * This class will assert_unreached() if an event occurs when there is no - * Promise created by a waitForEvent() call waiting to be fulfilled, or if the - * event is of a different type to the type passed to waitForEvent. This helps - * provide test coverage to ensure that only events that are expected occur, in - * the correct order and with the correct timing. It also helps vastly simplify - * the already complex code below by avoiding lots of gnarly error handling - * code. - */ -function EventWatcher(watchedNode, eventTypes) -{ - if (typeof eventTypes == 'string') { - eventTypes = [eventTypes]; - } - - var waitingFor = null; - - function eventHandler(evt) { - if (!waitingFor) { - assert_unreached('Not expecting event, but got: ' + evt.type + - ' targeting element #' + evt.target.getAttribute('id')); - return; - } - if (evt.type != waitingFor.types[0]) { - assert_unreached('Expected ' + waitingFor.types[0] + ' event but got ' + - evt.type + ' event'); - return; - } - if (waitingFor.types.length > 1) { - // Pop first event from array - waitingFor.types.shift(); - return; - } - // We need to null out waitingFor before calling the resolve function since - // the Promise's resolve handlers may call waitForEvent() which will need - // to set waitingFor. - var resolveFunc = waitingFor.resolve; - waitingFor = null; - resolveFunc(evt); - } - - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.addEventListener(eventTypes[i], eventHandler); - } - - this.waitForEvent = function(type) { - if (typeof type != 'string') { - return Promise.reject('Event type not a string'); - } - return this.waitForEvents([type]); - }; - - /** - * This is useful when two events are expected to fire one immediately after - * the other. This happens when we skip over the entire active interval for - * instance. In this case an 'animationstart' and an 'animationend' are fired - * and due to the asynchronous nature of Promise callbacks this won't work: - * - * eventWatcher.waitForEvent('animationstart').then(function() { - * return waitForEvent('animationend'); - * }).then(...); - * - * It doesn't work because the 'animationend' listener is added too late, - * because the resolve handler for the first Promise is called asynchronously - * some time after the 'animationstart' event is called, rather than at the - * time the event reaches the watched element. - */ - this.waitForEvents = function(types) { - if (waitingFor) { - return Promise.reject('Already waiting for an event'); - } - return new Promise(function(resolve, reject) { - waitingFor = { - types: types, - resolve: resolve, - reject: reject - }; - }); - }; - - this.stopWatching = function() { - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.removeEventListener(eventTypes[i], eventHandler); - } - }; - - return this; -} - // The terms used for the naming of the following helper functions refer to // terms used in the Web Animations specification for specific phases of an // animation. The terms can be found here: @@ -277,7 +171,7 @@ test(function(t) async_test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, 'transitionend'); + var eventWatcher = new EventWatcher(t, div, 'transitionend'); flushComputedStyle(div); div.style.marginLeft = '200px'; // initiate transition @@ -295,11 +189,9 @@ async_test(function(t) { checkStateAtFiftyPctOfActiveInterval(animation); animation.startTime = startTimeForEndOfActiveInterval(animation.timeline); - return eventWatcher.waitForEvent('transitionend'); + return eventWatcher.wait_for('transitionend'); })).then(t.step_func(function() { checkStateAtActiveIntervalEndTime(animation); - - eventWatcher.stopWatching(); })).catch(t.step_func(function(reason) { assert_unreached(reason); })).then(function() { @@ -310,7 +202,7 @@ async_test(function(t) { test(function(t) { var div = addDiv(t, {'class': 'animated-div'}); - var eventWatcher = new EventWatcher(div, 'transitionend'); + var eventWatcher = new EventWatcher(t, div, 'transitionend'); flushComputedStyle(div); div.style.marginLeft = '200px'; // initiate transition @@ -336,8 +228,7 @@ test(function(t) { // causing computed style to be updated and the 'transitionend' event to // be dispatched synchronously. We need to call waitForEvent first // otherwise eventWatcher will assert that the event was unexpected. - eventWatcher.waitForEvent('transitionend').then(function() { - eventWatcher.stopWatching(); + eventWatcher.wait_for('transitionend').then(function() { t.done(); }); checkStateAtActiveIntervalStartTime(animation); From 8ff667521d4cfb9d1c282885390d50dd1311dd2a Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 21 Apr 2015 15:09:48 -0500 Subject: [PATCH 021/241] Backout 3c3337ed60a1 (bug 1139306) for causing bug 1156918. --- b2g/chrome/content/content.css | 11 ++++-- .../linux/devtools/floating-scrollbars.css | 4 +- .../osx/devtools/floating-scrollbars.css | 4 +- .../windows/devtools/floating-scrollbars.css | 4 +- layout/generic/nsGfxScrollFrame.cpp | 39 ++++++++----------- layout/generic/nsGfxScrollFrame.h | 3 +- layout/xul/nsScrollbarFrame.cpp | 24 +++++------- layout/xul/nsScrollbarFrame.h | 4 +- mobile/android/themes/core/content.css | 5 +++ 9 files changed, 43 insertions(+), 55 deletions(-) diff --git a/b2g/chrome/content/content.css b/b2g/chrome/content/content.css index 4e86898f0a9b..64777cff7ef9 100644 --- a/b2g/chrome/content/content.css +++ b/b2g/chrome/content/content.css @@ -30,14 +30,19 @@ html xul|scrollbar { pointer-events: none; } -/* Scrollbar code will reset the margin to the correct side depending on - layout.scrollbar.side pref */ xul|scrollbar[orient="vertical"] { - margin-left: -8px; + -moz-margin-start: -8px; min-width: 8px; max-width: 8px; } +/* workaround for bug 1119057: as -moz-margin-start may not work as expected, + * force a right margin value in RTL mode. */ +[dir="rtl"] xul|scrollbar[root="true"][orient="vertical"] { + -moz-margin-start: unset; + margin-right: -8px; +} + xul|scrollbar[orient="vertical"] xul|thumb { max-width: 6px !important; min-width: 6px !important; diff --git a/browser/themes/linux/devtools/floating-scrollbars.css b/browser/themes/linux/devtools/floating-scrollbars.css index a49ba02bf90e..ff70d646f367 100644 --- a/browser/themes/linux/devtools/floating-scrollbars.css +++ b/browser/themes/linux/devtools/floating-scrollbars.css @@ -9,10 +9,8 @@ scrollbar { padding: 2px; } -/* Scrollbar code will reset the margin to the correct side depending on - layout.scrollbar.side pref */ scrollbar[orient="vertical"] { - margin-left: -10px; + -moz-margin-start: -10px; min-width: 10px; max-width: 10px; } diff --git a/browser/themes/osx/devtools/floating-scrollbars.css b/browser/themes/osx/devtools/floating-scrollbars.css index a3d3061cff70..3cd2fda2f8d3 100644 --- a/browser/themes/osx/devtools/floating-scrollbars.css +++ b/browser/themes/osx/devtools/floating-scrollbars.css @@ -10,10 +10,8 @@ scrollbar { padding: 2px; } -/* Scrollbar code will reset the margin to the correct side depending on - layout.scrollbar.side pref */ scrollbar[orient="vertical"] { - margin-left: -8px; + -moz-margin-start: -8px; min-width: 8px; max-width: 8px; } diff --git a/browser/themes/windows/devtools/floating-scrollbars.css b/browser/themes/windows/devtools/floating-scrollbars.css index a49ba02bf90e..ff70d646f367 100644 --- a/browser/themes/windows/devtools/floating-scrollbars.css +++ b/browser/themes/windows/devtools/floating-scrollbars.css @@ -9,10 +9,8 @@ scrollbar { padding: 2px; } -/* Scrollbar code will reset the margin to the correct side depending on - layout.scrollbar.side pref */ scrollbar[orient="vertical"] { - margin-left: -10px; + -moz-margin-start: -10px; min-width: 10px; max-width: 10px; } diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 39394aee5405..79f33870aeb5 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -395,7 +395,7 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowState* aState, aState->mShowVScrollbar = aAssumeVScroll; nsPoint scrollPortOrigin(aState->mComputedBorder.left, aState->mComputedBorder.top); - if (mHelper.GetScrollbarSide() == ScrollFrameHelper::eScrollbarOnLeft) { + if (!mHelper.IsScrollbarOnRight()) { scrollPortOrigin.x += vScrollbarActualWidth; } mHelper.mScrollPort = nsRect(scrollPortOrigin, scrollPortSize); @@ -1009,7 +1009,7 @@ ScrollFrameHelper::GetDesiredScrollbarSizes(nsBoxLayoutState* aState) if (mVScrollbarBox) { nsSize size = mVScrollbarBox->GetPrefSize(*aState); nsBox::AddMargin(mVScrollbarBox, size); - if (GetScrollbarSide() == eScrollbarOnRight) + if (IsScrollbarOnRight()) result.left = size.width; else result.right = size.width; @@ -3766,7 +3766,7 @@ ScrollFrameHelper::CreateAnonymousContent( nsAutoString dir; switch (resizeStyle) { case NS_STYLE_RESIZE_HORIZONTAL: - if (GetScrollbarSide() == eScrollbarOnRight) { + if (IsScrollbarOnRight()) { dir.AssignLiteral("right"); } else { @@ -4213,8 +4213,8 @@ ScrollFrameHelper::IsLTR() const return wm.IsVertical() ? wm.IsVerticalLR() : wm.IsBidiLTR(); } -ScrollFrameHelper::eScrollbarSide -ScrollFrameHelper::GetScrollbarSide() const +bool +ScrollFrameHelper::IsScrollbarOnRight() const { nsPresContext *presContext = mOuter->PresContext(); @@ -4222,19 +4222,18 @@ ScrollFrameHelper::GetScrollbarSide() const // layout.scrollbar.side. For non-top-level elements, it depends only on the // directionaliy of the element (equivalent to a value of "1" for the pref). if (!mIsRoot) - return IsLTR() ? eScrollbarOnRight : eScrollbarOnLeft; + return IsLTR(); switch (presContext->GetCachedIntPref(kPresContext_ScrollbarSide)) { default: case 0: // UI directionality - return (presContext->GetCachedIntPref(kPresContext_BidiDirection) - == IBMBIDI_TEXTDIRECTION_LTR) - ? eScrollbarOnRight : eScrollbarOnLeft; + return presContext->GetCachedIntPref(kPresContext_BidiDirection) + == IBMBIDI_TEXTDIRECTION_LTR; case 1: // Document / content directionality - return IsLTR() ? eScrollbarOnRight : eScrollbarOnLeft; + return IsLTR(); case 2: // Always right - return eScrollbarOnRight; + return true; case 3: // Always left - return eScrollbarOnLeft; + return false; } } @@ -4272,8 +4271,7 @@ ScrollFrameHelper::IsScrollingActive(nsDisplayListBuilder* aBuilder) const nsresult nsXULScrollFrame::Layout(nsBoxLayoutState& aState) { - bool scrollbarRight = - (mHelper.GetScrollbarSide() == ScrollFrameHelper::eScrollbarOnRight); + bool scrollbarRight = mHelper.IsScrollbarOnRight(); bool scrollbarBottom = true; // get the content rect @@ -4740,7 +4738,7 @@ ScrollFrameHelper::LayoutScrollbars(nsBoxLayoutState& aState, "This should have been suppressed"); bool hasResizer = HasResizer(); - bool scrollbarOnLeft = (GetScrollbarSide() == eScrollbarOnLeft); + bool scrollbarOnLeft = !IsScrollbarOnRight(); // place the scrollcorner if (mScrollCornerBox || mResizerBox) { @@ -4806,14 +4804,9 @@ ScrollFrameHelper::LayoutScrollbars(nsBoxLayoutState& aState, vRect.width = aContentArea.width - mScrollPort.width; vRect.x = scrollbarOnLeft ? aContentArea.x : mScrollPort.XMost(); if (mHasVerticalScrollbar) { - nsScrollbarFrame* scrollbar = do_QueryFrame(mVScrollbarBox); - NS_ASSERTION(scrollbar, "Frame must be a scrollbar"); - - if (scrollbar) { - nsMargin margin; - scrollbar->GetScrollbarMargin(margin, GetScrollbarSide()); - vRect.Deflate(margin); - } + nsMargin margin; + mVScrollbarBox->GetMargin(margin); + vRect.Deflate(margin); } AdjustScrollbarRectForResizer(mOuter, presContext, vRect, hasResizer, true); } diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 05aa84aa9889..a0cc47d6f099 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -307,8 +307,7 @@ public: nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); nscoord GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState); bool IsLTR() const; - enum eScrollbarSide { eScrollbarOnLeft, eScrollbarOnRight }; - eScrollbarSide GetScrollbarSide() const; + bool IsScrollbarOnRight() const; bool IsScrollingActive(nsDisplayListBuilder* aBuilder) const; bool IsMaybeScrollingActive() const; bool IsProcessingAsyncScroll() const { diff --git a/layout/xul/nsScrollbarFrame.cpp b/layout/xul/nsScrollbarFrame.cpp index 32acbf4cdbfb..70c7c01ee5d1 100644 --- a/layout/xul/nsScrollbarFrame.cpp +++ b/layout/xul/nsScrollbarFrame.cpp @@ -167,11 +167,8 @@ nsScrollbarFrame::GetScrollbarMediator() } nsresult -nsScrollbarFrame::GetScrollbarMargin( - nsMargin& aMargin, - mozilla::ScrollFrameHelper::eScrollbarSide aSide) +nsScrollbarFrame::GetMargin(nsMargin& aMargin) { - nsresult rv = NS_ERROR_FAILURE; aMargin.SizeTo(0,0,0,0); if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) { @@ -186,21 +183,18 @@ nsScrollbarFrame::GetScrollbarMargin( aMargin.top = -presContext->DevPixelsToAppUnits(size.height); } else { - aMargin.left = -presContext->DevPixelsToAppUnits(size.width); + if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { + aMargin.right = -presContext->DevPixelsToAppUnits(size.width); + } + else { + aMargin.left = -presContext->DevPixelsToAppUnits(size.width); + } } - rv = NS_OK; + return NS_OK; } } - if (NS_FAILED(rv)) { - rv = nsBox::GetMargin(aMargin); - } - - if (NS_SUCCEEDED(rv) && aSide == ScrollFrameHelper::eScrollbarOnLeft) { - Swap(aMargin.left, aMargin.right); - } - - return rv; + return nsBox::GetMargin(aMargin); } void diff --git a/layout/xul/nsScrollbarFrame.h b/layout/xul/nsScrollbarFrame.h index 357b3c681738..098167cbb42b 100644 --- a/layout/xul/nsScrollbarFrame.h +++ b/layout/xul/nsScrollbarFrame.h @@ -12,7 +12,6 @@ #include "mozilla/Attributes.h" #include "nsBoxFrame.h" -#include "nsGfxScrollFrame.h" class nsIScrollbarMediator; @@ -82,8 +81,7 @@ public: */ virtual bool DoesClipChildren() override { return true; } - nsresult GetScrollbarMargin(nsMargin& aMargin, - mozilla::ScrollFrameHelper::eScrollbarSide aSide); + virtual nsresult GetMargin(nsMargin& aMargin) override; /** * The following three methods set the value of mIncrement when a diff --git a/mobile/android/themes/core/content.css b/mobile/android/themes/core/content.css index 64d0c442abad..89ab922a11f3 100644 --- a/mobile/android/themes/core/content.css +++ b/mobile/android/themes/core/content.css @@ -33,6 +33,11 @@ xul|window xul|scrollbar[orient="vertical"] { border: 0px solid transparent !important; } +xul|window xul|scrollbar[orient="vertical"]:-moz-locale-dir(rtl) { + margin-left: 2px; + margin-right: -10px; +} + xul|window xul|scrollbar[orient="vertical"] xul|thumb { max-width: 6px !important; min-width: 6px !important; From 499947932e35921580ec54d8af58114c97acc531 Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Tue, 21 Apr 2015 16:20:56 -0400 Subject: [PATCH 022/241] no bug - change mdn link in comment to be https. r=comment-only DONTBUILD --- build/pgo/server-locations.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pgo/server-locations.txt b/build/pgo/server-locations.txt index b39966142bc2..e1d214592694 100644 --- a/build/pgo/server-locations.txt +++ b/build/pgo/server-locations.txt @@ -8,7 +8,7 @@ # It is referred to by the following page, so if this file moves, that page must # be modified accordingly: # -# http://developer.mozilla.org/en/docs/Mochitest#How_do_I_test_issues_which_only_show_up_when_tests_are_run_across_domains.3F +# https://developer.mozilla.org/en/docs/Mochitest#How_do_I_test_issues_which_only_show_up_when_tests_are_run_across_domains.3F # # Empty lines and lines which begin with "#" are ignored and may be used for # storing comments. All other lines consist of an origin followed by whitespace From 3f4737e49a0c9542b46b521114f98588fd0a9514 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sun, 19 Apr 2015 13:22:35 -0400 Subject: [PATCH 023/241] Bug 1156084 - Disallow AddRef() and Release() calls on the return value of methods returning XPCOM objects; r=jrmuizel When a method returns type D derived from RefCounted type B, there is an ImplicitCastExpr (or an ExplicitCastExpr, if there is an explicit cast to the base type in the code) in the AST between the CallExpr and MemberExpr, which we didn't take into account before. This caused the analysis to not work on common patterns such as nsCOMPtr. --- build/clang-plugin/clang-plugin.cpp | 8 ++++ .../tests/TestNoAddRefReleaseOnReturn.cpp | 45 +++++++++++++++++++ dom/ipc/TabParent.cpp | 7 +-- dom/media/gmp/GMPService.cpp | 4 +- gfx/2d/DrawTargetCG.cpp | 2 +- netwerk/protocol/ftp/FTPChannelParent.cpp | 4 +- netwerk/protocol/http/HttpChannelParent.cpp | 4 +- .../websocket/WebSocketChannelParent.cpp | 4 +- .../protocol/wyciwyg/WyciwygChannelParent.cpp | 4 +- 9 files changed, 68 insertions(+), 14 deletions(-) diff --git a/build/clang-plugin/clang-plugin.cpp b/build/clang-plugin/clang-plugin.cpp index 0999789d44ec..218f8dcbaee1 100644 --- a/build/clang-plugin/clang-plugin.cpp +++ b/build/clang-plugin/clang-plugin.cpp @@ -639,11 +639,19 @@ DiagnosticsMatcher::DiagnosticsMatcher() )).bind("node"), &nanExprChecker); + // First, look for direct parents of the MemberExpr. astMatcher.addMatcher(callExpr(callee(functionDecl(hasNoAddRefReleaseOnReturnAttr()).bind("func")), hasParent(memberExpr(isAddRefOrRelease(), hasParent(callExpr())).bind("member") )).bind("node"), &noAddRefReleaseOnReturnChecker); + // Then, look for MemberExpr that need to be casted to the right type using + // an intermediary CastExpr before we get to the CallExpr. + astMatcher.addMatcher(callExpr(callee(functionDecl(hasNoAddRefReleaseOnReturnAttr()).bind("func")), + hasParent(castExpr(hasParent(memberExpr(isAddRefOrRelease(), + hasParent(callExpr())).bind("member")))) + ).bind("node"), + &noAddRefReleaseOnReturnChecker); astMatcher.addMatcher(lambdaExpr( hasDescendant(declRefExpr(hasType(pointerType(pointee(isRefCounted())))).bind("node")) diff --git a/build/clang-plugin/tests/TestNoAddRefReleaseOnReturn.cpp b/build/clang-plugin/tests/TestNoAddRefReleaseOnReturn.cpp index 8283a72583ee..2e1f83377e50 100644 --- a/build/clang-plugin/tests/TestNoAddRefReleaseOnReturn.cpp +++ b/build/clang-plugin/tests/TestNoAddRefReleaseOnReturn.cpp @@ -6,12 +6,20 @@ struct Test { void foo(); }; +struct TestD : Test {}; + struct S { Test* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN; Test& g() MOZ_NO_ADDREF_RELEASE_ON_RETURN; Test h() MOZ_NO_ADDREF_RELEASE_ON_RETURN; }; +struct SD { + TestD* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN; + TestD& g() MOZ_NO_ADDREF_RELEASE_ON_RETURN; + TestD h() MOZ_NO_ADDREF_RELEASE_ON_RETURN; +}; + template struct X { T* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN; @@ -28,6 +36,10 @@ Test* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN; Test& g() MOZ_NO_ADDREF_RELEASE_ON_RETURN; Test h() MOZ_NO_ADDREF_RELEASE_ON_RETURN; +TestD* fd() MOZ_NO_ADDREF_RELEASE_ON_RETURN; +TestD& gd() MOZ_NO_ADDREF_RELEASE_ON_RETURN; +TestD hd() MOZ_NO_ADDREF_RELEASE_ON_RETURN; + void test() { S s; s.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}} @@ -39,6 +51,16 @@ void test() { s.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}} s.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}} s.h().foo(); + SD sd; + sd.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}} + sd.f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}} + sd.f()->foo(); + sd.g().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'g'}} + sd.g().Release(); // expected-error{{'Release' cannot be called on the return value of 'g'}} + sd.g().foo(); + sd.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}} + sd.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}} + sd.h().foo(); X x; x.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}} x.f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}} @@ -49,10 +71,24 @@ void test() { x.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}} x.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}} x.h().foo(); + X xd; + xd.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}} + xd.f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}} + xd.f()->foo(); + xd.g().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'g'}} + xd.g().Release(); // expected-error{{'Release' cannot be called on the return value of 'g'}} + xd.g().foo(); + xd.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}} + xd.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}} + xd.h().foo(); SP sp; sp->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'operator->'}} sp->Release(); // expected-error{{'Release' cannot be called on the return value of 'operator->'}} sp->foo(); + SP spd; + spd->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'operator->'}} + spd->Release(); // expected-error{{'Release' cannot be called on the return value of 'operator->'}} + spd->foo(); f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}} f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}} f()->foo(); @@ -62,4 +98,13 @@ void test() { h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}} h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}} h().foo(); + fd()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'fd'}} + fd()->Release(); // expected-error{{'Release' cannot be called on the return value of 'fd'}} + fd()->foo(); + gd().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'gd'}} + gd().Release(); // expected-error{{'Release' cannot be called on the return value of 'gd'}} + gd().foo(); + hd().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'hd'}} + hd().Release(); // expected-error{{'Release' cannot be called on the return value of 'hd'}} + hd().foo(); } diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index d927bb2a7462..466baa8a44da 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -3062,15 +3062,16 @@ public: NS_IMETHOD SetOriginalURI(nsIURI*) NO_IMPL NS_IMETHOD GetURI(nsIURI** aUri) override { - NS_IF_ADDREF(mUri); - *aUri = mUri; + nsCOMPtr copy = mUri; + copy.forget(aUri); return NS_OK; } NS_IMETHOD GetOwner(nsISupports**) NO_IMPL NS_IMETHOD SetOwner(nsISupports*) NO_IMPL NS_IMETHOD GetLoadInfo(nsILoadInfo** aLoadInfo) override { - NS_IF_ADDREF(*aLoadInfo = mLoadInfo); + nsCOMPtr copy = mLoadInfo; + copy.forget(aLoadInfo); return NS_OK; } NS_IMETHOD SetLoadInfo(nsILoadInfo* aLoadInfo) override diff --git a/dom/media/gmp/GMPService.cpp b/dom/media/gmp/GMPService.cpp index 74b1c768caf1..4d3af96b6bbb 100644 --- a/dom/media/gmp/GMPService.cpp +++ b/dom/media/gmp/GMPService.cpp @@ -283,8 +283,8 @@ GeckoMediaPluginService::GetThread(nsIThread** aThread) InitializePlugins(); } - NS_ADDREF(mGMPThread); - *aThread = mGMPThread; + nsCOMPtr copy = mGMPThread; + copy.forget(aThread); return NS_OK; } diff --git a/gfx/2d/DrawTargetCG.cpp b/gfx/2d/DrawTargetCG.cpp index 246ee4982f58..70c941594968 100644 --- a/gfx/2d/DrawTargetCG.cpp +++ b/gfx/2d/DrawTargetCG.cpp @@ -251,7 +251,7 @@ GetRetainedImageFromSourceSurface(SourceSurface *aSurface) if (!data) { MOZ_CRASH("unsupported source surface"); } - data->AddRef(); + data.get()->AddRef(); return CreateCGImage(releaseDataSurface, data.get(), data->GetData(), data->GetSize(), data->Stride(), data->GetFormat()); diff --git a/netwerk/protocol/ftp/FTPChannelParent.cpp b/netwerk/protocol/ftp/FTPChannelParent.cpp index d7c4c00e4f43..2a2bea67bf3f 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.cpp +++ b/netwerk/protocol/ftp/FTPChannelParent.cpp @@ -465,8 +465,8 @@ FTPChannelParent::GetInterface(const nsIID& uuid, void** result) { // Only support nsILoadContext if child channel's callbacks did too if (uuid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) { - NS_ADDREF(mLoadContext); - *result = static_cast(mLoadContext); + nsCOMPtr copy = mLoadContext; + copy.forget(result); return NS_OK; } diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 7e4dcbbbee45..8ce483145bb9 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -223,8 +223,8 @@ HttpChannelParent::GetInterface(const nsIID& aIID, void **result) // Only support nsILoadContext if child channel's callbacks did too if (aIID.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) { - NS_ADDREF(mLoadContext); - *result = static_cast(mLoadContext); + nsCOMPtr copy = mLoadContext; + copy.forget(result); return NS_OK; } diff --git a/netwerk/protocol/websocket/WebSocketChannelParent.cpp b/netwerk/protocol/websocket/WebSocketChannelParent.cpp index 2c92b8221478..af1520934589 100644 --- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp +++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp @@ -306,8 +306,8 @@ WebSocketChannelParent::GetInterface(const nsIID & iid, void **result) // Only support nsILoadContext if child channel's callbacks did too if (iid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) { - NS_ADDREF(mLoadContext); - *result = static_cast(mLoadContext); + nsCOMPtr copy = mLoadContext; + copy.forget(result); return NS_OK; } diff --git a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp index 9f0b4f6bc2eb..6096acc6d616 100644 --- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp +++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp @@ -343,8 +343,8 @@ WyciwygChannelParent::GetInterface(const nsIID& uuid, void** result) { // Only support nsILoadContext if child channel's callbacks did too if (uuid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) { - NS_ADDREF(mLoadContext); - *result = static_cast(mLoadContext); + nsCOMPtr copy = mLoadContext; + copy.forget(result); return NS_OK; } From 3d21a0590450d1ca9a119bcb019cfaf317704c90 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 10 Apr 2015 23:05:46 -0400 Subject: [PATCH 024/241] Bug 1153348 - Add an analysis to prohibit operator bools which aren't marked as either explicit or MOZ_IMPLICIT; r=jrmuizel This is the counterpart to the existing analysis to catch constructors which aren't marked as either explicit or MOZ_IMPLICIT. --- build/clang-plugin/clang-plugin.cpp | 105 +++++++++++++++--- .../tests/TestExplicitOperatorBool.cpp | 11 ++ build/clang-plugin/tests/moz.build | 1 + dom/bindings/CallbackObject.h | 2 +- dom/html/HTMLMediaElement.h | 2 +- dom/media/SelfRef.h | 2 +- dom/plugins/base/nsNPAPIPluginInstance.cpp | 2 +- dom/plugins/ipc/PluginScriptableObjectUtils.h | 2 +- hal/linux/udev.h | 2 +- memory/replace/logalloc/replay/Replay.cpp | 2 +- mfbt/Atomics.h | 2 +- netwerk/base/AutoClose.h | 2 +- netwerk/socket/nsSOCKSIOLayer.cpp | 2 +- xpcom/build/FileLocation.h | 4 +- xpcom/glue/nsTArray.h | 2 +- 15 files changed, 116 insertions(+), 27 deletions(-) create mode 100644 build/clang-plugin/tests/TestExplicitOperatorBool.cpp diff --git a/build/clang-plugin/clang-plugin.cpp b/build/clang-plugin/clang-plugin.cpp index 218f8dcbaee1..210c6d0cf68e 100644 --- a/build/clang-plugin/clang-plugin.cpp +++ b/build/clang-plugin/clang-plugin.cpp @@ -84,6 +84,11 @@ private: virtual void run(const MatchFinder::MatchResult &Result); }; + class ExplicitOperatorBoolChecker : public MatchFinder::MatchCallback { + public: + virtual void run(const MatchFinder::MatchResult &Result); + }; + ScopeChecker stackClassChecker; ScopeChecker globalClassChecker; NonHeapClassChecker nonheapClassChecker; @@ -92,16 +97,17 @@ private: NaNExprChecker nanExprChecker; NoAddRefReleaseOnReturnChecker noAddRefReleaseOnReturnChecker; RefCountedInsideLambdaChecker refCountedInsideLambdaChecker; + ExplicitOperatorBoolChecker explicitOperatorBoolChecker; MatchFinder astMatcher; }; namespace { -bool isInIgnoredNamespace(const Decl *decl) { +std::string getDeclarationNamespace(const Decl *decl) { const DeclContext *DC = decl->getDeclContext()->getEnclosingNamespaceContext(); const NamespaceDecl *ND = dyn_cast(DC); if (!ND) { - return false; + return ""; } while (const DeclContext *ParentDC = ND->getParent()) { @@ -112,8 +118,15 @@ bool isInIgnoredNamespace(const Decl *decl) { } const auto& name = ND->getName(); + return name; +} + +bool isInIgnoredNamespaceForImplicitCtor(const Decl *decl) { + std::string name = getDeclarationNamespace(decl); + if (name == "") { + return false; + } - // namespace std and icu are ignored for now return name == "std" || // standard C++ lib name == "__gnu_cxx" || // gnu C++ lib name == "boost" || // boost @@ -129,7 +142,19 @@ bool isInIgnoredNamespace(const Decl *decl) { name == "testing"; // gtest } -bool isIgnoredPath(const Decl *decl) { +bool isInIgnoredNamespaceForImplicitConversion(const Decl *decl) { + std::string name = getDeclarationNamespace(decl); + if (name == "") { + return false; + } + + return name == "std" || // standard C++ lib + name == "__gnu_cxx" || // gnu C++ lib + name == "google_breakpad" || // breakpad + name == "testing"; // gtest +} + +bool isIgnoredPathForImplicitCtor(const Decl *decl) { decl = decl->getCanonicalDecl(); SourceLocation Loc = decl->getLocation(); const SourceManager &SM = decl->getASTContext().getSourceManager(); @@ -150,9 +175,30 @@ bool isIgnoredPath(const Decl *decl) { return false; } -bool isInterestingDecl(const Decl *decl) { - return !isInIgnoredNamespace(decl) && - !isIgnoredPath(decl); +bool isIgnoredPathForImplicitConversion(const Decl *decl) { + decl = decl->getCanonicalDecl(); + SourceLocation Loc = decl->getLocation(); + const SourceManager &SM = decl->getASTContext().getSourceManager(); + SmallString<1024> FileName = SM.getFilename(Loc); + llvm::sys::fs::make_absolute(FileName); + llvm::sys::path::reverse_iterator begin = llvm::sys::path::rbegin(FileName), + end = llvm::sys::path::rend(FileName); + for (; begin != end; ++begin) { + if (begin->compare_lower(StringRef("graphite2")) == 0) { + return true; + } + } + return false; +} + +bool isInterestingDeclForImplicitCtor(const Decl *decl) { + return !isInIgnoredNamespaceForImplicitCtor(decl) && + !isIgnoredPathForImplicitCtor(decl); +} + +bool isInterestingDeclForImplicitConversion(const Decl *decl) { + return !isInIgnoredNamespaceForImplicitConversion(decl) && + !isIgnoredPathForImplicitConversion(decl); } } @@ -232,7 +278,7 @@ public: } } - if (!d->isAbstract() && isInterestingDecl(d)) { + if (!d->isAbstract() && isInterestingDeclForImplicitCtor(d)) { for (CXXRecordDecl::ctor_iterator ctor = d->ctor_begin(), e = d->ctor_end(); ctor != e; ++ctor) { // Ignore non-converting ctors @@ -416,6 +462,16 @@ bool isClassRefCounted(QualType T) { return clazz ? isClassRefCounted(clazz) : RegularClass; } +template +bool IsInSystemHeader(const ASTContext &AC, const T &D) { + auto &SourceManager = AC.getSourceManager(); + auto ExpansionLoc = SourceManager.getExpansionLoc(D.getLocStart()); + if (ExpansionLoc.isInvalid()) { + return false; + } + return SourceManager.isInSystemHeader(ExpansionLoc); +} + } namespace clang { @@ -515,12 +571,7 @@ AST_MATCHER(QualType, isFloat) { /// isExpansionInSystemHeader in newer clangs, but modified in order to work /// with old clangs that we use on infra. AST_MATCHER(BinaryOperator, isInSystemHeader) { - auto &SourceManager = Finder->getASTContext().getSourceManager(); - auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart()); - if (ExpansionLoc.isInvalid()) { - return false; - } - return SourceManager.isInSystemHeader(ExpansionLoc); + return IsInSystemHeader(Finder->getASTContext(), Node); } /// This matcher will match locations in SkScalar.h. This header contains a @@ -657,6 +708,13 @@ DiagnosticsMatcher::DiagnosticsMatcher() hasDescendant(declRefExpr(hasType(pointerType(pointee(isRefCounted())))).bind("node")) ), &refCountedInsideLambdaChecker); + + // Older clang versions such as the ones used on the infra recognize these + // conversions as 'operator _Bool', but newer clang versions recognize these + // as 'operator bool'. + astMatcher.addMatcher(methodDecl(anyOf(hasName("operator bool"), + hasName("operator _Bool"))).bind("node"), + &explicitOperatorBoolChecker); } void DiagnosticsMatcher::ScopeChecker::run( @@ -869,6 +927,25 @@ void DiagnosticsMatcher::RefCountedInsideLambdaChecker::run( Diag.Report(node->getLocStart(), noteID); } +void DiagnosticsMatcher::ExplicitOperatorBoolChecker::run( + const MatchFinder::MatchResult &Result) { + DiagnosticsEngine &Diag = Result.Context->getDiagnostics(); + unsigned errorID = Diag.getDiagnosticIDs()->getCustomDiagID( + DiagnosticIDs::Error, "bad implicit conversion operator for %0"); + unsigned noteID = Diag.getDiagnosticIDs()->getCustomDiagID( + DiagnosticIDs::Note, "consider adding the explicit keyword to %0"); + const CXXConversionDecl *method = Result.Nodes.getNodeAs("node"); + const CXXRecordDecl *clazz = method->getParent(); + + if (!method->isExplicitSpecified() && + !MozChecker::hasCustomAnnotation(method, "moz_implicit") && + !IsInSystemHeader(method->getASTContext(), *method) && + isInterestingDeclForImplicitConversion(method)) { + Diag.Report(method->getLocStart(), errorID) << clazz; + Diag.Report(method->getLocStart(), noteID) << "'operator bool'"; + } +} + class MozCheckAction : public PluginASTAction { public: ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI, StringRef fileName) override { diff --git a/build/clang-plugin/tests/TestExplicitOperatorBool.cpp b/build/clang-plugin/tests/TestExplicitOperatorBool.cpp new file mode 100644 index 000000000000..bc4b43a7d06a --- /dev/null +++ b/build/clang-plugin/tests/TestExplicitOperatorBool.cpp @@ -0,0 +1,11 @@ +#define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) + +struct Bad { + operator bool(); // expected-error {{bad implicit conversion operator for 'Bad'}} expected-note {{consider adding the explicit keyword to 'operator bool'}} +}; +struct Good { + explicit operator bool(); +}; +struct Okay { + MOZ_IMPLICIT operator bool(); +}; diff --git a/build/clang-plugin/tests/moz.build b/build/clang-plugin/tests/moz.build index 5a6a26b5034e..0894046e1125 100644 --- a/build/clang-plugin/tests/moz.build +++ b/build/clang-plugin/tests/moz.build @@ -7,6 +7,7 @@ SOURCES += [ 'TestBadImplicitConversionCtor.cpp', 'TestCustomHeap.cpp', + 'TestExplicitOperatorBool.cpp', 'TestGlobalClass.cpp', 'TestMustOverride.cpp', 'TestNANTestingExpr.cpp', diff --git a/dom/bindings/CallbackObject.h b/dom/bindings/CallbackObject.h index 5d8565e9c315..a07279e96bcf 100644 --- a/dom/bindings/CallbackObject.h +++ b/dom/bindings/CallbackObject.h @@ -305,7 +305,7 @@ public: } // Boolean conversion operator so people can use this in boolean tests - operator bool() const + explicit operator bool() const { return GetISupports(); } diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index b5e6a66dd66a..cec21baefa69 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -660,7 +660,7 @@ protected: void SetOuter(HTMLMediaElement* outer) { mOuter = outer; } void SetCanPlay(bool aCanPlay); - operator bool() const { return mValue; } + MOZ_IMPLICIT operator bool() const { return mValue; } WakeLockBoolWrapper& operator=(bool val); diff --git a/dom/media/SelfRef.h b/dom/media/SelfRef.h index 866b6de99531..301d986fa0dc 100644 --- a/dom/media/SelfRef.h +++ b/dom/media/SelfRef.h @@ -35,7 +35,7 @@ public: } } - operator bool() const { return mHeld; } + MOZ_IMPLICIT operator bool() const { return mHeld; } SelfReference(const SelfReference& aOther) = delete; void operator=(const SelfReference& aOther) = delete; diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index 5f601403b16c..efcc353682e5 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -1167,7 +1167,7 @@ public: if (plugin) mLibrary = plugin->GetLibrary(); } - operator bool() { return !!mLibrary; } + explicit operator bool() { return !!mLibrary; } PluginLibrary* operator->() { return mLibrary; } private: diff --git a/dom/plugins/ipc/PluginScriptableObjectUtils.h b/dom/plugins/ipc/PluginScriptableObjectUtils.h index 432c53b7777b..bef2113c79f8 100644 --- a/dom/plugins/ipc/PluginScriptableObjectUtils.h +++ b/dom/plugins/ipc/PluginScriptableObjectUtils.h @@ -277,7 +277,7 @@ public: return mActor; } - operator bool() + explicit operator bool() { return !!mActor; } diff --git a/hal/linux/udev.h b/hal/linux/udev.h index 9f28d95c8274..4c717560c035 100644 --- a/hal/linux/udev.h +++ b/hal/linux/udev.h @@ -63,7 +63,7 @@ class udev_lib { } } - operator bool() { + explicit operator bool() { return udev; } diff --git a/memory/replace/logalloc/replay/Replay.cpp b/memory/replace/logalloc/replay/Replay.cpp index 75db8fb1e769..a047d4152bfb 100644 --- a/memory/replace/logalloc/replay/Replay.cpp +++ b/memory/replace/logalloc/replay/Replay.cpp @@ -176,7 +176,7 @@ public: } /* Returns whether the buffer is empty. */ - operator bool() { return mLength; } + explicit operator bool() { return mLength; } /* Returns the memory location of the buffer. */ const char* get() { return mBuf; } diff --git a/mfbt/Atomics.h b/mfbt/Atomics.h index 0afee7f2df55..33610144eda2 100644 --- a/mfbt/Atomics.h +++ b/mfbt/Atomics.h @@ -742,7 +742,7 @@ public: explicit MOZ_CONSTEXPR Atomic(bool aInit) : Base(aInit) {} // We provide boolean wrappers for the underlying AtomicBase methods. - operator bool() const + MOZ_IMPLICIT operator bool() const { return Base::Intrinsics::load(Base::mValue); } diff --git a/netwerk/base/AutoClose.h b/netwerk/base/AutoClose.h index ba82614f69df..f8521144a9d5 100644 --- a/netwerk/base/AutoClose.h +++ b/netwerk/base/AutoClose.h @@ -23,7 +23,7 @@ public: Close(); } - operator bool() const + explicit operator bool() const { return mPtr; } diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp index 50232f0f5905..d07df13ecf27 100644 --- a/netwerk/socket/nsSOCKSIOLayer.cpp +++ b/netwerk/socket/nsSOCKSIOLayer.cpp @@ -242,7 +242,7 @@ public: return mLength; } - operator bool() { return !!mBuf; } + explicit operator bool() { return !!mBuf; } private: template friend class Buffer; diff --git a/xpcom/build/FileLocation.h b/xpcom/build/FileLocation.h index 967718b0ee64..17f24be6f332 100644 --- a/xpcom/build/FileLocation.h +++ b/xpcom/build/FileLocation.h @@ -90,9 +90,9 @@ public: * or not. */ #if defined(MOZILLA_XPCOMRT_API) - operator bool() const { return mBaseFile; } + explicit operator bool() const { return mBaseFile; } #else - operator bool() const { return mBaseFile || mBaseZip; } + explicit operator bool() const { return mBaseFile || mBaseZip; } #endif // defined(MOZILLA_XPCOMRT_API) /** diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index c7f56614a8e9..9d654d54bcbc 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -112,7 +112,7 @@ struct nsTArrayFallibleResult // Note: allows implicit conversions from and to bool MOZ_IMPLICIT nsTArrayFallibleResult(bool aResult) : mResult(aResult) {} - operator bool() { return mResult; } + MOZ_IMPLICIT operator bool() { return mResult; } private: bool mResult; From f18bd05cf5c70d8a02a5665c72564894d4419060 Mon Sep 17 00:00:00 2001 From: Ross Ziegler Date: Tue, 21 Apr 2015 17:06:18 -0400 Subject: [PATCH 025/241] Bug 1152454 - Made liveregions responsive to name/value change events. r=yzen --- accessible/jsat/EventManager.jsm | 12 ++++++++++++ accessible/jsat/Presentation.jsm | 10 ++++++---- .../tests/mochitest/jsat/doc_content_integration.html | 15 +++++++++++++++ accessible/tests/mochitest/jsat/jsatcommon.js | 2 +- .../tests/mochitest/jsat/test_content_integration.html | 16 +++++++++++++--- 5 files changed, 47 insertions(+), 8 deletions(-) --- accessible/jsat/EventManager.jsm | 12 ++++++++++++ accessible/jsat/Presentation.jsm | 10 ++++++---- .../mochitest/jsat/doc_content_integration.html | 15 +++++++++++++++ accessible/tests/mochitest/jsat/jsatcommon.js | 2 +- .../mochitest/jsat/test_content_integration.html | 16 +++++++++++++--- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm index 1c8c8d849f1e..71fad7a658a9 100644 --- a/accessible/jsat/EventManager.jsm +++ b/accessible/jsat/EventManager.jsm @@ -191,6 +191,12 @@ this.EventManager.prototype = { let acc = aEvent.accessible; if (acc === this.contentControl.vc.position) { this.present(Presentation.nameChanged(acc)); + } else { + let {liveRegion, isPolite} = this._handleLiveRegion(aEvent, + ['text', 'all']); + if (liveRegion) { + this.present(Presentation.nameChanged(acc, isPolite)); + } } break; } @@ -293,6 +299,12 @@ this.EventManager.prototype = { if (position === target || Utils.getEmbeddedControl(position) === target) { this.present(Presentation.valueChanged(target)); + } else { + let {liveRegion, isPolite} = this._handleLiveRegion(aEvent, + ['text', 'all']); + if (liveRegion) { + this.present(Presentation.valueChanged(target, isPolite)); + } } } } diff --git a/accessible/jsat/Presentation.jsm b/accessible/jsat/Presentation.jsm index 0d331f845495..eea6f6690c07 100644 --- a/accessible/jsat/Presentation.jsm +++ b/accessible/jsat/Presentation.jsm @@ -523,18 +523,19 @@ B2GPresenter.prototype.pivotChanged = }; B2GPresenter.prototype.nameChanged = - function B2GPresenter_nameChanged(aAccessible) { + function B2GPresenter_nameChanged(aAccessible, aIsPolite = true) { return { type: this.type, details: { eventType: 'name-change', - data: aAccessible.name + data: aAccessible.name, + options: {enqueue: aIsPolite} } }; }; B2GPresenter.prototype.valueChanged = - function B2GPresenter_valueChanged(aAccessible) { + function B2GPresenter_valueChanged(aAccessible, aIsPolite = true) { // the editable value changes are handled in the text changed presenter if (Utils.getState(aAccessible).contains(States.EDITABLE)) { @@ -545,7 +546,8 @@ B2GPresenter.prototype.valueChanged = type: this.type, details: { eventType: 'value-change', - data: aAccessible.value + data: aAccessible.value, + options: {enqueue: aIsPolite} } }; }; diff --git a/accessible/tests/mochitest/jsat/doc_content_integration.html b/accessible/tests/mochitest/jsat/doc_content_integration.html index dcea1d8ecc10..6bffe9791382 100644 --- a/accessible/tests/mochitest/jsat/doc_content_integration.html +++ b/accessible/tests/mochitest/jsat/doc_content_integration.html @@ -44,6 +44,17 @@ document.getElementById('fruit').setAttribute('aria-label', 'banana'); } + function renameSlider() { + document.getElementById('slider').setAttribute( + 'aria-label', 'mover'); + } + + function changeSliderValue() { + document.getElementById('slider').setAttribute('aria-valuenow', '5'); + document.getElementById('slider').setAttribute( + 'aria-valuetext', 'medium'); + } + + + +
+
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
+
+ + diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html b/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html new file mode 100644 index 000000000000..e989d0e86376 --- /dev/null +++ b/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html @@ -0,0 +1,36 @@ + + + + + + + +
+
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
+
+ + diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1.html b/layout/reftests/invalidation/image-scrolling-zoom-1.html new file mode 100644 index 000000000000..85a2753b0367 --- /dev/null +++ b/layout/reftests/invalidation/image-scrolling-zoom-1.html @@ -0,0 +1,51 @@ + + + + + + + +
+
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
Item
+
+
+ + + diff --git a/layout/reftests/invalidation/one-pixel-wide-background.png b/layout/reftests/invalidation/one-pixel-wide-background.png new file mode 100644 index 0000000000000000000000000000000000000000..09f59e39ac05bad3f390aeecd72bf750069b738a GIT binary patch literal 1059 zcmZ{jPm9w)7{+G}ENhlMErO^EA$mXzscg4K{K770hfbumQjoG;W1Wie71~YPk%{)%I z8vr*){4>TZ(DFD+GL(1p!h!g=kfE*>7WTTMkNX3yODNV_X4ABEPt`QdrL#F2`j0D| zk2?A*#!>{~VzDq64U^E9&~CTe&~l*T7~ElGX9){(BgyWTi!9giaWUSLs1kK6y#>i#Z?Q;M@p_*<1<*6RKt&Pa4BmVcgv%yTNFCfBLSYTkRW zWMr`pjMo9OC;{RiP*JI|AI3N-a^bnJ)$3fBM1(#|gDDo}DiBGkyNf6jDT*bBktQn8 zh2mG1e(kbv3Y9mGr}6_`Hle5fdUx*!@5>uKe}A;KH~oEa@o-mB6las#0MIYW=Iyti Q6w$f8N5}s8!HYM40j82W^#A|> literal 0 HcmV?d00001 diff --git a/layout/reftests/invalidation/reftest.list b/layout/reftests/invalidation/reftest.list index df3ef58d958e..34081a30e114 100644 --- a/layout/reftests/invalidation/reftest.list +++ b/layout/reftests/invalidation/reftest.list @@ -64,3 +64,5 @@ pref(layout.animated-image-layers.enabled,true) random-if(Android||gtk2Widget) = skip-if(asyncPanZoom&&winWidget) != layer-splitting-5.html about:blank skip-if(asyncPanZoom&&winWidget) != layer-splitting-6.html about:blank != layer-splitting-7.html about:blank +fuzzy-if(gtk2Widget,2,4) == image-scrolling-zoom-1.html image-scrolling-zoom-1-ref.html +!= image-scrolling-zoom-1-ref.html image-scrolling-zoom-1-notref.html From d2fb40701c8e896f9bd867778be148a34d70337b Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 21 Apr 2015 19:23:10 -0700 Subject: [PATCH 077/241] Bug 1085783 (Part 1) - Snap both the fill and dest rects using UserToDeviceSnapped() when pixel snapping images. r=roc --- layout/base/nsLayoutUtils.cpp | 74 +++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index a5b7af3bbf7d..512d3181ec77 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5831,11 +5831,12 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, // Avoid unnecessarily large offsets. bool doTile = !aDest.Contains(aFill); - nsRect dest = doTile ? TileNearRect(aDest, aFill.Intersect(aDirty)) : aDest; - nsPoint anchor = aAnchor + (dest.TopLeft() - aDest.TopLeft()); + nsRect appUnitDest = doTile ? TileNearRect(aDest, aFill.Intersect(aDirty)) + : aDest; + nsPoint anchor = aAnchor + (appUnitDest.TopLeft() - aDest.TopLeft()); gfxRect devPixelDest = - nsLayoutUtils::RectToGfxRect(dest, aAppUnitsPerDevPixel); + nsLayoutUtils::RectToGfxRect(appUnitDest, aAppUnitsPerDevPixel); gfxRect devPixelFill = nsLayoutUtils::RectToGfxRect(aFill, aAppUnitsPerDevPixel); gfxRect devPixelDirty = @@ -5843,52 +5844,57 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, gfxMatrix currentMatrix = aCtx->CurrentMatrix(); gfxRect fill = devPixelFill; + gfxRect dest = devPixelDest; bool didSnap; // Snap even if we have a scale in the context. But don't snap if // we have something that's not translation+scale, or if the scale flips in // the X or Y direction, because snapped image drawing can't handle that yet. if (!currentMatrix.HasNonAxisAlignedTransform() && currentMatrix._11 > 0.0 && currentMatrix._22 > 0.0 && - aCtx->UserToDevicePixelSnapped(fill, true)) { + aCtx->UserToDevicePixelSnapped(fill, true) && + aCtx->UserToDevicePixelSnapped(dest, true)) { + // We snapped. On this code path, |fill| and |dest| take into account + // currentMatrix's transform. didSnap = true; - if (fill.IsEmpty()) { - return SnappedImageDrawingParameters(); - } } else { + // We didn't snap. On this code path, |fill| and |dest| do not take into + // account currentMatrix's transform. didSnap = false; fill = devPixelFill; + dest = devPixelDest; } - // Apply the context's scale to the dest rect. - gfxSize destScale = didSnap ? gfxSize(currentMatrix._11, currentMatrix._22) - : currentMatrix.ScaleFactors(true); - gfxSize appUnitScaledDest(dest.width * destScale.width, - dest.height * destScale.height); - gfxSize scaledDest = appUnitScaledDest / aAppUnitsPerDevPixel; - if (scaledDest.IsEmpty()) { + // If we snapped above, |dest| already takes into account |currentMatrix|'s scale + // and has integer coordinates. If not, we need these properties to compute + // the optimal drawn image size, so compute |snappedDestSize| here. + gfxSize snappedDestSize = dest.Size(); + if (!didSnap) { + gfxSize scaleFactors = currentMatrix.ScaleFactors(true); + snappedDestSize.Scale(scaleFactors.width, scaleFactors.height); + snappedDestSize.width = NS_round(snappedDestSize.width); + snappedDestSize.height = NS_round(snappedDestSize.height); + } + + // We need to be sure that this is at least one pixel in width and height, + // or we'll end up drawing nothing even if we have a nonempty fill. + snappedDestSize.width = std::max(snappedDestSize.width, 1.0); + snappedDestSize.height = std::max(snappedDestSize.height, 1.0); + + // Bail if we're not going to end up drawing anything. + if (fill.IsEmpty() || snappedDestSize.IsEmpty()) { return SnappedImageDrawingParameters(); } - // Compute a snapped version of the scaled dest rect, which we'll use to - // determine the optimal image size to draw with. We need to be sure that - // this rect is at least one pixel in width and height, or we'll end up - // drawing nothing even if we have a nonempty fill. - gfxSize snappedScaledDest = - gfxSize(NSAppUnitsToIntPixels(appUnitScaledDest.width, aAppUnitsPerDevPixel), - NSAppUnitsToIntPixels(appUnitScaledDest.height, aAppUnitsPerDevPixel)); - snappedScaledDest.width = std::max(snappedScaledDest.width, 1.0); - snappedScaledDest.height = std::max(snappedScaledDest.height, 1.0); - nsIntSize intImageSize = - aImage->OptimalImageSizeForDest(snappedScaledDest, + aImage->OptimalImageSizeForDest(snappedDestSize, imgIContainer::FRAME_CURRENT, aGraphicsFilter, aImageFlags); gfxSize imageSize(intImageSize.width, intImageSize.height); + // XXX(seth): May be buggy; see bug 1151016. CSSIntSize svgViewportSize = currentMatrix.IsIdentity() ? CSSIntSize(intImageSize.width, intImageSize.height) - : CSSIntSize(NSAppUnitsToIntPixels(dest.width, aAppUnitsPerDevPixel), //XXX BUG! - NSAppUnitsToIntPixels(dest.height, aAppUnitsPerDevPixel)); //XXX BUG! + : CSSIntSize(devPixelDest.width, devPixelDest.height); // Compute the set of pixels that would be sampled by an ideal rendering gfxPoint subimageTopLeft = @@ -5904,8 +5910,9 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, gfxMatrix transform; gfxMatrix invTransform; - bool anchorAtUpperLeft = anchor.x == dest.x && anchor.y == dest.y; - bool exactlyOneImageCopy = aFill.IsEqualEdges(dest); + bool anchorAtUpperLeft = anchor.x == appUnitDest.x && + anchor.y == appUnitDest.y; + bool exactlyOneImageCopy = aFill.IsEqualEdges(appUnitDest); if (anchorAtUpperLeft && exactlyOneImageCopy) { // The simple case: we can ignore the anchor point and compute the // transformation from the sampled region (the subimage) to the fill rect. @@ -5933,7 +5940,14 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, anchorPoint = StableRound(anchorPoint); } - gfxRect anchoredDestRect(anchorPoint, scaledDest); + // Compute an unsnapped version of the dest rect's size. We continue to + // follow the pattern that we take |currentMatrix| into account only if + // |didSnap| is true. + gfxSize unsnappedDestSize + = didSnap ? devPixelDest.Size() * currentMatrix.ScaleFactors(true) + : devPixelDest.Size(); + + gfxRect anchoredDestRect(anchorPoint, unsnappedDestSize); gfxRect anchoredImageRect(imageSpaceAnchorPoint, imageSize); // Calculate anchoredDestRect with snapped fill rect when the devPixelFill rect From 0d5b8cabbbe9609d0b064038231dd5f893ea6d8f Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 21 Apr 2015 19:23:13 -0700 Subject: [PATCH 078/241] Bug 1085783 (Part 2) - Add a test for rounding behavior when high-quality downscaling. r=roc --- .../green-circle-with-blue-border.png | Bin 0 -> 12279 bytes .../image-high-quality-scaling-1-ref.html | 22 ++++++++++++++++++ .../image-high-quality-scaling-1.html | 22 ++++++++++++++++++ layout/reftests/pixel-rounding/reftest.list | 4 ++++ 4 files changed, 48 insertions(+) create mode 100644 layout/reftests/pixel-rounding/green-circle-with-blue-border.png create mode 100644 layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html create mode 100644 layout/reftests/pixel-rounding/image-high-quality-scaling-1.html diff --git a/layout/reftests/pixel-rounding/green-circle-with-blue-border.png b/layout/reftests/pixel-rounding/green-circle-with-blue-border.png new file mode 100644 index 0000000000000000000000000000000000000000..570fd24944a815efd7026eea8df31326a206e52d GIT binary patch literal 12279 zcmZ{K1z42ZxBd(`AVVr30)n)3Nq2V)-O>Wm-8hJZbc1w?bTdHn~kFb#eKb|W{&P|!cl;wa(rxFrcP`etn6(68_CV)^?!Hof3WUL{!f~vm(Bk{yD#~R_D30i^-&0^Q2}K~ z3!B&8Ql@T}BAo0T+$`)|ES&6`9Q*?8Tmn4<vxS{Pzg|uq9nAP2C(_G#wr7L?AX^ zmUi~{uM{s?U$S!i#r-GZALRRS2&lT)SRxgCuSO9h{Qr~v8!zc-@8n|X>Uxjo{u}>K z*}w7XmadL=?)TMeIoP;~aQ;pCm-yc-z5gy3;r$QipTd6=bpJQPKZXAw+)sqSA5G~> z+1Oh;{22=;7jiWJYstTvl8$zcE*egz=9c#g`$PGM=-=o+?dbh?J1^PU|JlwzO8#aF zvE5tqKdk#N*ZCtw`i=+~Ij8^eLlLmWHvrPTnbzf{#5KKuyO|h%1k$s2t-dZ|k5MRT z=75iX3qD+WEDlPPRzszC@n(*AcX_7!#M#)${lrMmEy-UCV&Mq_>PbTqrGdc!;N!%r zkOvPjV&Bu?#fwF6-HNt<=wX)?{vj-U_U*Zdr0Ne1RpFD;J-3$9(o$(@wFk3?8aXn_ zp05TKMGc%v_GkN+)2_{`3;0&w$lru7)4N)x8WMlf3}w(-QqW3;kkP%@{$RRasg6}1 z-(9M-r1dCjn55S*!p87hUG-#{v)onFWe~g<*KUDRD&8<6LIIQNpgajB=OXl_6-?OA z^sV-2bA}HszjDc;KE{tF{TqtY+$2*LSM$fL^(svZObn|F4x@W-;K^aKQnkZ$uw5GG zM5lfAu8vcST|PtiZMpo(6?p~eL~5q9Pahsxe$A|z^=udVY%pW)AMeBU!PC(nxRiPB zF&h;;JtTU0F*rLCo=?oeR0|iZKT?| z^jo60V!qq#V|C7bLt8SC3*TeTdf6taQ2T`S93vyIYs~ZONq7p+FTE4@o>KH{B3s{Q zNoc~jQLT4F2Gm!*QxR3;I9Z8{YrbpM=8okIe3$+;>I)Q*D}%_k*|p#8Y{Gb=xvm>x z_SCIL;sc)2$|pxVFSRQo%lQ_9S(GW(WZVP{ZJm1DqX-;`oZjY)mm8*iCy%m%KC-{tS%5HQj zB`{i9-)n*EvvZTSGshUub#O(b&)di;6MK6^ABjYymt+UC^tqC~$K0JGbvmyPz~71ajrO{wWL zs~&i+0^vXB`>1c;*Y+E;cUE7IG5Dq^D`0##O$Mx9wKTt;-6k_;{Y^u}&HcFfz4@U% zg8qhwVV?7SSgDN9`mxqmF`+r*Ibp+DpX^xkRj)9DbkTs>gTCUR?T-?C<_AQzVk=ic z!dDw3QC#~TEu4$KmNPns_Qse|tQU}?R}NJ6?Z$JQ+H>xWYHD5Bcg?Ot*}uOH(}%(q zUpSqIL=1kvc%f4H+%BwasPm5Avn<}xcr8(a;QF-s-8{Je@*^RBD&NUM7t61%gl z$<9&3<=zh~#Kpl$P=b9E@sB$fMj$LLm3`_1vErAUX4x9kFdvyBMlnt=VfnxRP)Rm3^SiVg>U`6%48aG zjhS`H==?7tefY**ffH3b`Pn17+}>e#B05Wzeno5R1u&mxx3{YEb__-@2`PM!i&})w zrNwRL^Ow_zm*WWLzsj5mR9&9PNE*;?o-X#i3;1$IZESz#7f|D(ydlZuv`b&as)_b? zLwa7=us$^)rp_niw=JYP;AhYHt`Vn4SZI$&yMX8l>3S@dpZQ&LRM2s~A+7Hm`cUV| zW%!jZgYyQx&5v&_435HP17kWq7t?cuZ7ti0;b|N|G4)ZC*dodRG6h#__=lqqQeLS~rU^*S>?uzkO$8 zjMp9~2t2g&Dv?}y@`~do##i*2{fIwWl)Ej@87geJq!euo?rt|~pGNxP;UVUDC&q{9 zcjD>~RCEeF5z}91#>C`F+JSty80GvY3~5{H#)v3$8^rhF*>GMkR^wtZuO}k)3&~ zE59vM6#8nQfBdP*yl!fdlx}bQ+Cak0EpqBzR^6Emj5kyGqg?4r(afTlrUXYLqo;y>z zk;3L&2p{_LF+Xk|m$o+kBUVVP1V(5q>dx@eQ{(xy<6bhlvK$X;#9ty&JP@ zkar#+u>Qw|3&@;^jK&wW@q%)HDT7Lz!^-iQjdSt_6U9r>P@6ZALN-~~-y_n(V>wEo z$4kbAYqe@GZG*aE9Dj1Urn-kupZSM5>Zx7c+3&!T^rL~;3L~|z8L72>j0T`sVsm_5 z$2b|K)=dw#g(+E9&Kl+ODwzT6OnyBUov$1}W$TtMeM;jzH#kv`ACsTEguinoY}!=n zNa=`=HgDK{>s=M2#D9zdTLK2NvRSR#O|X|rHDA3v$~Meg9zj@%JJ?(vsUKW1TvO3R z&N&~C-op01-k%}x07bO(#`A?34i~u>4|qlGD-7Pv=J0ns-&Eez*wnkFa;P~LL40v- zwDGZ4&$`IF{&nOKA2cVR0pLPk%Uqi+lFXJEpDps`>l@y9fx1z2(-wL4E?%ZdSSi%V zU0-(KN<{^J@yzpXR%^rO9d8VR`icElfG3=Ky}8)!s{e%5vk!F>x1FL+xO?ltC6Uj^ zZ!=`CU#5D&f3H*MZE~UB!I#oz6E=9W6KlM6Dt}0{b}Ay*S=dz)E$`%(XL&J zYg3M+wb^)ShU^VLS4ROLR&L(WE8V#r}&$ zdd^CL($yafw~gPUlX3PP;fL1WcCwwvG~-B!9B%90Kq8W}>}q7kRmYN&qWw-u*ye(! zKHhCOzk?@mSywRC5L`Yar(I%rc!Sf9i?#oh)N+L%W~w(0t5wy?TKD17+R8-3S9~8L zEmNOx-J}>8BE3zJvtXzbJ8{(sh+V8O`E~6Ry+^rMNMv!ESruMlPO_pmj!%-Ut`|ECE;g1)IDD25*Y3<1`Xms&xN8{gp{qRAk zzhb88<{XYgJ$w(;1ds|PBkM|WY~o12S`o`SH}Pkp!jH2mnoYM*OC0J-EKw(J1OywJC?;;KCE*m_{mkywmACzT*iO#g&DtRo;AP zE40t+*eLxtw7T* zsoN0Vw$qdbF-?F^^3fuw4)F5#MCbWYLak1vo6qMt!wD2@ovicd>*ME;mz?{ypaR^5 zWbF}&bdzw=x7Ua`dlD`w7H;CFZ?DNY_V94$wiPun9F+anvim27C#J1`bz;Q^rP*+^ zr|vZi1}ypL^3fR^wY+awgoy3#JoW3-pg=$8(0)vP!CKLFdO63Jb$$z9L?KtK!FT{N z1M}fpb>c!SOcJ72ud-q|ZO2~ZbbU#{fz_WKRWB;?o$N{M~ZpNt$ zHkkK8FTY7IzQE7(OccX*M;u@>lwMNb3JakDn|tM4$3zl)eau{#?wOS@V@{2VOAkOA zeGVZ|QH@V5D$;$l?*|vH zUld*<2)Tb`-{A|s3>;Q?cSV=Eg{cT6*M|z2#H{tHWxa+O>t^e@<|a|=Xxogc4#!;g zZ42(kqcDRs_0zIn>pet)p#Q42|K-Yk)NZHO)=rd8kd>XU{OFQo6}->h(~}hyIeQ*p zJHU3H>e=n={W!`SzNuvV2&DP?add4IRG1>x-aMf+YVRz0`BX?$DxG4Ji2(rKkL{7n zsZZsre6o`?5S?_LVRy0ZRV3YTy@(*QQe$N3)D)vFlIHm)1waXuY>0BNK!e>`*;KpB zhh7PZiid(2;s^jBuk)p)2`ak1>ymcR1;bfCm8$L(Q{@H2&~loG9FPqBeol?fFvfzA z>xV^vLE9p*lri%c-jw!{v1e9pPPTZw+yd)V|)Xq6}twG-27g=qi zh%c3TQyO8;?h*pVGZutR;KbfgB@v3mDxC2uUDKbQqh55QE@T~dHU79Lp1WP?i#Uec zLen*=D93m>T(IU$+nm^lJ=OiSN1(zx+^huX8?ZIVOLy7yu~hfPf;(lU33|^!qz)|vC=l)QJEHIO*)qdK zuV5is{HxN5jE(+LGY}qz935a%MVPwBR^g5wZaM#2>%RU)b9wvEinZ3{T5S3h0w*pH$}>zM>?AIYgy^}~@UQuvJhAJ`q1#Bx+ESTQ z=VUO6L}4_aQK-ezCOg8$M;kBjG)1S6xlObeYc7CNf(JYFx=&Hd1PnSyIS>)2WD>F} ziI13O>eX2pOu|rxuYyW#{HCzSiJ~6`5rihhhhUEI@S^rxre-!cr_& zXW{dSDAX^=&K43SjOBoyj5&uPQF(l;Q$U0u=T5a`QfP%KDFj(x6AHb%phqZN=gly0 zWG%t3Ejvf6%si~z1bkazYXm+x=R4u`vPt4Z^4?l#48z*jGOr${#Kb6O)FEonTn<#h z$P3iN;e>fS`*h~8oil%;zk9vZWyh0;;W&w4KN5xB_w;!7u-(d2(xVKyo3cY4q6N(r z0EV)J+j$R+^tHS%#B@BITtt`C%kkD)6oJP^eqwCwc1AbKes8^h6+m_usg7j=Kk-Xo zT4dgk_SeaRpO!!;ISl|P#K@EGP}L6)e8e3;#3E_UgvkHZpg6Gt6(~{zKsyn#lzzV8 z${tCEk(p6-l56P61buAXv#;!D%=foM?t?#vYJV)BRKj`9EKEviCn-?F83GS^D&VRZTeC+Z^dM}G~W}jYXcJ{ZQ~vH zjamde8nvtX5Sbjlcy@Tl!$G3J5~N zA~b#Aze->m=fn*b2-x|B$+(UNV*ew~ObKp-ip#sS!QPXay+|nlqvjX1?>RhM{ zi$8fU_Lg;wDeswjCkvQ7`d8AFi{Th=x!5~B}37<5J`&| z73vCLY6&WMR{#|OO{{pb{9r^_xhTt#_3~2TS^63RBfsdEXu&WKt3GP&&ym^}K-m~_ zL?XV-y(!kdVC{Hch7rhm(_a?GDG%hOhqB1(D%KBqx|`yA+<@03j51v0fjxwfw5qJ- z!0i&YV#x({=QVCS@djIo?}R-o)S(4XMX;37lkQ3mA$m*fK>IBdN{^M0izd>1lp!k6 zTq!_?u8M`M_5HJS!jTAHxY&X`@C7)>0tG%Z{xXbNKI474wRzBopJE#L_@n@1NlBjL_!867{ zUTIYad7#uEatX8K0-78z+oL1~xB=M2>PcsVrjhn@4BVr41Vwi0oyuSnWY6ObgEO+} zO$Wc>I)Jn0;_p`vWOw9?#Vgo?W8Zji-}hVgzP|MHQA8tlwyFwry*YZ0=Xd{}1h;tO_>av+GP32ag{)yea$!xj(7&L-zPM0dYX zD7==#e%A59k@t(L!+aT_pSMccueBL>u>FdF0yba7;(ZE35%NAoc}`Javwf zvrCE9`9|HxkWS!~@E5WfgY){ulSc@L?dL8#@klKp+0?8!#qZB$9^~1v{bdbNJv$L` zg=GMyoo_5Y$s&mxgdh_qyg@e@@JDBZfY;;M)p*yJ+~_xwovbRzShNJrQJPXOKO`d# zZO_fEDqK2XA~!WXmIU;e)7$Qa{Oc0OmEx zZ<6*X%j1S+j~kZ{`qhHFDgZ+k_ukDyO)3`^uKO-Y7Bi(9E>?D!c)zd%CLSsYAfQ$` zB!^ls(+F$#T#tdDMRF;rV+FZxG5=ZNo_rWoZ0h^vK<)_Ak^}Q;0}8)(yOJU11x!@= zGq$&y7!_ziLX`lSKMPr?n?>fR*tOY{gWU^<0ur+SRPvQOn6`~cNdF4O(1sBKzD(LkZdung+v!LJ$af$2f~7g_43u- zi*ZlH=(@r~(VyaxHB*2LH2`Z9X~;10Vt|*Md(>RZzc@HHyOT3VNWF6&8HPG@kFcMj z#j{-So`)2y&$}`c<9PN4p^|;lpki1g{wsui*jptZ)UTNw_w@Nhtcl662mvOFk%l-f z`?`(mhN`f9FzYu;_MfG^*N#FCb`S4?Fw7O5vM!#GE8}LOHkCP$emoNl@cqTqIiZkb zTDnUI%kSwXJrOcX+A$%zL0!thqK!k5p@-I>AEWe4Y0dZYS{!eMmJw3^CO0+8I+X{; zFhFapR4Z8!xSzO8Lzx^pLjTxQI)T{F+M?;?J%;&Kli_;lu#avJJvDIS4T`{@ziY|x zjfPyP#TANGMg_7UOye0~;~b>a>6Oc;9DjBZPK_wb4OcT-fJP)DiUkoXT=o1=M#)C8 zB#P)#0o-H&WY`6I5aKi=H%0lV`n6J zZ~5SJOb=(|R)mWIdWhDG(s(LDwvR0%9Fo<*TdxuqkZO06gd9#IBlK`RQg^^ll{mbu zPHIq5BKxbSZO|9*efpgEkn(;W_tX_`G_s=`DHmLhmelf`CTA)*6d7(L3B=@4wTsSv z|E^*k@ay4Igm=l3J*lEm*ded~^$mw%Q3M2;glb*IbLTD5?&xd&4W<+Kl>*`O@I}1n}p?$FYAeWO_y=yj_{2F zO`{sAzjv%+#Hb2^T2?1~YouVMX2D*)>XzehYv-MtFl@^N6dyv!R*9H4j)lh1@>O5g zmreR`O@E80tsrDwJ-w;Bib@J6aDgCRCMXR>b& zs+yB%+PzE~KKgXcYi4dXziwTAr?O5J{4@`Mt3#iimsh2In@mW%yl}K0F+y}KWmNGK z&s;8H5QD))jl#m>1EgP|EiG+L%MUK`SX%MX71`=Jb};(&dVzm+y7~~whxCE@Kl|2c z0>}rmZtUNIN<4EWLHpQGT%T`JgmDV$9}7VL1a?x8Q=XI_Ek4`{hR)?k%)3d{@cbY} zuvfB9fYN|wXiW>Ci;_1p)kzckr6JHT!;w8r)<;hQ)Xk+5^f2+=sNhQ-gJ9ufs)+FO4*;TuaJ! zo1+nnn^RXRx=*x9I3wiBe!|HL=1l3|>A|67NMc#flZ)nO&Aa)n;C8_LqAz z)AuJt1x16wWP&O!iq&Y&rIv3OG$r-LbVqQi9qCwmBVGRufq)?4CdH7xi1)y39Au^TA>p&3q+No{^XTX!m!?R6zQetx>4r5`N_3c&mOJw3V7BG`Va zn{)i1_FgH<4+w7H7qVr!XGj+p05pI}8Al(K@PQ8>;QZv7Y9=`kF&kHvb~uJ&kE>1y zpv=Aiy&+tr3=I{t6|O(HnanZhPN;&P@Mmr^&*_`ZZm5Y_(iP#uAJ3qo{N&+jo;?rg zPI$3GJ$HYy=G(N5W$Ns~!u93he6xNvug1XcINTqxtHXzBd?*W-x>N!4AvFUMJi@Wb z!u-YWyvU{Z62YG7x9nJ(d3nVhw6Sqs%5wAk7kGc-aDS!fXACDFf!a&NqGeZV;3i72 zgeg;24q3m{2k}Daki03AM?xTPPPF|ByACemM2Rv+NpNE#(><@wq{68>${oC$fYJaq zw99vSXWvN*3Dx5tobKUmy6E_d+Wk0|n{Vlh)we50!Oscta)HK#5R9&@SoBF~qp_m( zmGKJ%d+VC#H?|xtq$NfiE9h!|GT{dBK=JBM#7H*m7=3jFF3@E6BA-EHf_rweEV+s& zUU?{}5iXjdK1H2$+bPW6!;|+pxhS>nGg~*BoL0?wZGmS81`u|l&Au_gl9L?GAl@H~ zao2{e)wW_zUhxl?D>}Ns)@!pQdZ>CMYl370nW`x@aB?uM`f(RB&pabpKUrVCC9Ze4 zJCVr1Qy(ppfWA&$cmI0?PV5(tdIK0>ewx$fx<+O^tf^2#!w6>r|qh4u}bFkjsr6@LQeHa@_4N zsHth!im~Eup5D$?mGJlV7N2W0HoV@M7qOP$F03?~@^fKTB@6scFaVW)Zo-dZ$i1m6 z1~}ljuTDK&9rLV|ZCp?+Lyq6vf7qy|Nf(3U&}1E-B@7&lU%C>#^2J-@%W~Jax%&qSTR> zo|n+q<9PxX?Z9KsWA0fj6SP6`(K?c+Uh=cEnhQ9V&K~CY^rc#1L}1pQ;PW| zJ#7%gbNn$i`2Yo-Wj5XR`k<93BuW+c^EA1E%M&HjFA^k=rWfo3)FgKG>^Q`&A3CAb zH5E($UKSK!zOLn^rL21#WpM4?v{k=`oS^d*l!>B=TCb7Zq)v>9cLv)vPDBX2k(*sO z;*2Zc==TF6So+uMm%kh;ko0WwXUQKN5bF(apDK_&EwG@oWF!Royg6Q_}DGf*N8nL{#)vZpDfV*H`5v9={`Wyi^5BF zAA8ixbG35;f3j&76|)t%Ty#*pYPc{sNDUTyTbv&_!)aSzjr`UdB)iPHd4ZOtTbXV< zE99EPho4P}v5>f6vo5Mkn6|d>MMuiUM&)_=-Lueq(Yz5M`a#whz z(3CH|UtR5c6nW)6s8-rz#;fQ(e3}r&OW5=nQ@9U<_gI8|k)uic$@l?wQhjvz!v5K% zx_JeE-E#ETPj@#(5c1v8vHX^w;6z!;=i;i>9-iT&Rz1RwLta6-Pm!WO zP+PYFVeuDlcx(vlBfB&}0NGFx?{LCd59d7QJ8m85uGL&Uy%J1Lv-9X@QN3Chu3&mh z|IoH*@NH_b+pPJ@dzg(qgRy2*fj;kMF4MSc!UY}ZQ zwV+HQ5DB+8&pNU_@+V_%yklv?uchZqk%U|=t(xZHVPbw#w1Y+n^4{|V?S(zLniv`5 zMF9A%76!HFGymF--znkyI`8#;O#LQA=

5X^8m zePq^Tf5o6-v(tE6dyE3L~eL1W!;7?BQjji;t>T&Xu_AmUQ@Rnfg zgfpvK7D^6%_;X!bT=JPScbNFQn(dOnBM&lz{0)`L>+Y9_O}Iii`Ptf(5SsWs*kv1~9E1udPhNba zGmckV&nExu@5G1Q2%Useqjg?C$xYi@6=5NR5`lDU1QwU{R4xr9nEi#2=l{453om}KdR7R)pv6;*e|upNGq|faWg9DQKt=F zppA>P@jX?M>&@)=I=wnY?eWX6Fa`a|+E=2i9`%5JWLL>A-oQ7G5|V7yaMIt?F``bD z4jdYENVA~!iy7&Gqkp!_Y}r0y<~`YW^-YN+%d2c6QoNu=`O z_@cVy2Xuh?Q$QTd$JDX!qz|f}sgAp0{sc3wuw~^yrR&hzW|!*(nz^&R81hsvO~4#6 ziH?3X_{>4)`1oq2vG5=?9IUaCJ#n0oURZX66Iu6H4ic@DVg2|?ZelpvWW)T z_)Hxri^<@|aNu{fGtXAQCAZUg#V#NWPnMgbyMr5k zWAk0>cc8ya5uGYEa-%-eUe($Ij(L_hIBoGC9rd(oH*e_v{&D+FjsICKdL+DcamfMb z`sfQDCH;AYz37OM_hD)FbmgWsE7l|^McJ81Mp@|K>kRCcJM?`ZTN=zSbD@4{jsj(v+sK0(or5kpKdWWKh_U0?SSk`B?5 zdjarA)Ri91zI%$ez4u3^&b0oY8H;PJ+7wS;d)xG6X&Ljj`2b#D`g&Ijjft$VYmgiZ zas9q!a*XqJmr~(ZGaBE;r1#cuzGgiml}3a@A3wt*UFHuW7jU= zw9s}V;tg1#cR4S%l=g%vJbxs~)J5yFI$?!oa90t83=J3j!8FM%^^zf2E4{mviX??Q zta*yBflfrm<`HT9Ou=m|kMb3-qd1qKR)*lp9jc$9Re*E~%lG?ie0gaVsR{{`cmEI6 Cd^~jk literal 0 HcmV?d00001 diff --git a/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html b/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html new file mode 100644 index 000000000000..62df7fa51163 --- /dev/null +++ b/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html @@ -0,0 +1,22 @@ + + + + + + + +

+ +
+ + diff --git a/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html b/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html new file mode 100644 index 000000000000..e3d14a61f930 --- /dev/null +++ b/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html @@ -0,0 +1,22 @@ + + + + + + + +
+ +
+ + diff --git a/layout/reftests/pixel-rounding/reftest.list b/layout/reftests/pixel-rounding/reftest.list index 5a775b41570f..5dc55cde480c 100644 --- a/layout/reftests/pixel-rounding/reftest.list +++ b/layout/reftests/pixel-rounding/reftest.list @@ -123,6 +123,10 @@ fails == collapsed-border-top-6.html border-top-10-ref.html == image-width-left-5.html image-width-5.html == image-width-left-6.html image-width-6.html + +pref(image.high_quality_downscaling.enabled,true) == image-high-quality-scaling-1.html image-high-quality-scaling-1-ref.html + + != offscreen-0-ref.html offscreen-10-ref.html == offscreen-background-color-pos-4.html offscreen-0-ref.html == offscreen-background-color-pos-5.html offscreen-10-ref.html From b90b61a9580a3a21a2c4bbd3bec18e03149693af Mon Sep 17 00:00:00 2001 From: JW Wang Date: Wed, 22 Apr 2015 10:26:31 +0800 Subject: [PATCH 079/241] Bug 1091155 - don't check if 'playing' has fired for it depends on how fast decoding is which is not reliable. --- dom/media/test/test_eme_playback.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dom/media/test/test_eme_playback.html b/dom/media/test/test_eme_playback.html index 3ca002c01b8e..9c6cee8483f0 100644 --- a/dom/media/test/test_eme_playback.html +++ b/dom/media/test/test_eme_playback.html @@ -49,14 +49,11 @@ function startTest(test, token) ); var gotEncrypted = 0; - var gotPlaying = false; v.addEventListener("encrypted", function(ev) { gotEncrypted += 1; }); - v.addEventListener("playing", function () { gotPlaying = true; }); - v.addEventListener("loadedmetadata", function() { ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v), TimeStamp(token) + " isEncrypted should be true"); @@ -69,7 +66,6 @@ function startTest(test, token) is(gotEncrypted, test.sessionCount, TimeStamp(token) + " encrypted events expected: " + test.sessionCount + ", actual: " + gotEncrypted); - ok(gotPlaying, TimeStamp(token) + " playing event should have fired"); ok(Math.abs(test.duration - v.duration) < 0.1, TimeStamp(token) + " Duration of video should be corrrect"); From e459a22bdc463df30c2864dac0611a335913f911 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Tue, 21 Apr 2015 17:58:29 -0700 Subject: [PATCH 080/241] Bug 1013743, MutationObserver should observe only the subtree it is attached to, r=wchen --HG-- extra : rebase_source : c66bb5a6c5bc81163c084ddee732becd471db40e --- dom/base/nsDOMMutationObserver.cpp | 44 ++++++++++---- dom/base/nsDOMMutationObserver.h | 23 ++++++-- dom/base/test/test_mutationobservers.html | 72 ++++++++++++++++++++++- 3 files changed, 120 insertions(+), 19 deletions(-) diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp index 19c4c953bcd3..7bd9bbf086f2 100644 --- a/dom/base/nsDOMMutationObserver.cpp +++ b/dom/base/nsDOMMutationObserver.cpp @@ -64,6 +64,13 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMMutationRecord, // Observer +bool +nsMutationReceiverBase::IsObservable(nsIContent* aContent) +{ + return !aContent->ChromeOnlyAccess() && + (Observer()->IsChrome() || !aContent->IsInAnonymousSubtree()); +} + NS_IMPL_ADDREF(nsMutationReceiver) NS_IMPL_RELEASE(nsMutationReceiver) @@ -111,8 +118,7 @@ nsMutationReceiver::AttributeWillChange(nsIDocument* aDocument, int32_t aModType) { if (nsAutoMutationBatch::IsBatching() || - !ObservesAttr(aElement, aNameSpaceID, aAttribute) || - aElement->ChromeOnlyAccess()) { + !ObservesAttr(RegisterTarget(), aElement, aNameSpaceID, aAttribute)) { return; } @@ -147,14 +153,16 @@ nsMutationReceiver::CharacterDataWillChange(nsIDocument *aDocument, CharacterDataChangeInfo* aInfo) { if (nsAutoMutationBatch::IsBatching() || - !CharacterData() || !(Subtree() || aContent == Target()) || - aContent->ChromeOnlyAccess()) { + !CharacterData() || + (!Subtree() && aContent != Target()) || + (Subtree() && RegisterTarget()->SubtreeRoot() != aContent->SubtreeRoot()) || + !IsObservable(aContent)) { return; } - + nsDOMMutationRecord* m = Observer()->CurrentRecord(nsGkAtoms::characterData); - + NS_ASSERTION(!m->mTarget || m->mTarget == aContent, "Wrong target!"); @@ -173,8 +181,11 @@ nsMutationReceiver::ContentAppended(nsIDocument* aDocument, int32_t aNewIndexInContainer) { nsINode* parent = NODE_FROM(aContainer, aDocument); - bool wantsChildList = ChildList() && (Subtree() || parent == Target()); - if (!wantsChildList || aFirstNewContent->ChromeOnlyAccess()) { + bool wantsChildList = + ChildList() && + ((Subtree() && RegisterTarget()->SubtreeRoot() == parent->SubtreeRoot()) || + parent == Target()); + if (!wantsChildList || !IsObservable(aFirstNewContent)) { return; } @@ -211,8 +222,11 @@ nsMutationReceiver::ContentInserted(nsIDocument* aDocument, int32_t aIndexInContainer) { nsINode* parent = NODE_FROM(aContainer, aDocument); - bool wantsChildList = ChildList() && (Subtree() || parent == Target()); - if (!wantsChildList || aChild->ChromeOnlyAccess()) { + bool wantsChildList = + ChildList() && + ((Subtree() && RegisterTarget()->SubtreeRoot() == parent->SubtreeRoot()) || + parent == Target()); + if (!wantsChildList || !IsObservable(aChild)) { return; } @@ -243,11 +257,14 @@ nsMutationReceiver::ContentRemoved(nsIDocument* aDocument, int32_t aIndexInContainer, nsIContent* aPreviousSibling) { - if (aChild->ChromeOnlyAccess()) { + if (!IsObservable(aChild)) { return; } nsINode* parent = NODE_FROM(aContainer, aDocument); + if (Subtree() && parent->SubtreeRoot() != RegisterTarget()->SubtreeRoot()) { + return; + } if (nsAutoMutationBatch::IsBatching()) { if (nsAutoMutationBatch::IsRemovalDone()) { // This can happen for example if HTML parser parses to @@ -265,7 +282,7 @@ nsMutationReceiver::ContentRemoved(nsIDocument* aDocument, } return; - } + } if (Subtree()) { // Try to avoid creating transient observer if the node @@ -714,8 +731,9 @@ nsDOMMutationObserver::Constructor(const mozilla::dom::GlobalObject& aGlobal, return nullptr; } MOZ_ASSERT(window->IsInnerWindow()); + bool isChrome = nsContentUtils::IsChromeDoc(window->GetExtantDoc()); nsRefPtr observer = - new nsDOMMutationObserver(window.forget(), aCb); + new nsDOMMutationObserver(window.forget(), aCb, isChrome); return observer.forget(); } diff --git a/dom/base/nsDOMMutationObserver.h b/dom/base/nsDOMMutationObserver.h index 7917027fc5bd..fda8e03afb09 100644 --- a/dom/base/nsDOMMutationObserver.h +++ b/dom/base/nsDOMMutationObserver.h @@ -248,14 +248,20 @@ protected: mRegisterTarget->OwnerDoc()->SetMayHaveDOMMutationObservers(); } - bool ObservesAttr(mozilla::dom::Element* aElement, + bool IsObservable(nsIContent* aContent); + + bool ObservesAttr(nsINode* aRegisterTarget, + mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttr) { if (mParent) { - return mParent->ObservesAttr(aElement, aNameSpaceID, aAttr); + return mParent->ObservesAttr(aRegisterTarget, aElement, aNameSpaceID, aAttr); } - if (!Attributes() || (!Subtree() && aElement != Target())) { + if (!Attributes() || + (!Subtree() && aElement != Target()) || + (Subtree() && aRegisterTarget->SubtreeRoot() != aElement->SubtreeRoot()) || + !IsObservable(aElement)) { return false; } if (AllAttributes()) { @@ -447,9 +453,10 @@ class nsDOMMutationObserver final : public nsISupports, { public: nsDOMMutationObserver(already_AddRefed&& aOwner, - mozilla::dom::MutationCallback& aCb) + mozilla::dom::MutationCallback& aCb, + bool aChrome) : mOwner(aOwner), mLastPendingMutation(nullptr), mPendingMutationCount(0), - mCallback(&aCb), mWaitingForRun(false), mId(++sCount) + mCallback(&aCb), mWaitingForRun(false), mIsChrome(aChrome), mId(++sCount) { } NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -471,6 +478,11 @@ public: return mOwner; } + bool IsChrome() + { + return mIsChrome; + } + void Observe(nsINode& aTarget, const mozilla::dom::MutationObserverInit& aOptions, mozilla::ErrorResult& aRv); @@ -571,6 +583,7 @@ protected: nsRefPtr mCallback; bool mWaitingForRun; + bool mIsChrome; uint64_t mId; diff --git a/dom/base/test/test_mutationobservers.html b/dom/base/test/test_mutationobservers.html index 3f0647900943..076da19d8cee 100644 --- a/dom/base/test/test_mutationobservers.html +++ b/dom/base/test/test_mutationobservers.html @@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=641821 /** Test for Bug 641821 **/ +SimpleTest.requestFlakyTimeout("requestFlakyTimeout is silly. (But make sure marquee has time to initialize itself.)"); + var div = document.createElement("div"); var M; @@ -580,7 +582,7 @@ function testExpandos() { var m2 = new M(function(records, observer) { is(observer.expandoProperty, true); observer.disconnect(); - then(testStyleCreate); + then(testOutsideShadowDOM); }); m2.expandoProperty = true; m2.observe(div, { attributes: true }); @@ -596,6 +598,74 @@ function testExpandos() { div.setAttribute("foo", "bar2"); } +function testOutsideShadowDOM() { + var m = new M(function(records, observer) { + is(records.length, 1); + is(records[0].type, "attributes", "Should have got attributes"); + observer.disconnect(); + then(testInsideShadowDOM); + }); + m.observe(div, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }) + var sr = div.createShadowRoot(); + sr.innerHTML = "text"; + sr.firstChild.setAttribute("foo", "bar"); + sr.firstChild.firstChild.data = "text2"; + sr.firstChild.appendChild(document.createElement("div")); + div.setAttribute("foo", "bar"); +} + +function testInsideShadowDOM() { + var m = new M(function(records, observer) { + is(records.length, 4); + is(records[0].type, "childList"); + is(records[1].type, "attributes"); + is(records[2].type, "characterData"); + is(records[3].type, "childList"); + observer.disconnect(); + then(testMarquee); + }); + var sr = div.createShadowRoot(); + m.observe(sr, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + + sr.innerHTML = "text"; + sr.firstChild.setAttribute("foo", "bar"); + sr.firstChild.firstChild.data = "text2"; + sr.firstChild.appendChild(document.createElement("div")); + div.setAttribute("foo", "bar2"); + +} + +function testMarquee() { + var m = new M(function(records, observer) { + is(records.length, 1); + is(records[0].type, "attributes"); + is(records[0].attributeName, "ok"); + is(records[0].oldValue, null); + observer.disconnect(); + then(testStyleCreate); + }); + var marquee = document.createElement("marquee"); + m.observe(marquee, { + attributes: true, + attributeOldValue: true, + childList: true, + characterData: true, + subtree: true + }); + document.body.appendChild(marquee); + setTimeout(function() {marquee.setAttribute("ok", "ok")}, 500); +} + function testStyleCreate() { m = new M(function(records, observer) { is(records.length, 1, "number of records"); From 5c1e2ee9328314492d9312fec6d8a9e38e7c1f94 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 08:29:15 +0200 Subject: [PATCH 081/241] Bug 1156632 - Remove unused forward class declarations - patch 1 - dom/base, r=ehsan --- dom/base/DirectionalityUtils.h | 2 -- dom/base/Element.h | 5 ----- dom/base/File.h | 2 -- dom/base/ImportManager.h | 1 - dom/base/ShadowRoot.h | 3 --- dom/base/ThirdPartyUtil.h | 2 -- dom/base/URL.h | 2 -- dom/base/WebSocket.h | 4 ---- dom/base/nsContentAreaDragDrop.h | 4 ---- dom/base/nsContentCreatorFunctions.h | 2 -- dom/base/nsContentSink.h | 2 -- dom/base/nsContentUtils.h | 7 ------- dom/base/nsDOMClassInfo.h | 3 --- dom/base/nsDocument.h | 5 ----- dom/base/nsFrameLoader.h | 3 --- dom/base/nsFrameMessageManager.h | 2 -- dom/base/nsGenericDOMDataNode.h | 5 ----- dom/base/nsHostObjectProtocolHandler.h | 1 - dom/base/nsIAttribute.h | 1 - dom/base/nsIDOMScriptObjectFactory.h | 4 ---- dom/base/nsIDocument.h | 2 -- dom/base/nsIDocumentObserver.h | 2 -- dom/base/nsINode.h | 2 -- dom/base/nsIScriptContext.h | 10 ---------- dom/base/nsImageLoadingContent.h | 2 -- dom/base/nsJSEnvironment.h | 4 ---- dom/base/nsMappedAttributes.h | 1 - dom/base/nsNameSpaceManager.h | 1 - dom/base/nsNodeUtils.h | 2 -- dom/base/nsPIDOMWindow.h | 1 - dom/base/nsReferencedElement.h | 1 - dom/base/nsScriptNameSpaceManager.h | 4 ---- dom/base/nsTextFragment.h | 1 - dom/base/nsWindowRoot.h | 6 ------ dom/base/nsWrapperCache.h | 1 - dom/base/nsXMLContentSerializer.h | 1 - 36 files changed, 101 deletions(-) diff --git a/dom/base/DirectionalityUtils.h b/dom/base/DirectionalityUtils.h index 4b1758c180b4..6125191f7a36 100644 --- a/dom/base/DirectionalityUtils.h +++ b/dom/base/DirectionalityUtils.h @@ -10,8 +10,6 @@ #include "nscore.h" class nsIContent; -class nsIDocument; -class nsINode; class nsAString; class nsAttrValue; class nsTextNode; diff --git a/dom/base/Element.h b/dom/base/Element.h index 9d21961fc710..8a877de07e5f 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -37,16 +37,11 @@ #include "mozilla/dom/ElementBinding.h" #include "Units.h" -class nsIDOMEventListener; class nsIFrame; class nsIDOMMozNamedAttrMap; -class nsIDOMCSSStyleDeclaration; class nsIURI; -class nsIControllers; -class nsEventChainVisitor; class nsIScrollableFrame; class nsAttrValueOrString; -class ContentUnbinder; class nsContentList; class nsDOMSettableTokenList; class nsDOMTokenList; diff --git a/dom/base/File.h b/dom/base/File.h index b3fae54be4ed..41fcef670979 100644 --- a/dom/base/File.h +++ b/dom/base/File.h @@ -29,10 +29,8 @@ #include "nsWrapperCache.h" #include "nsWeakReference.h" -class nsDOMMultipartFile; class nsIFile; class nsIInputStream; -class nsIClassInfo; #define FILEIMPL_IID \ { 0xbccb3275, 0x6778, 0x4ac5, \ diff --git a/dom/base/ImportManager.h b/dom/base/ImportManager.h index 8d1aa77c3429..85e470e070a8 100644 --- a/dom/base/ImportManager.h +++ b/dom/base/ImportManager.h @@ -49,7 +49,6 @@ #include "nsURIHashKey.h" class nsIDocument; -class nsIChannel; class nsIPrincipal; class nsINode; class AutoError; diff --git a/dom/base/ShadowRoot.h b/dom/base/ShadowRoot.h index 2217f62ea399..68244135174f 100644 --- a/dom/base/ShadowRoot.h +++ b/dom/base/ShadowRoot.h @@ -15,10 +15,7 @@ class nsIAtom; class nsIContent; -class nsIDocument; -class nsPIDOMWindow; class nsXBLPrototypeBinding; -class nsTagNameMapEntry; namespace mozilla { namespace dom { diff --git a/dom/base/ThirdPartyUtil.h b/dom/base/ThirdPartyUtil.h index f0018693d484..c6c297995809 100644 --- a/dom/base/ThirdPartyUtil.h +++ b/dom/base/ThirdPartyUtil.h @@ -12,8 +12,6 @@ #include "mozilla/Attributes.h" class nsIURI; -class nsIChannel; -class nsIDOMWindow; class ThirdPartyUtil final : public mozIThirdPartyUtil { diff --git a/dom/base/URL.h b/dom/base/URL.h index 3b17727bf225..a98e3a400c36 100644 --- a/dom/base/URL.h +++ b/dom/base/URL.h @@ -11,8 +11,6 @@ #include "nsAutoPtr.h" #include "nsString.h" -class nsIDOMBlob; -class nsIPrincipal; class nsISupports; class nsIURI; diff --git a/dom/base/WebSocket.h b/dom/base/WebSocket.h index 9075b65176fe..877b16de9115 100644 --- a/dom/base/WebSocket.h +++ b/dom/base/WebSocket.h @@ -28,10 +28,6 @@ class nsIInputStream; namespace mozilla { namespace dom { -namespace workers { -class WorkerPrivate; -} - class File; class WebSocketImpl; diff --git a/dom/base/nsContentAreaDragDrop.h b/dom/base/nsContentAreaDragDrop.h index 091502e575ce..d6da34aa34dc 100644 --- a/dom/base/nsContentAreaDragDrop.h +++ b/dom/base/nsContentAreaDragDrop.h @@ -12,15 +12,11 @@ #include "nsIDOMEventListener.h" #include "nsITransferable.h" -class nsIDOMNode; class nsPIDOMWindow; -class nsIDOMDragEvent; class nsISelection; class nsITransferable; class nsIContent; -class nsIURI; class nsIFile; -class nsISimpleEnumerator; namespace mozilla { namespace dom { diff --git a/dom/base/nsContentCreatorFunctions.h b/dom/base/nsContentCreatorFunctions.h index b00a77ebde3b..e2c892b3f417 100644 --- a/dom/base/nsContentCreatorFunctions.h +++ b/dom/base/nsContentCreatorFunctions.h @@ -15,10 +15,8 @@ * (mozilla/content and mozilla/layout). */ -class nsAString; class nsIContent; class imgRequestProxy; -class nsNodeInfoManager; class nsGenericHTMLElement; namespace mozilla { diff --git a/dom/base/nsContentSink.h b/dom/base/nsContentSink.h index 4339b6eeb906..79cd6f6990b1 100644 --- a/dom/base/nsContentSink.h +++ b/dom/base/nsContentSink.h @@ -31,11 +31,9 @@ class nsIDocument; class nsIURI; class nsIChannel; class nsIDocShell; -class nsIParser; class nsIAtom; class nsIChannel; class nsIContent; -class nsViewManager; class nsNodeInfoManager; class nsScriptLoader; class nsIApplicationCache; diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 9a8895edfcc9..39e352bfeceb 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -51,18 +51,14 @@ class nsIConsoleService; class nsIContent; class nsIContentPolicy; class nsIContentSecurityPolicy; -class nsIDocShell; class nsIDocument; class nsIDocumentLoaderFactory; -class nsIDocumentObserver; class nsIDOMDocument; class nsIDOMDocumentFragment; class nsIDOMEvent; -class nsIDOMHTMLFormElement; class nsIDOMHTMLInputElement; class nsIDOMKeyEvent; class nsIDOMNode; -class nsIDOMScriptObjectFactory; class nsIDOMWindow; class nsIDragSession; class nsIEditor; @@ -71,7 +67,6 @@ class nsIFrame; class nsIImageLoadingContent; class nsIInterfaceRequestor; class nsIIOService; -class nsIJSRuntimeService; class nsILineBreaker; class nsIMessageBroadcaster; class nsNameSpaceManager; @@ -83,7 +78,6 @@ class nsIPrincipal; class nsIRequest; class nsIRunnable; class nsIScriptContext; -class nsIScriptGlobalObject; class nsIScriptSecurityManager; class nsIStringBundle; class nsIStringBundleService; @@ -96,7 +90,6 @@ class nsIXPConnect; class nsNodeInfoManager; class nsPIDOMWindow; class nsPresContext; -class nsScriptObjectTracer; class nsStringBuffer; class nsStringHashKey; class nsTextFragment; diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index da3224c68f4f..a5da614d74a1 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -18,11 +18,8 @@ #undef GetClassName #endif -class nsContentList; -class nsDocument; struct nsGlobalNameStruct; class nsGlobalWindow; -class nsIScriptSecurityManager; struct nsDOMClassInfoData; diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 3ab039290115..b6389768ba91 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -76,17 +76,12 @@ class nsDOMStyleSheetSetList; -class nsIOutputStream; class nsDocument; -class nsIDTD; class nsIRadioVisitor; class nsIFormControl; struct nsRadioGroupStruct; class nsOnloadBlocker; class nsUnblockOnloadEvent; -class nsChildContentList; -class nsHTMLStyleSheet; -class nsHTMLCSSStyleSheet; class nsDOMNavigationTiming; class nsWindowSizes; class nsHtml5TreeOpExecutor; diff --git a/dom/base/nsFrameLoader.h b/dom/base/nsFrameLoader.h index b2ba049a0b3f..2aae752c7629 100644 --- a/dom/base/nsFrameLoader.h +++ b/dom/base/nsFrameLoader.h @@ -50,9 +50,6 @@ class RenderFrameParent; #if defined(MOZ_WIDGET_GTK) typedef struct _GtkWidget GtkWidget; #endif -#ifdef MOZ_WIDGET_QT -class QX11EmbedContainer; -#endif class nsFrameLoader final : public nsIFrameLoader, public nsStubMutationObserver, diff --git a/dom/base/nsFrameMessageManager.h b/dom/base/nsFrameMessageManager.h index d25a8eddbf42..e58b63dbfad8 100644 --- a/dom/base/nsFrameMessageManager.h +++ b/dom/base/nsFrameMessageManager.h @@ -124,8 +124,6 @@ StructuredCloneData UnpackClonedMessageDataForChild(const ClonedMessageData& aDa } // namespace dom } // namespace mozilla -class nsAXPCNativeCallContext; - struct nsMessageListenerInfo { bool operator==(const nsMessageListenerInfo& aOther) const diff --git a/dom/base/nsGenericDOMDataNode.h b/dom/base/nsGenericDOMDataNode.h index 68094d3b4d08..fb00677e470c 100644 --- a/dom/base/nsGenericDOMDataNode.h +++ b/dom/base/nsGenericDOMDataNode.h @@ -23,12 +23,7 @@ #include "mozilla/dom/ShadowRoot.h" class nsIDocument; -class nsIDOMAttr; -class nsIDOMEventListener; -class nsIDOMNodeList; -class nsIFrame; class nsIDOMText; -class nsURI; #define DATA_NODE_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_)) diff --git a/dom/base/nsHostObjectProtocolHandler.h b/dom/base/nsHostObjectProtocolHandler.h index 977e5e078ff3..712c4b786754 100644 --- a/dom/base/nsHostObjectProtocolHandler.h +++ b/dom/base/nsHostObjectProtocolHandler.h @@ -17,7 +17,6 @@ #define FONTTABLEURI_SCHEME "moz-fonttable" #define RTSPURI_SCHEME "rtsp" -class nsIDOMBlob; class nsIPrincipal; namespace mozilla { diff --git a/dom/base/nsIAttribute.h b/dom/base/nsIAttribute.h index ac5cfcadbce0..1e5e53fd61bd 100644 --- a/dom/base/nsIAttribute.h +++ b/dom/base/nsIAttribute.h @@ -9,7 +9,6 @@ #include "nsINode.h" class nsDOMAttributeMap; -class nsIContent; #define NS_IATTRIBUTE_IID \ { 0x233a9c4d, 0xb27f, 0x4662, \ diff --git a/dom/base/nsIDOMScriptObjectFactory.h b/dom/base/nsIDOMScriptObjectFactory.h index 03f20f3c39da..271ec8e84388 100644 --- a/dom/base/nsIDOMScriptObjectFactory.h +++ b/dom/base/nsIDOMScriptObjectFactory.h @@ -14,10 +14,6 @@ { 0x2a50e17c, 0x46ff, 0x4150, \ { 0xbb, 0x46, 0xd8, 0x07, 0xb3, 0x36, 0xde, 0xab } } -class nsIScriptContext; -class nsIScriptGlobalObject; -class nsIDOMEventListener; - typedef nsXPCClassInfo* (*nsDOMClassInfoExternalConstructorFnc) (const char* aName); diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 52686f803058..4c25bfda83ee 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -49,7 +49,6 @@ class nsIDocShell; class nsIDocumentEncoder; class nsIDocumentObserver; class nsIDOMDocument; -class nsIDOMDocumentFragment; class nsIDOMDocumentType; class nsIDOMElement; class nsIDOMNodeFilter; @@ -119,7 +118,6 @@ class EventTarget; class FontFaceSet; class FrameRequestCallback; class ImportManager; -class OverfillCallback; class HTMLBodyElement; struct LifecycleCallbackArgs; class Link; diff --git a/dom/base/nsIDocumentObserver.h b/dom/base/nsIDocumentObserver.h index ebdf806c30b5..71df26d54141 100644 --- a/dom/base/nsIDocumentObserver.h +++ b/dom/base/nsIDocumentObserver.h @@ -9,11 +9,9 @@ #include "nsISupports.h" #include "nsIMutationObserver.h" -class nsIAtom; class nsIContent; class nsIStyleSheet; class nsIStyleRule; -class nsString; class nsIDocument; #define NS_IDOCUMENT_OBSERVER_IID \ diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h index 077e09e93db2..1543b92b9993 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -48,7 +48,6 @@ class nsIPrincipal; class nsIURI; class nsNodeSupportsWeakRefTearoff; class nsNodeWeakReference; -class nsXPCClassInfo; class nsDOMMutationObserver; namespace mozilla { @@ -73,7 +72,6 @@ class DOMQuad; class DOMRectReadOnly; class Element; class EventHandlerNonNull; -class OnErrorEventHandlerNonNull; template class Optional; class Text; class TextOrElementOrDocument; diff --git a/dom/base/nsIScriptContext.h b/dom/base/nsIScriptContext.h index 4f98e3262d08..68256eb8eaeb 100644 --- a/dom/base/nsIScriptContext.h +++ b/dom/base/nsIScriptContext.h @@ -14,16 +14,6 @@ #include "js/GCAPI.h" class nsIScriptGlobalObject; -class nsIScriptSecurityManager; -class nsIPrincipal; -class nsIAtom; -class nsIArray; -class nsIVariant; -class nsIObjectInputStream; -class nsIObjectOutputStream; -class nsIScriptObjectPrincipal; -class nsIDOMWindow; -class nsIURI; #define NS_ISCRIPTCONTEXT_IID \ { 0x901f0d5e, 0x217a, 0x45fa, \ diff --git a/dom/base/nsImageLoadingContent.h b/dom/base/nsImageLoadingContent.h index 6719ffed6f64..17698ec27774 100644 --- a/dom/base/nsImageLoadingContent.h +++ b/dom/base/nsImageLoadingContent.h @@ -27,8 +27,6 @@ class nsIURI; class nsIDocument; -class imgILoader; -class nsIIOService; class nsPresContext; class nsIContent; class imgRequestProxy; diff --git a/dom/base/nsJSEnvironment.h b/dom/base/nsJSEnvironment.h index 7447f8dc4f54..e87192a52379 100644 --- a/dom/base/nsJSEnvironment.h +++ b/dom/base/nsJSEnvironment.h @@ -19,9 +19,7 @@ #include "xpcpublic.h" class nsICycleCollectorListener; -class nsIXPConnectJSObjectHolder; class nsScriptNameSpaceManager; -class nsCycleCollectionNoteRootCallback; namespace JS { class AutoValueVector; @@ -173,8 +171,6 @@ private: static bool DOMOperationCallback(JSContext *cx); }; -class nsIJSRuntimeService; -class nsIPrincipal; class nsPIDOMWindow; namespace mozilla { diff --git a/dom/base/nsMappedAttributes.h b/dom/base/nsMappedAttributes.h index e3a6d6bf8a21..6d5a1d5b1dc6 100644 --- a/dom/base/nsMappedAttributes.h +++ b/dom/base/nsMappedAttributes.h @@ -19,7 +19,6 @@ class nsIAtom; class nsHTMLStyleSheet; -class nsRuleWalker; class nsMappedAttributes final : public nsIStyleRule { diff --git a/dom/base/nsNameSpaceManager.h b/dom/base/nsNameSpaceManager.h index 0d8428f0a4f9..566fc441bb70 100644 --- a/dom/base/nsNameSpaceManager.h +++ b/dom/base/nsNameSpaceManager.h @@ -11,7 +11,6 @@ #include "mozilla/StaticPtr.h" -class nsIAtom; class nsAString; class nsNameSpaceKey : public PLDHashEntryHdr diff --git a/dom/base/nsNodeUtils.h b/dom/base/nsNodeUtils.h index c6dadba06e90..d5e26799738b 100644 --- a/dom/base/nsNodeUtils.h +++ b/dom/base/nsNodeUtils.h @@ -12,8 +12,6 @@ #include "nsCOMArray.h" struct CharacterDataChangeInfo; -class nsIVariant; -class nsIDOMNode; template class nsCOMArray; class nsCycleCollectionTraversalCallback; namespace mozilla { diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index f0fa6c09b86f..a0d65357e5bc 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -25,7 +25,6 @@ class nsIContent; class nsIDocShell; class nsIDocument; class nsIIdleObserver; -class nsIPrincipal; class nsIScriptTimeoutHandler; class nsIURI; class nsPerformance; diff --git a/dom/base/nsReferencedElement.h b/dom/base/nsReferencedElement.h index 733debce8316..9e1d1223172b 100644 --- a/dom/base/nsReferencedElement.h +++ b/dom/base/nsReferencedElement.h @@ -15,7 +15,6 @@ #include "nsAutoPtr.h" class nsIURI; -class nsCycleCollectionCallback; /** * Class to track what element is referenced by a given ID. diff --git a/dom/base/nsScriptNameSpaceManager.h b/dom/base/nsScriptNameSpaceManager.h index b59f4849b388..a1a93178f076 100644 --- a/dom/base/nsScriptNameSpaceManager.h +++ b/dom/base/nsScriptNameSpaceManager.h @@ -79,11 +79,7 @@ struct nsGlobalNameStruct mozilla::dom::ConstructorEnabled* mConstructorEnabled; }; - -class nsIScriptContext; class nsICategoryManager; -class GlobalNameMapEntry; - class nsScriptNameSpaceManager : public nsIObserver, public nsSupportsWeakReference, diff --git a/dom/base/nsTextFragment.h b/dom/base/nsTextFragment.h index bfb2098048d1..7c1e0e33a6e5 100644 --- a/dom/base/nsTextFragment.h +++ b/dom/base/nsTextFragment.h @@ -19,7 +19,6 @@ #include "nsISupportsImpl.h" class nsString; -class nsCString; // XXX should this normalize the code to keep a \u0000 at the end? diff --git a/dom/base/nsWindowRoot.h b/dom/base/nsWindowRoot.h index 1308255be58c..fd6d9f2c2fc8 100644 --- a/dom/base/nsWindowRoot.h +++ b/dom/base/nsWindowRoot.h @@ -8,15 +8,9 @@ #define nsWindowRoot_h__ class nsPIDOMWindow; -class nsIDOMEventListener; class nsIDOMEvent; class nsIGlobalObject; -namespace mozilla { -class EventChainPostVisitor; -class EventChainPreVisitor; -} // namespace mozilla - #include "mozilla/Attributes.h" #include "mozilla/EventListenerManager.h" #include "nsIDOMEventTarget.h" diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index ac6dfa0e272e..e4606fef3107 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -23,7 +23,6 @@ class ProcessGlobal; class SandboxPrivate; class nsInProcessTabChildGlobal; class nsWindowRoot; -class XPCWrappedNativeScope; #define NS_WRAPPERCACHE_IID \ { 0x6f3179a1, 0x36f7, 0x4a5c, \ diff --git a/dom/base/nsXMLContentSerializer.h b/dom/base/nsXMLContentSerializer.h index 7f14baff1f73..56ff11ae76cc 100644 --- a/dom/base/nsXMLContentSerializer.h +++ b/dom/base/nsXMLContentSerializer.h @@ -23,7 +23,6 @@ #define kEndTag NS_LITERAL_STRING(" Date: Wed, 22 Apr 2015 08:29:17 +0200 Subject: [PATCH 082/241] Bug 1156632 - Remove unused forward class declarations - patch 2 - dom/media, dom/indexedDB, dom/svg, r=ehsan --- dom/indexedDB/ActorsChild.h | 1 - dom/indexedDB/ActorsParent.h | 4 ---- dom/indexedDB/IDBDatabase.h | 1 - dom/indexedDB/IDBObjectStore.h | 4 ---- dom/indexedDB/IDBRequest.h | 1 - dom/indexedDB/IDBTransaction.h | 2 -- dom/indexedDB/IndexedDatabase.h | 4 ---- dom/indexedDB/IndexedDatabaseManager.h | 2 -- dom/indexedDB/PermissionRequestBase.h | 1 - dom/media/AbstractMediaDecoder.h | 1 - dom/media/AudioSegment.h | 1 - dom/media/AudioSink.h | 1 - dom/media/AudioTrack.h | 2 -- dom/media/DOMMediaStream.h | 2 -- dom/media/EncodedBufferCache.h | 2 -- dom/media/GraphDriver.h | 1 - dom/media/Latency.h | 1 - dom/media/MediaDecoderStateMachine.h | 5 ----- dom/media/MediaDeviceInfo.h | 3 --- dom/media/MediaManager.h | 2 -- dom/media/MediaShutdownManager.h | 1 - dom/media/MediaStreamGraph.h | 1 - dom/media/TextTrack.h | 1 - dom/media/android/AndroidMediaPluginHost.h | 2 -- dom/media/android/AndroidMediaReader.h | 4 ---- dom/media/directshow/DirectShowReader.h | 5 ----- dom/media/directshow/SourceFilter.h | 1 - dom/media/eme/MediaKeySession.h | 3 --- dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h | 1 - dom/media/encoder/fmp4_muxer/ISOMediaWriter.h | 1 - dom/media/fmp4/PlatformDecoderModule.h | 4 ---- dom/media/gmp/GMPContentParent.h | 4 ---- dom/media/gmp/GMPParent.h | 1 - dom/media/imagecapture/ImageCapture.h | 2 -- dom/media/mediasource/SourceBufferList.h | 1 - dom/media/omx/MediaOmxReader.h | 4 ---- dom/media/omx/OMXCodecProxy.h | 1 - dom/media/systemservices/LoadMonitor.h | 1 - dom/media/webaudio/AudioContext.h | 1 - dom/media/webaudio/blink/Reverb.h | 3 --- dom/media/webm/WebMBufferedParser.h | 4 ---- dom/media/webrtc/MediaEngineDefault.h | 1 - dom/media/webspeech/recognition/SpeechRecognition.h | 2 -- dom/media/wmf/WMFReader.h | 4 ---- dom/svg/SVGContentUtils.h | 1 - dom/svg/SVGFragmentIdentifier.h | 1 - dom/svg/SVGIRect.h | 1 - dom/svg/SVGSVGElement.h | 1 - dom/svg/SVGTextPositioningElement.h | 2 -- dom/svg/nsISVGPoint.h | 2 -- dom/svg/nsSVGBoolean.h | 1 - dom/svg/nsSVGElement.h | 2 -- dom/svg/nsSVGFilters.h | 1 - dom/svg/nsSVGPathGeometryElement.h | 2 -- dom/system/gonk/AutoMounterSetting.h | 2 -- dom/system/gonk/MozMtpServer.h | 6 ------ dom/system/gonk/nsVolume.h | 1 - dom/system/gonk/nsVolumeService.h | 1 - dom/workers/DataStore.h | 1 - dom/workers/DataStoreCursor.h | 1 - dom/workers/FileReaderSync.h | 1 - dom/workers/RuntimeService.h | 1 - dom/workers/ScriptLoader.h | 6 ------ dom/workers/ServiceWorker.h | 2 -- dom/workers/ServiceWorkerManager.h | 2 -- dom/workers/ServiceWorkerRegistrar.h | 1 - dom/workers/URL.h | 2 -- 67 files changed, 135 deletions(-) diff --git a/dom/indexedDB/ActorsChild.h b/dom/indexedDB/ActorsChild.h index 5d29c221ddb4..1f1cfb3173d5 100644 --- a/dom/indexedDB/ActorsChild.h +++ b/dom/indexedDB/ActorsChild.h @@ -42,7 +42,6 @@ class IDBMutableFile; class IDBOpenDBRequest; class IDBRequest; class Key; -class PBackgroundIDBFileChild; class PermissionRequestChild; class PermissionRequestParent; class SerializedStructuredCloneReadInfo; diff --git a/dom/indexedDB/ActorsParent.h b/dom/indexedDB/ActorsParent.h index 02dc7e701821..ec7535733fe3 100644 --- a/dom/indexedDB/ActorsParent.h +++ b/dom/indexedDB/ActorsParent.h @@ -6,16 +6,12 @@ #define mozilla_dom_indexeddb_actorsparent_h__ template struct already_AddRefed; -class nsCString; -struct nsID; class nsIPrincipal; -class nsPIDOMWindow; namespace mozilla { namespace dom { class Element; -class TabParent; namespace quota { diff --git a/dom/indexedDB/IDBDatabase.h b/dom/indexedDB/IDBDatabase.h index 8dce2ac18057..5c54c91e4a26 100644 --- a/dom/indexedDB/IDBDatabase.h +++ b/dom/indexedDB/IDBDatabase.h @@ -19,7 +19,6 @@ #include "nsTHashtable.h" class nsIDocument; -class nsIWeakReference; class nsPIDOMWindow; namespace mozilla { diff --git a/dom/indexedDB/IDBObjectStore.h b/dom/indexedDB/IDBObjectStore.h index 92074cf87d67..a67c9d618602 100644 --- a/dom/indexedDB/IDBObjectStore.h +++ b/dom/indexedDB/IDBObjectStore.h @@ -27,21 +27,17 @@ class ErrorResult; namespace dom { class DOMStringList; -class nsIContentParent; template class Sequence; namespace indexedDB { -class FileManager; class IDBCursor; -class IDBKeyRange; class IDBRequest; class IDBTransaction; class IndexUpdateInfo; class Key; class KeyPath; class ObjectStoreSpec; -struct StructuredCloneFile; struct StructuredCloneReadInfo; class IDBObjectStore final diff --git a/dom/indexedDB/IDBRequest.h b/dom/indexedDB/IDBRequest.h index ffbb42f00f52..00a2cd6a4730 100644 --- a/dom/indexedDB/IDBRequest.h +++ b/dom/indexedDB/IDBRequest.h @@ -28,7 +28,6 @@ class ErrorResult; namespace dom { class DOMError; -struct ErrorEventInit; template struct Nullable; class OwningIDBObjectStoreOrIDBIndexOrIDBCursor; diff --git a/dom/indexedDB/IDBTransaction.h b/dom/indexedDB/IDBTransaction.h index 9009d7f79d70..9934157a3e9f 100644 --- a/dom/indexedDB/IDBTransaction.h +++ b/dom/indexedDB/IDBTransaction.h @@ -27,7 +27,6 @@ namespace dom { class DOMError; class DOMStringList; -class PBlobChild; namespace indexedDB { @@ -42,7 +41,6 @@ class IDBRequest; class IndexMetadata; class ObjectStoreSpec; class OpenCursorParams; -class PBackgroundIDBDatabaseFileChild; class RequestParams; class IDBTransaction final diff --git a/dom/indexedDB/IndexedDatabase.h b/dom/indexedDB/IndexedDatabase.h index e16bb76537e7..f4cfa7e295fe 100644 --- a/dom/indexedDB/IndexedDatabase.h +++ b/dom/indexedDB/IndexedDatabase.h @@ -12,8 +12,6 @@ #include "nsCOMPtr.h" #include "nsTArray.h" -class nsIInputStream; - namespace mozilla { namespace dom { @@ -23,9 +21,7 @@ namespace indexedDB { class FileInfo; class IDBDatabase; -class IDBTransaction; class SerializedStructuredCloneReadInfo; -class SerializedStructuredCloneWriteInfo; struct StructuredCloneFile { diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h index 3bd08ad4743e..3e5e700d8dbc 100644 --- a/dom/indexedDB/IndexedDatabaseManager.h +++ b/dom/indexedDB/IndexedDatabaseManager.h @@ -16,12 +16,10 @@ #include "nsClassHashtable.h" #include "nsHashKeys.h" -class nsPIDOMWindow; struct PRLogModuleInfo; namespace mozilla { -class DOMEventTargetHelper; class EventChainPostVisitor; namespace dom { diff --git a/dom/indexedDB/PermissionRequestBase.h b/dom/indexedDB/PermissionRequestBase.h index 80ffda1dd5cc..9ad3c4a71574 100644 --- a/dom/indexedDB/PermissionRequestBase.h +++ b/dom/indexedDB/PermissionRequestBase.h @@ -14,7 +14,6 @@ #include "nsString.h" class nsIPrincipal; -class nsPIDOMWindow; namespace mozilla { namespace dom { diff --git a/dom/media/AbstractMediaDecoder.h b/dom/media/AbstractMediaDecoder.h index 1c19c72f3614..d5f0f11b6058 100644 --- a/dom/media/AbstractMediaDecoder.h +++ b/dom/media/AbstractMediaDecoder.h @@ -23,7 +23,6 @@ namespace layers class MediaResource; class ReentrantMonitor; class VideoFrameContainer; -class TimedMetadata; class MediaDecoderOwner; #ifdef MOZ_EME class CDMProxy; diff --git a/dom/media/AudioSegment.h b/dom/media/AudioSegment.h index 102a4c9213cf..aae240ad8179 100644 --- a/dom/media/AudioSegment.h +++ b/dom/media/AudioSegment.h @@ -43,7 +43,6 @@ public: nsTArray > mBuffers; }; -class AudioStream; class AudioMixer; /** diff --git a/dom/media/AudioSink.h b/dom/media/AudioSink.h index a080076b21b8..8863bcaa92fc 100644 --- a/dom/media/AudioSink.h +++ b/dom/media/AudioSink.h @@ -12,7 +12,6 @@ namespace mozilla { -class AudioAvailableEventManager; class AudioStream; class MediaDecoderStateMachine; diff --git a/dom/media/AudioTrack.h b/dom/media/AudioTrack.h index b9de8c4c1ac9..ae8389e43241 100644 --- a/dom/media/AudioTrack.h +++ b/dom/media/AudioTrack.h @@ -12,8 +12,6 @@ namespace mozilla { namespace dom { -class AudioTrackList; - class AudioTrack : public MediaTrack { public: diff --git a/dom/media/DOMMediaStream.h b/dom/media/DOMMediaStream.h index eed388392389..b2c1b232bb8f 100644 --- a/dom/media/DOMMediaStream.h +++ b/dom/media/DOMMediaStream.h @@ -15,8 +15,6 @@ #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/CORSMode.h" -class nsXPCClassInfo; - // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to // GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing // currentTime getter. diff --git a/dom/media/EncodedBufferCache.h b/dom/media/EncodedBufferCache.h index f7acf2327ef7..8b78efa9002f 100644 --- a/dom/media/EncodedBufferCache.h +++ b/dom/media/EncodedBufferCache.h @@ -12,7 +12,6 @@ #include "mozilla/Mutex.h" struct PRFileDesc; -class nsIDOMBlob; namespace mozilla { @@ -20,7 +19,6 @@ namespace dom { class File; } -class ReentrantMonitor; /** * Data is moved into a temporary file when it grows beyond * the maximal size passed in the Init function. diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h index 5bc64866c24d..9ef0692775b7 100644 --- a/dom/media/GraphDriver.h +++ b/dom/media/GraphDriver.h @@ -60,7 +60,6 @@ static const int VIDEO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS + SCHEDULE_SAFETY_MARGIN_MS; class MediaStreamGraphImpl; -class MessageBlock; /** * Microseconds relative to the start of the graph timeline. diff --git a/dom/media/Latency.h b/dom/media/Latency.h index 0cee37471f3f..56645da7dafe 100644 --- a/dom/media/Latency.h +++ b/dom/media/Latency.h @@ -16,7 +16,6 @@ #include "nsIObserver.h" class AsyncLatencyLogger; -class LogEvent; PRLogModuleInfo* GetLatencyLog(); diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 1ce5b802154d..9e21e6ebea64 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -92,16 +92,11 @@ hardware (via AudioStream). #include "mozilla/RollingMean.h" #include "MediaTimer.h" -class nsITimer; - namespace mozilla { class AudioSegment; -class VideoSegment; class MediaTaskQueue; -class SharedThreadPool; class AudioSink; -class MediaDecoderStateMachineScheduler; // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to // GetTickCount() and conflicts with MediaDecoderStateMachine::GetCurrentTime diff --git a/dom/media/MediaDeviceInfo.h b/dom/media/MediaDeviceInfo.h index 2a90ea5b7a5e..c1a5a6001b91 100644 --- a/dom/media/MediaDeviceInfo.h +++ b/dom/media/MediaDeviceInfo.h @@ -14,9 +14,6 @@ namespace mozilla { namespace dom { -class Promise; -struct MediaStreamConstraints; - #define MOZILLA_DOM_MEDIADEVICEINFO_IMPLEMENTATION_IID \ {0x25091870, 0x84d6, 0x4acf, {0xaf, 0x97, 0x6e, 0xd5, 0x5b, 0xe0, 0x47, 0xb2}} diff --git a/dom/media/MediaManager.h b/dom/media/MediaManager.h index 55288e57b528..76d4940877a1 100644 --- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -45,8 +45,6 @@ namespace mozilla { namespace dom { struct MediaStreamConstraints; -class NavigatorUserMediaSuccessCallback; -class NavigatorUserMediaErrorCallback; struct MediaTrackConstraintSet; } diff --git a/dom/media/MediaShutdownManager.h b/dom/media/MediaShutdownManager.h index bcd400e9f84f..aa2e2ff1f058 100644 --- a/dom/media/MediaShutdownManager.h +++ b/dom/media/MediaShutdownManager.h @@ -19,7 +19,6 @@ namespace mozilla { class MediaDecoder; -class StateMachineThread; // The MediaShutdownManager manages shutting down the MediaDecoder // infrastructure in response to an xpcom-shutdown notification. This happens diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index 43a0cd0aaca2..c9623b3c30c7 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -248,7 +248,6 @@ class MediaInputPort; class AudioNodeEngine; class AudioNodeExternalInputStream; class AudioNodeStream; -struct AudioChunk; class CameraPreviewMediaStream; /** diff --git a/dom/media/TextTrack.h b/dom/media/TextTrack.h index 2983df14b480..03e8e4cd42aa 100644 --- a/dom/media/TextTrack.h +++ b/dom/media/TextTrack.h @@ -19,7 +19,6 @@ namespace dom { class TextTrackList; class TextTrackCue; class TextTrackCueList; -class TextTrackRegion; class HTMLTrackElement; enum TextTrackSource { diff --git a/dom/media/android/AndroidMediaPluginHost.h b/dom/media/android/AndroidMediaPluginHost.h index e965172efd4f..6a6ae3f51f93 100644 --- a/dom/media/android/AndroidMediaPluginHost.h +++ b/dom/media/android/AndroidMediaPluginHost.h @@ -13,8 +13,6 @@ namespace mozilla { -class AndroidMediaReader; - class AndroidMediaPluginHost { nsRefPtr mResourceServer; nsTArray mPlugins; diff --git a/dom/media/android/AndroidMediaReader.h b/dom/media/android/AndroidMediaReader.h index a968b8a641d0..d573ea654bd9 100644 --- a/dom/media/android/AndroidMediaReader.h +++ b/dom/media/android/AndroidMediaReader.h @@ -25,10 +25,6 @@ namespace layers { class ImageContainer; } -namespace dom { -class TimeRanges; -} - class AndroidMediaReader : public MediaDecoderReader { nsCString mType; diff --git a/dom/media/directshow/DirectShowReader.h b/dom/media/directshow/DirectShowReader.h index 7699deebc9db..792121a02711 100644 --- a/dom/media/directshow/DirectShowReader.h +++ b/dom/media/directshow/DirectShowReader.h @@ -15,17 +15,12 @@ struct IGraphBuilder; struct IMediaControl; struct IMediaSeeking; -struct IMediaEventEx; namespace mozilla { class AudioSinkFilter; class SourceFilter; -namespace dom { -class TimeRanges; -} - // Decoder backend for decoding MP3 using DirectShow. DirectShow operates as // a filter graph. The basic design of the DirectShowReader is that we have // a SourceFilter that wraps the MediaResource that connects to the diff --git a/dom/media/directshow/SourceFilter.h b/dom/media/directshow/SourceFilter.h index 3b171bd45063..d5ce2770e9a6 100644 --- a/dom/media/directshow/SourceFilter.h +++ b/dom/media/directshow/SourceFilter.h @@ -19,7 +19,6 @@ namespace mozilla { class MediaResource; -class ReadRequest; class OutputPin; diff --git a/dom/media/eme/MediaKeySession.h b/dom/media/eme/MediaKeySession.h index 37995c65db64..a84486672560 100644 --- a/dom/media/eme/MediaKeySession.h +++ b/dom/media/eme/MediaKeySession.h @@ -23,9 +23,6 @@ struct JSContext; namespace mozilla { - -class CDMProxy; - namespace dom { class ArrayBufferViewOrArrayBuffer; diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h b/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h index bc615f96950c..3803210d542a 100644 --- a/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h +++ b/dom/media/encoder/fmp4_muxer/ISOMediaBoxes.h @@ -28,7 +28,6 @@ namespace mozilla { class AudioTrackMetadata; class VideoTrackMetadata; -class ES_Descriptor; class ISOControl; /** diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h b/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h index bcb047b9a16f..78d7a4a7599b 100644 --- a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h +++ b/dom/media/encoder/fmp4_muxer/ISOMediaWriter.h @@ -13,7 +13,6 @@ namespace mozilla { class ISOControl; class FragmentBuffer; -class ISOMediaWriterRunnable; class ISOMediaWriter : public ContainerWriter { diff --git a/dom/media/fmp4/PlatformDecoderModule.h b/dom/media/fmp4/PlatformDecoderModule.h index f4d2a5c49d3b..88a808f67a81 100644 --- a/dom/media/fmp4/PlatformDecoderModule.h +++ b/dom/media/fmp4/PlatformDecoderModule.h @@ -13,14 +13,11 @@ #include "mozilla/RefPtr.h" #include -class nsIThreadPool; - namespace mozilla { class TrackInfo; class AudioInfo; class VideoInfo; class MediaRawData; -class MediaByteBuffer; namespace layers { class ImageContainer; @@ -28,7 +25,6 @@ class ImageContainer; class MediaDataDecoder; class MediaDataDecoderCallback; -class MediaInputQueue; class FlushableMediaTaskQueue; class CDMProxy; typedef int64_t Microseconds; diff --git a/dom/media/gmp/GMPContentParent.h b/dom/media/gmp/GMPContentParent.h index 67cb81e62361..c137b675fb8e 100644 --- a/dom/media/gmp/GMPContentParent.h +++ b/dom/media/gmp/GMPContentParent.h @@ -9,14 +9,10 @@ #include "mozilla/gmp/PGMPContentParent.h" #include "nsISupportsImpl.h" -class nsITimer; - namespace mozilla { namespace gmp { -class GeckoMediaPluginService; class GMPAudioDecoderParent; -class GMPCapability; class GMPDecryptorParent; class GMPParent; class GMPVideoDecoderParent; diff --git a/dom/media/gmp/GMPParent.h b/dom/media/gmp/GMPParent.h index cd5a1c02be82..27d564a180a8 100644 --- a/dom/media/gmp/GMPParent.h +++ b/dom/media/gmp/GMPParent.h @@ -23,7 +23,6 @@ #include "nsIFile.h" #include "ThreadSafeRefcountingWithMainThreadDestruction.h" -class nsILineInputStream; class nsIThread; #ifdef MOZ_CRASHREPORTER diff --git a/dom/media/imagecapture/ImageCapture.h b/dom/media/imagecapture/ImageCapture.h index 14d8361a18a0..1335f0382521 100644 --- a/dom/media/imagecapture/ImageCapture.h +++ b/dom/media/imagecapture/ImageCapture.h @@ -11,8 +11,6 @@ #include "mozilla/dom/ImageCaptureBinding.h" #include "prlog.h" -class nsIDOMBlob; - namespace mozilla { #ifdef PR_LOGGING diff --git a/dom/media/mediasource/SourceBufferList.h b/dom/media/mediasource/SourceBufferList.h index f1ea2b546c9a..83c019c87f42 100644 --- a/dom/media/mediasource/SourceBufferList.h +++ b/dom/media/mediasource/SourceBufferList.h @@ -22,7 +22,6 @@ class JSObject; namespace mozilla { -class ErrorResult; template class AsyncEventRunner; namespace dom { diff --git a/dom/media/omx/MediaOmxReader.h b/dom/media/omx/MediaOmxReader.h index 641c423fe1ec..1d2a13b76f0b 100644 --- a/dom/media/omx/MediaOmxReader.h +++ b/dom/media/omx/MediaOmxReader.h @@ -22,10 +22,6 @@ class MOZ_EXPORT MediaExtractor; namespace mozilla { -namespace dom { - class TimeRanges; -} - class AbstractMediaDecoder; class MediaOmxReader : public MediaOmxCommonReader diff --git a/dom/media/omx/OMXCodecProxy.h b/dom/media/omx/OMXCodecProxy.h index 166ea6b4d5e4..4746646bd0b1 100644 --- a/dom/media/omx/OMXCodecProxy.h +++ b/dom/media/omx/OMXCodecProxy.h @@ -17,7 +17,6 @@ namespace android { -struct MediaBufferGroup; struct MetaData; class OMXCodecProxy : public MediaSource, diff --git a/dom/media/systemservices/LoadMonitor.h b/dom/media/systemservices/LoadMonitor.h index ad5f6aca429a..2b496157e534 100644 --- a/dom/media/systemservices/LoadMonitor.h +++ b/dom/media/systemservices/LoadMonitor.h @@ -16,7 +16,6 @@ #include "nsIObserver.h" namespace mozilla { -class LoadInfoUpdateRunner; class LoadInfoCollectRunner; class LoadNotificationCallback diff --git a/dom/media/webaudio/AudioContext.h b/dom/media/webaudio/AudioContext.h index 20e7f5b64823..26619bb848c6 100644 --- a/dom/media/webaudio/AudioContext.h +++ b/dom/media/webaudio/AudioContext.h @@ -35,7 +35,6 @@ class DOMMediaStream; class ErrorResult; class MediaStream; class MediaStreamGraph; -class AudioNodeEngine; class AudioNodeStream; namespace dom { diff --git a/dom/media/webaudio/blink/Reverb.h b/dom/media/webaudio/blink/Reverb.h index 97fa311cdb56..135381fe87e4 100644 --- a/dom/media/webaudio/blink/Reverb.h +++ b/dom/media/webaudio/blink/Reverb.h @@ -41,9 +41,6 @@ class ThreadSharedFloatArrayBufferList; namespace WebCore { -class DirectConvolver; -class FFTConvolver; - // Multi-channel convolution reverb with channel matrixing - one or more ReverbConvolver objects are used internally. class Reverb { diff --git a/dom/media/webm/WebMBufferedParser.h b/dom/media/webm/WebMBufferedParser.h index 971bf0712d81..9fe05945bfff 100644 --- a/dom/media/webm/WebMBufferedParser.h +++ b/dom/media/webm/WebMBufferedParser.h @@ -12,10 +12,6 @@ namespace mozilla { -namespace dom { -class TimeRanges; -} - // Stores a stream byte offset and the scaled timecode of the block at // that offset. struct WebMTimeDataOffset diff --git a/dom/media/webrtc/MediaEngineDefault.h b/dom/media/webrtc/MediaEngineDefault.h index 89cc998a3c15..88a3a1198449 100644 --- a/dom/media/webrtc/MediaEngineDefault.h +++ b/dom/media/webrtc/MediaEngineDefault.h @@ -23,7 +23,6 @@ namespace mozilla { namespace layers { class ImageContainer; -class PlanarYCbCrImage; } class MediaEngineDefault; diff --git a/dom/media/webspeech/recognition/SpeechRecognition.h b/dom/media/webspeech/recognition/SpeechRecognition.h index 98d4f30f6a3c..8e1177e7360d 100644 --- a/dom/media/webspeech/recognition/SpeechRecognition.h +++ b/dom/media/webspeech/recognition/SpeechRecognition.h @@ -31,8 +31,6 @@ #include "mozilla/dom/SpeechRecognitionError.h" -class nsIDOMWindow; - namespace mozilla { namespace dom { diff --git a/dom/media/wmf/WMFReader.h b/dom/media/wmf/WMFReader.h index f5de0cf86730..4c04c0ca3a1b 100644 --- a/dom/media/wmf/WMFReader.h +++ b/dom/media/wmf/WMFReader.h @@ -18,10 +18,6 @@ class WMFByteStream; class WMFSourceReaderCallback; class DXVA2Manager; -namespace dom { -class TimeRanges; -} - // Decoder backend for reading H.264/AAC in MP4/M4A, and MP3 files using // Windows Media Foundation. class WMFReader : public MediaDecoderReader diff --git a/dom/svg/SVGContentUtils.h b/dom/svg/SVGContentUtils.h index be709df33dbd..9c5d3faf5722 100644 --- a/dom/svg/SVGContentUtils.h +++ b/dom/svg/SVGContentUtils.h @@ -21,7 +21,6 @@ class gfxTextContextPaint; class nsIContent; class nsIDocument; class nsIFrame; -class nsPresContext; class nsStyleContext; class nsStyleCoord; class nsSVGElement; diff --git a/dom/svg/SVGFragmentIdentifier.h b/dom/svg/SVGFragmentIdentifier.h index 197418ebaaf3..5d35161fcd3a 100644 --- a/dom/svg/SVGFragmentIdentifier.h +++ b/dom/svg/SVGFragmentIdentifier.h @@ -9,7 +9,6 @@ #include "nsString.h" class nsIDocument; -class nsSVGViewElement; namespace mozilla { diff --git a/dom/svg/SVGIRect.h b/dom/svg/SVGIRect.h index 44ba61feee28..50c3daf2358a 100644 --- a/dom/svg/SVGIRect.h +++ b/dom/svg/SVGIRect.h @@ -13,7 +13,6 @@ #include "nsWrapperCache.h" class nsIContent; -class nsSVGElement; namespace mozilla { namespace dom { diff --git a/dom/svg/SVGSVGElement.h b/dom/svg/SVGSVGElement.h index 60d840a0cd6b..0c30262ffdf9 100644 --- a/dom/svg/SVGSVGElement.h +++ b/dom/svg/SVGSVGElement.h @@ -24,7 +24,6 @@ nsresult NS_NewSVGSVGElement(nsIContent **aResult, class nsSMILTimeContainer; class nsSVGOuterSVGFrame; class nsSVGInnerSVGFrame; -class nsSVGImageFrame; namespace mozilla { class AutoSVGRenderingState; diff --git a/dom/svg/SVGTextPositioningElement.h b/dom/svg/SVGTextPositioningElement.h index fce810862277..82029db9a0f7 100644 --- a/dom/svg/SVGTextPositioningElement.h +++ b/dom/svg/SVGTextPositioningElement.h @@ -10,8 +10,6 @@ #include "SVGAnimatedLengthList.h" #include "SVGAnimatedNumberList.h" -class nsSVGElement; - namespace mozilla { class SVGAnimatedLengthList; class DOMSVGAnimatedLengthList; diff --git a/dom/svg/nsISVGPoint.h b/dom/svg/nsISVGPoint.h index 3d7e8a2ac66f..2c6aacb6c2ce 100644 --- a/dom/svg/nsISVGPoint.h +++ b/dom/svg/nsISVGPoint.h @@ -11,8 +11,6 @@ #include "mozilla/dom/SVGPointBinding.h" #include "DOMSVGPointList.h" -class nsSVGElement; - // {d6b6c440-af8d-40ee-856b-02a317cab275} #define MOZILLA_NSISVGPOINT_IID \ { 0xd6b6c440, 0xaf8d, 0x40ee, \ diff --git a/dom/svg/nsSVGBoolean.h b/dom/svg/nsSVGBoolean.h index 4dfac49dcc74..df741febe0b9 100644 --- a/dom/svg/nsSVGBoolean.h +++ b/dom/svg/nsSVGBoolean.h @@ -12,7 +12,6 @@ #include "mozilla/Attributes.h" class nsIAtom; -class nsISupports; class nsSMILValue; class nsSVGElement; diff --git a/dom/svg/nsSVGElement.h b/dom/svg/nsSVGElement.h index 82af504ba120..7ca9a186b7d2 100644 --- a/dom/svg/nsSVGElement.h +++ b/dom/svg/nsSVGElement.h @@ -33,13 +33,11 @@ class nsSVGIntegerPair; class nsSVGLength2; class nsSVGNumber2; class nsSVGNumberPair; -class nsSVGPathGeometryElement; class nsSVGString; class nsSVGViewBox; namespace mozilla { namespace dom { -class CSSValue; class SVGSVGElement; static const unsigned short SVG_UNIT_TYPE_UNKNOWN = 0; diff --git a/dom/svg/nsSVGFilters.h b/dom/svg/nsSVGFilters.h index 011e208f66be..b6cf0077e554 100644 --- a/dom/svg/nsSVGFilters.h +++ b/dom/svg/nsSVGFilters.h @@ -16,7 +16,6 @@ #include "FilterSupport.h" class nsSVGFilterInstance; -class nsSVGFilterResource; class nsSVGNumberPair; struct nsSVGStringInfo { diff --git a/dom/svg/nsSVGPathGeometryElement.h b/dom/svg/nsSVGPathGeometryElement.h index 05d9421df53c..8c62fb2d801f 100644 --- a/dom/svg/nsSVGPathGeometryElement.h +++ b/dom/svg/nsSVGPathGeometryElement.h @@ -9,8 +9,6 @@ #include "mozilla/gfx/2D.h" #include "SVGGraphicsElement.h" -class gfxMatrix; - struct nsSVGMark { enum Type { eStart, diff --git a/dom/system/gonk/AutoMounterSetting.h b/dom/system/gonk/AutoMounterSetting.h index f527c1045b4b..9a874ee78066 100644 --- a/dom/system/gonk/AutoMounterSetting.h +++ b/dom/system/gonk/AutoMounterSetting.h @@ -10,8 +10,6 @@ namespace mozilla { namespace system { -class ResultListener; - class AutoMounterSetting : public nsIObserver { public: diff --git a/dom/system/gonk/MozMtpServer.h b/dom/system/gonk/MozMtpServer.h index 602bd98e26bb..9bee0c4726e7 100644 --- a/dom/system/gonk/MozMtpServer.h +++ b/dom/system/gonk/MozMtpServer.h @@ -16,12 +16,6 @@ #include "nsCOMPtr.h" #include "nsIThread.h" -namespace mozilla { -namespace system { - class Volume; -} -} - BEGIN_MTP_NAMESPACE using namespace android; diff --git a/dom/system/gonk/nsVolume.h b/dom/system/gonk/nsVolume.h index 885b7d64d083..f1fb87bea143 100644 --- a/dom/system/gonk/nsVolume.h +++ b/dom/system/gonk/nsVolume.h @@ -14,7 +14,6 @@ namespace mozilla { namespace system { class Volume; -class VolumeMountLock; class nsVolume : public nsIVolume { diff --git a/dom/system/gonk/nsVolumeService.h b/dom/system/gonk/nsVolumeService.h index b7298a9df92b..d3a615a4536f 100644 --- a/dom/system/gonk/nsVolumeService.h +++ b/dom/system/gonk/nsVolumeService.h @@ -22,7 +22,6 @@ class VolumeInfo; namespace system { -class WakeLockCallback; class Volume; /*************************************************************************** diff --git a/dom/workers/DataStore.h b/dom/workers/DataStore.h index d18414cb2f97..6a8595361028 100644 --- a/dom/workers/DataStore.h +++ b/dom/workers/DataStore.h @@ -18,7 +18,6 @@ namespace dom { class Promise; class DataStore; -class DataStoreImpl; class StringOrUnsignedLong; class OwningStringOrUnsignedLong; diff --git a/dom/workers/DataStoreCursor.h b/dom/workers/DataStoreCursor.h index e180c70dbd5b..1e36aa6ddbaa 100644 --- a/dom/workers/DataStoreCursor.h +++ b/dom/workers/DataStoreCursor.h @@ -16,7 +16,6 @@ namespace dom { class Promise; class GlobalObject; class DataStoreCursor; -class DataStoreCursorImpl; namespace workers { diff --git a/dom/workers/FileReaderSync.h b/dom/workers/FileReaderSync.h index dccc06c9725c..4a78eed2321b 100644 --- a/dom/workers/FileReaderSync.h +++ b/dom/workers/FileReaderSync.h @@ -10,7 +10,6 @@ #include "Workers.h" class nsIInputStream; -class nsIDOMBlob; namespace mozilla { class ErrorResult; diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h index 44a336e33ef9..a6be4e3bba65 100644 --- a/dom/workers/RuntimeService.h +++ b/dom/workers/RuntimeService.h @@ -16,7 +16,6 @@ #include "nsHashKeys.h" #include "nsTArray.h" -class nsIRunnable; class nsITimer; class nsPIDOMWindow; diff --git a/dom/workers/ScriptLoader.h b/dom/workers/ScriptLoader.h index 7331144132d0..91a720fa2a85 100644 --- a/dom/workers/ScriptLoader.h +++ b/dom/workers/ScriptLoader.h @@ -19,12 +19,6 @@ namespace mozilla { class ErrorResult; -namespace dom { - -template -class Sequence; - -} // namespace dom } // namespace mozilla BEGIN_WORKERS_NAMESPACE diff --git a/dom/workers/ServiceWorker.h b/dom/workers/ServiceWorker.h index 719e9ccaab9d..1223b75fede3 100644 --- a/dom/workers/ServiceWorker.h +++ b/dom/workers/ServiceWorker.h @@ -15,8 +15,6 @@ class nsPIDOMWindow; namespace mozilla { namespace dom { -class Promise; - namespace workers { class ServiceWorkerInfo; diff --git a/dom/workers/ServiceWorkerManager.h b/dom/workers/ServiceWorkerManager.h index fe9627e53fd3..dcb190760dad 100644 --- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -28,8 +28,6 @@ #include "nsTArrayForwardDeclare.h" #include "nsTObserverArray.h" -class nsIScriptError; - namespace mozilla { namespace ipc { diff --git a/dom/workers/ServiceWorkerRegistrar.h b/dom/workers/ServiceWorkerRegistrar.h index 5c99d3a3fae0..03533b951a1f 100644 --- a/dom/workers/ServiceWorkerRegistrar.h +++ b/dom/workers/ServiceWorkerRegistrar.h @@ -23,7 +23,6 @@ class nsIFile; -class nsRunnable; namespace mozilla { namespace dom { diff --git a/dom/workers/URL.h b/dom/workers/URL.h index 25deee9a8c67..8e3459ddc4e1 100644 --- a/dom/workers/URL.h +++ b/dom/workers/URL.h @@ -13,8 +13,6 @@ #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/URLSearchParams.h" -class nsIPrincipal; - namespace mozilla { namespace dom { class File; From 789ad8312d515aa5812ce5da44a7d805fb0bb46d Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 08:29:18 +0200 Subject: [PATCH 083/241] Bug 1156632 - Remove unused forward class declarations - patch 3 - dom/{events,xbl,xslt,xul} and others, r=ehsan --- dom/bindings/test/TestCImplementedInterface.h | 2 -- dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h | 2 -- dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h | 1 - dom/bluetooth/bluetooth1/BluetoothDevice.h | 1 - dom/bluetooth/bluetooth1/BluetoothPropertyContainer.h | 1 - dom/bluetooth/bluetooth1/BluetoothService.h | 1 - dom/bluetooth/bluetooth2/BluetoothDevice.h | 1 - dom/bluetooth/bluetooth2/BluetoothDiscoveryHandle.h | 1 - dom/bluetooth/bluetooth2/BluetoothGatt.h | 2 -- dom/bluetooth/bluetooth2/BluetoothGattDescriptor.h | 1 - dom/bluetooth/bluetooth2/BluetoothPairingHandle.h | 2 -- dom/bluetooth/bluetooth2/BluetoothPairingListener.h | 1 - dom/datastore/DataStoreCursor.h | 2 -- dom/datastore/DataStoreDB.h | 1 - dom/events/EventDispatcher.h | 1 - dom/events/EventListenerManager.h | 1 - dom/events/EventTarget.h | 1 - dom/events/IMEStateManager.h | 1 - dom/fetch/Fetch.h | 1 - dom/fetch/FetchDriver.h | 1 - dom/fetch/Headers.h | 2 -- dom/fetch/InternalHeaders.h | 3 --- dom/fetch/InternalRequest.h | 4 ---- dom/fetch/Request.h | 3 --- dom/fetch/Response.h | 4 ---- dom/filesystem/FileSystemTaskBase.h | 1 - dom/fmradio/FMRadio.h | 1 - dom/html/HTMLAllCollection.h | 3 --- dom/html/HTMLFrameElement.h | 2 -- dom/html/HTMLInputElement.h | 1 - dom/html/HTMLSourceElement.h | 1 - dom/html/HTMLTableCellElement.h | 2 -- dom/html/HTMLTableRowElement.h | 1 - dom/html/UndoManager.h | 1 - dom/html/nsFormSubmission.h | 5 ----- dom/html/nsHTMLDocument.h | 1 - dom/html/nsIForm.h | 2 -- dom/html/nsIFormControl.h | 2 -- dom/html/nsIHTMLCollection.h | 2 -- dom/html/nsIHTMLDocument.h | 3 --- dom/html/nsIRadioGroupContainer.h | 1 - dom/ipc/BlobChild.h | 1 - dom/ipc/BlobParent.h | 1 - dom/ipc/ContentChild.h | 6 ------ dom/ipc/ContentParent.h | 3 --- dom/ipc/CrashReporterParent.h | 1 - dom/ipc/PreallocatedProcessManager.h | 2 -- dom/ipc/ProcessHangMonitor.h | 2 -- dom/ipc/StructuredCloneUtils.h | 3 --- dom/mobileconnection/MobileNetworkInfo.h | 2 -- dom/nfc/MozNDEFRecord.h | 1 - dom/smil/nsISMILAttr.h | 1 - dom/tv/TVChannel.h | 1 - dom/xbl/XBLChildrenElement.h | 2 -- dom/xbl/nsBindingManager.h | 1 - dom/xbl/nsXBLBinding.h | 1 - dom/xbl/nsXBLDocumentInfo.h | 1 - dom/xbl/nsXBLProtoImplField.h | 1 - dom/xbl/nsXBLProtoImplMember.h | 1 - dom/xslt/xpath/XPathExpression.h | 1 - dom/xslt/xpath/txExpr.h | 1 - dom/xslt/xpath/txExprParser.h | 2 -- dom/xslt/xslt/txBufferingHandler.h | 1 - dom/xslt/xslt/txExecutionState.h | 1 - dom/xslt/xslt/txMozillaTextOutput.h | 1 - dom/xslt/xslt/txMozillaXMLOutput.h | 3 --- dom/xslt/xslt/txMozillaXSLTProcessor.h | 1 - dom/xslt/xslt/txStylesheet.h | 1 - dom/xslt/xslt/txXSLTFunctions.h | 3 --- dom/xslt/xslt/txXSLTPatterns.h | 2 -- dom/xul/XULDocument.h | 1 - dom/xul/nsXULElement.h | 3 --- dom/xul/templates/nsContentTestNode.h | 2 -- dom/xul/templates/nsRuleNetwork.h | 1 - dom/xul/templates/nsXULContentUtils.h | 3 --- dom/xul/templates/nsXULTemplateBuilder.h | 1 - dom/xul/templates/nsXULTemplateQueryProcessorRDF.h | 1 - 77 files changed, 130 deletions(-) diff --git a/dom/bindings/test/TestCImplementedInterface.h b/dom/bindings/test/TestCImplementedInterface.h index feb3b4e0e52d..4b915ad86f77 100644 --- a/dom/bindings/test/TestCImplementedInterface.h +++ b/dom/bindings/test/TestCImplementedInterface.h @@ -9,8 +9,6 @@ #include "../TestJSImplGenBinding.h" -class nsPIDOMWindow; - namespace mozilla { namespace dom { diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h index 1f83e7aa6edb..54e84c021b14 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h @@ -15,8 +15,6 @@ BEGIN_BLUETOOTH_NAMESPACE using namespace mozilla::ipc; -class BlutoothDaemonInterface; - class BluetoothDaemonSocketModule { public: diff --git a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h index 6b26af15cd69..496d70b18921 100644 --- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h +++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h @@ -17,7 +17,6 @@ BEGIN_BLUETOOTH_NAMESPACE -class BluetoothReplyRunnable; class BluetoothSocket; class Call; diff --git a/dom/bluetooth/bluetooth1/BluetoothDevice.h b/dom/bluetooth/bluetooth1/BluetoothDevice.h index 19a35fee85b8..afbd90313e1e 100644 --- a/dom/bluetooth/bluetooth1/BluetoothDevice.h +++ b/dom/bluetooth/bluetooth1/BluetoothDevice.h @@ -18,7 +18,6 @@ BEGIN_BLUETOOTH_NAMESPACE class BluetoothNamedValue; class BluetoothValue; class BluetoothSignal; -class BluetoothSocket; class BluetoothDevice : public DOMEventTargetHelper , public BluetoothSignalObserver diff --git a/dom/bluetooth/bluetooth1/BluetoothPropertyContainer.h b/dom/bluetooth/bluetooth1/BluetoothPropertyContainer.h index ce8670fdafbd..655eb74d2f58 100644 --- a/dom/bluetooth/bluetooth1/BluetoothPropertyContainer.h +++ b/dom/bluetooth/bluetooth1/BluetoothPropertyContainer.h @@ -10,7 +10,6 @@ #include "BluetoothCommon.h" #include "BluetoothReplyRunnable.h" -class nsIDOMDOMRequest; class nsPIDOMWindow; namespace mozilla { diff --git a/dom/bluetooth/bluetooth1/BluetoothService.h b/dom/bluetooth/bluetooth1/BluetoothService.h index 72e8c115b740..d634c64a46d2 100644 --- a/dom/bluetooth/bluetooth1/BluetoothService.h +++ b/dom/bluetooth/bluetooth1/BluetoothService.h @@ -27,7 +27,6 @@ class BlobParent; BEGIN_BLUETOOTH_NAMESPACE -class BluetoothManager; class BluetoothNamedValue; class BluetoothReplyRunnable; class BluetoothSignal; diff --git a/dom/bluetooth/bluetooth2/BluetoothDevice.h b/dom/bluetooth/bluetooth2/BluetoothDevice.h index 59c460459b35..64f0b57cc65e 100644 --- a/dom/bluetooth/bluetooth2/BluetoothDevice.h +++ b/dom/bluetooth/bluetooth2/BluetoothDevice.h @@ -27,7 +27,6 @@ class BluetoothGatt; class BluetoothNamedValue; class BluetoothValue; class BluetoothSignal; -class BluetoothSocket; class BluetoothDevice final : public DOMEventTargetHelper , public BluetoothSignalObserver diff --git a/dom/bluetooth/bluetooth2/BluetoothDiscoveryHandle.h b/dom/bluetooth/bluetooth2/BluetoothDiscoveryHandle.h index 675741d4f7c1..d25588a16445 100644 --- a/dom/bluetooth/bluetooth2/BluetoothDiscoveryHandle.h +++ b/dom/bluetooth/bluetooth2/BluetoothDiscoveryHandle.h @@ -16,7 +16,6 @@ BEGIN_BLUETOOTH_NAMESPACE class BluetoothDevice; -class BluetoothValue; class BluetoothDiscoveryHandle final : public DOMEventTargetHelper { diff --git a/dom/bluetooth/bluetooth2/BluetoothGatt.h b/dom/bluetooth/bluetooth2/BluetoothGatt.h index 0b417fd8b9f1..29a132254965 100644 --- a/dom/bluetooth/bluetooth2/BluetoothGatt.h +++ b/dom/bluetooth/bluetooth2/BluetoothGatt.h @@ -22,8 +22,6 @@ class Promise; BEGIN_BLUETOOTH_NAMESPACE -class BluetoothReplyRunnable; -class BluetoothService; class BluetoothSignal; class BluetoothValue; diff --git a/dom/bluetooth/bluetooth2/BluetoothGattDescriptor.h b/dom/bluetooth/bluetooth2/BluetoothGattDescriptor.h index 2633956e226a..ef6877fb7af8 100644 --- a/dom/bluetooth/bluetooth2/BluetoothGattDescriptor.h +++ b/dom/bluetooth/bluetooth2/BluetoothGattDescriptor.h @@ -20,7 +20,6 @@ BEGIN_BLUETOOTH_NAMESPACE class BluetoothGattCharacteristic; class BluetoothSignal; -class BluetoothValue; class BluetoothGattDescriptor final : public nsISupports , public nsWrapperCache diff --git a/dom/bluetooth/bluetooth2/BluetoothPairingHandle.h b/dom/bluetooth/bluetooth2/BluetoothPairingHandle.h index 0584f9e8f05f..b2ef9df6d34f 100644 --- a/dom/bluetooth/bluetooth2/BluetoothPairingHandle.h +++ b/dom/bluetooth/bluetooth2/BluetoothPairingHandle.h @@ -19,8 +19,6 @@ class Promise; BEGIN_BLUETOOTH_NAMESPACE -class BluetoothDevice; - class BluetoothPairingHandle final : public nsISupports , public nsWrapperCache { diff --git a/dom/bluetooth/bluetooth2/BluetoothPairingListener.h b/dom/bluetooth/bluetooth2/BluetoothPairingListener.h index a3a9bc470097..0e16804aa161 100644 --- a/dom/bluetooth/bluetooth2/BluetoothPairingListener.h +++ b/dom/bluetooth/bluetooth2/BluetoothPairingListener.h @@ -13,7 +13,6 @@ BEGIN_BLUETOOTH_NAMESPACE -class BluetoothDevice; class BluetoothSignal; class BluetoothPairingListener final : public DOMEventTargetHelper diff --git a/dom/datastore/DataStoreCursor.h b/dom/datastore/DataStoreCursor.h index c8a3243b2d26..a53c147ffbb5 100644 --- a/dom/datastore/DataStoreCursor.h +++ b/dom/datastore/DataStoreCursor.h @@ -9,8 +9,6 @@ #include "nsCOMPtr.h" #include "nsCycleCollectionParticipant.h" -class nsPIDOMWindow; - namespace mozilla { class ErrorResult; diff --git a/dom/datastore/DataStoreDB.h b/dom/datastore/DataStoreDB.h index a6c34292dfbe..6449ed285b2a 100644 --- a/dom/datastore/DataStoreDB.h +++ b/dom/datastore/DataStoreDB.h @@ -21,7 +21,6 @@ namespace dom { namespace indexedDB { class IDBDatabase; class IDBFactory; -class IDBObjectStore; class IDBOpenDBRequest; class IDBTransaction; } diff --git a/dom/events/EventDispatcher.h b/dom/events/EventDispatcher.h index 6795fe6f75c3..23a6087d0244 100644 --- a/dom/events/EventDispatcher.h +++ b/dom/events/EventDispatcher.h @@ -16,7 +16,6 @@ class nsIContent; class nsIDOMEvent; -class nsIScriptGlobalObject; class nsPresContext; template class nsCOMArray; diff --git a/dom/events/EventListenerManager.h b/dom/events/EventListenerManager.h index 144643d72654..478ac7f174e1 100644 --- a/dom/events/EventListenerManager.h +++ b/dom/events/EventListenerManager.h @@ -19,7 +19,6 @@ class nsIDocShell; class nsIDOMEvent; class nsIEventListenerInfo; -class nsIScriptContext; class nsPIDOMWindow; class JSTracer; diff --git a/dom/events/EventTarget.h b/dom/events/EventTarget.h index 351bf1d97f02..eee27396e57d 100644 --- a/dom/events/EventTarget.h +++ b/dom/events/EventTarget.h @@ -11,7 +11,6 @@ #include "nsIAtom.h" class nsIDOMWindow; -class nsIDOMEventListener; namespace mozilla { diff --git a/dom/events/IMEStateManager.h b/dom/events/IMEStateManager.h index 30ea50be286d..79ccf55ec37f 100644 --- a/dom/events/IMEStateManager.h +++ b/dom/events/IMEStateManager.h @@ -13,7 +13,6 @@ class nsIContent; class nsIDOMMouseEvent; class nsIEditor; class nsINode; -class nsPIDOMWindow; class nsPresContext; class nsISelection; diff --git a/dom/fetch/Fetch.h b/dom/fetch/Fetch.h index d83225ee5b5b..1125eb0a73a6 100644 --- a/dom/fetch/Fetch.h +++ b/dom/fetch/Fetch.h @@ -20,7 +20,6 @@ #include "mozilla/dom/RequestBinding.h" #include "mozilla/dom/workers/bindings/WorkerFeature.h" -class nsIOutputStream; class nsIGlobalObject; namespace mozilla { diff --git a/dom/fetch/FetchDriver.h b/dom/fetch/FetchDriver.h index b9cba3d935ef..34da18f960ff 100644 --- a/dom/fetch/FetchDriver.h +++ b/dom/fetch/FetchDriver.h @@ -24,7 +24,6 @@ class nsIPrincipal; namespace mozilla { namespace dom { -class BlobSet; class InternalRequest; class InternalResponse; diff --git a/dom/fetch/Headers.h b/dom/fetch/Headers.h index 06ee08a61474..80ab86e503d1 100644 --- a/dom/fetch/Headers.h +++ b/dom/fetch/Headers.h @@ -14,8 +14,6 @@ #include "InternalHeaders.h" -class nsPIDOMWindow; - namespace mozilla { class ErrorResult; diff --git a/dom/fetch/InternalHeaders.h b/dom/fetch/InternalHeaders.h index 5d632dcb981c..9e11a1e102ec 100644 --- a/dom/fetch/InternalHeaders.h +++ b/dom/fetch/InternalHeaders.h @@ -14,8 +14,6 @@ #include "nsClassHashtable.h" #include "nsWrapperCache.h" -class nsPIDOMWindow; - namespace mozilla { class ErrorResult; @@ -23,7 +21,6 @@ class ErrorResult; namespace dom { template class MozMap; -class HeadersOrByteStringSequenceSequenceOrByteStringMozMap; class InternalHeaders final { diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h index ebb8f4ee78ad..769c2e4a1c42 100644 --- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -19,9 +19,6 @@ #include "nsServiceManagerUtils.h" #endif -class nsIDocument; -class nsPIDOMWindow; - namespace mozilla { namespace dom { @@ -84,7 +81,6 @@ namespace dom { * TODO: Split TYPE_OBJECT into TYPE_EMBED and TYPE_OBJECT */ -class FetchBodyStream; class Request; #define kFETCH_CLIENT_REFERRER_STR "about:client" diff --git a/dom/fetch/Request.h b/dom/fetch/Request.h index 1bc6a6925075..b38f058f98a2 100644 --- a/dom/fetch/Request.h +++ b/dom/fetch/Request.h @@ -16,14 +16,11 @@ // files. #include "mozilla/dom/RequestBinding.h" -class nsPIDOMWindow; - namespace mozilla { namespace dom { class Headers; class InternalHeaders; -class Promise; class RequestOrUSVString; class Request final : public nsISupports diff --git a/dom/fetch/Response.h b/dom/fetch/Response.h index 786736144bf9..af75446bcacd 100644 --- a/dom/fetch/Response.h +++ b/dom/fetch/Response.h @@ -14,15 +14,11 @@ #include "InternalResponse.h" -class nsPIDOMWindow; - namespace mozilla { namespace dom { -class ArrayBufferOrArrayBufferViewOrUSVStringOrURLSearchParams; class Headers; class InternalHeaders; -class Promise; class Response final : public nsISupports , public FetchBody diff --git a/dom/filesystem/FileSystemTaskBase.h b/dom/filesystem/FileSystemTaskBase.h index 22acbe6b920e..624a71c29196 100644 --- a/dom/filesystem/FileSystemTaskBase.h +++ b/dom/filesystem/FileSystemTaskBase.h @@ -19,7 +19,6 @@ namespace dom { class BlobParent; class FileSystemBase; class FileSystemParams; -class Promise; /* * The base class to implement a Task class. diff --git a/dom/fmradio/FMRadio.h b/dom/fmradio/FMRadio.h index 69dd6e20a7dd..5a275feb5b18 100644 --- a/dom/fmradio/FMRadio.h +++ b/dom/fmradio/FMRadio.h @@ -14,7 +14,6 @@ #include "nsWeakReference.h" class nsPIDOMWindow; -class nsIScriptContext; BEGIN_FMRADIO_NAMESPACE diff --git a/dom/html/HTMLAllCollection.h b/dom/html/HTMLAllCollection.h index d6d71e2c8241..a80ff26ff409 100644 --- a/dom/html/HTMLAllCollection.h +++ b/dom/html/HTMLAllCollection.h @@ -21,9 +21,6 @@ class nsIContent; class nsINode; namespace mozilla { - -class ErrorResult; - namespace dom { class OwningNodeOrHTMLCollection; diff --git a/dom/html/HTMLFrameElement.h b/dom/html/HTMLFrameElement.h index ac8de9c8965b..d6a1698278c4 100644 --- a/dom/html/HTMLFrameElement.h +++ b/dom/html/HTMLFrameElement.h @@ -11,8 +11,6 @@ #include "nsGenericHTMLFrameElement.h" #include "nsGkAtoms.h" -class nsIDOMDocument; - namespace mozilla { namespace dom { diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 3e431325f078..1b3b3b117e85 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -25,7 +25,6 @@ #include "nsTextEditorState.h" class nsIRadioGroupContainer; -class nsIRadioGroupVisitor; class nsIRadioVisitor; namespace mozilla { diff --git a/dom/html/HTMLSourceElement.h b/dom/html/HTMLSourceElement.h index 34ddc82c1cdf..459aa6456075 100644 --- a/dom/html/HTMLSourceElement.h +++ b/dom/html/HTMLSourceElement.h @@ -17,7 +17,6 @@ class nsMediaList; namespace mozilla { namespace dom { -class ResponsiveImageSelector; class HTMLSourceElement final : public nsGenericHTMLElement, public nsIDOMHTMLSourceElement { diff --git a/dom/html/HTMLTableCellElement.h b/dom/html/HTMLTableCellElement.h index d0da453f434a..8b04563e4e67 100644 --- a/dom/html/HTMLTableCellElement.h +++ b/dom/html/HTMLTableCellElement.h @@ -9,8 +9,6 @@ #include "nsGenericHTMLElement.h" #include "nsIDOMHTMLTableCellElement.h" -class nsIDOMHTMLTableRowElement; - namespace mozilla { namespace dom { diff --git a/dom/html/HTMLTableRowElement.h b/dom/html/HTMLTableRowElement.h index 222689f8ceb5..42779de5a51e 100644 --- a/dom/html/HTMLTableRowElement.h +++ b/dom/html/HTMLTableRowElement.h @@ -8,7 +8,6 @@ #include "mozilla/Attributes.h" #include "nsGenericHTMLElement.h" -class nsIDOMHTMLTableElement; class nsContentList; namespace mozilla { diff --git a/dom/html/UndoManager.h b/dom/html/UndoManager.h index b56b62d0edab..ebc95e3e0218 100644 --- a/dom/html/UndoManager.h +++ b/dom/html/UndoManager.h @@ -16,7 +16,6 @@ #include "mozilla/dom/Nullable.h" class nsITransactionManager; -class nsIMutationObserver; namespace mozilla { class ErrorResult; diff --git a/dom/html/nsFormSubmission.h b/dom/html/nsFormSubmission.h index 76f527108d4f..455e3e9805de 100644 --- a/dom/html/nsFormSubmission.h +++ b/dom/html/nsFormSubmission.h @@ -12,12 +12,7 @@ class nsIURI; class nsIInputStream; class nsGenericHTMLElement; -class nsILinkHandler; class nsIContent; -class nsIFormControl; -class nsIDOMHTMLElement; -class nsIDocShell; -class nsIRequest; class nsISaveAsCharset; class nsIMultiplexInputStream; diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h index 8012bfc9dd0e..f06e071af53d 100644 --- a/dom/html/nsHTMLDocument.h +++ b/dom/html/nsHTMLDocument.h @@ -22,7 +22,6 @@ #include "mozilla/dom/HTMLSharedElement.h" class nsIEditor; -class nsIParser; class nsIURI; class nsIDocShell; class nsICachingChannel; diff --git a/dom/html/nsIForm.h b/dom/html/nsIForm.h index e103d1545f62..2772024a5808 100644 --- a/dom/html/nsIForm.h +++ b/dom/html/nsIForm.h @@ -9,8 +9,6 @@ #include "nsAString.h" class nsIFormControl; -class nsISimpleEnumerator; -class nsIURI; #define NS_FORM_METHOD_GET 0 #define NS_FORM_METHOD_POST 1 diff --git a/dom/html/nsIFormControl.h b/dom/html/nsIFormControl.h index 7922329db790..f6c9c402c008 100644 --- a/dom/html/nsIFormControl.h +++ b/dom/html/nsIFormControl.h @@ -8,8 +8,6 @@ #include "nsISupports.h" class nsIDOMHTMLFormElement; class nsPresState; -class nsString; -class nsIFormProcessor; class nsFormSubmission; namespace mozilla { diff --git a/dom/html/nsIHTMLCollection.h b/dom/html/nsIHTMLCollection.h index 8f448be948ce..709948d17ef0 100644 --- a/dom/html/nsIHTMLCollection.h +++ b/dom/html/nsIHTMLCollection.h @@ -15,8 +15,6 @@ class nsINode; class nsString; namespace mozilla { -class ErrorResult; - namespace dom { class Element; } // namespace dom diff --git a/dom/html/nsIHTMLDocument.h b/dom/html/nsIHTMLDocument.h index db8618a3b105..78a4c6515446 100644 --- a/dom/html/nsIHTMLDocument.h +++ b/dom/html/nsIHTMLDocument.h @@ -9,12 +9,9 @@ #include "nsISupports.h" #include "nsCompatibility.h" -class nsIDOMHTMLFormElement; class nsIContent; -class nsIScriptElement; class nsIEditor; class nsContentList; -class nsWrapperCache; #define NS_IHTMLDOCUMENT_IID \ { 0xcf814492, 0x303c, 0x4718, \ diff --git a/dom/html/nsIRadioGroupContainer.h b/dom/html/nsIRadioGroupContainer.h index 415389489943..a643c875f4d5 100644 --- a/dom/html/nsIRadioGroupContainer.h +++ b/dom/html/nsIRadioGroupContainer.h @@ -7,7 +7,6 @@ #include "nsISupports.h" -class nsString; class nsIRadioVisitor; class nsIFormControl; diff --git a/dom/ipc/BlobChild.h b/dom/ipc/BlobChild.h index 69798cd82447..c5c94fe93cec 100644 --- a/dom/ipc/BlobChild.h +++ b/dom/ipc/BlobChild.h @@ -10,7 +10,6 @@ #include "nsCOMPtr.h" #include "nsID.h" -class nsIDOMBlob; class nsIEventTarget; class nsIRemoteBlob; class nsString; diff --git a/dom/ipc/BlobParent.h b/dom/ipc/BlobParent.h index ee46909439c2..619e2329e052 100644 --- a/dom/ipc/BlobParent.h +++ b/dom/ipc/BlobParent.h @@ -14,7 +14,6 @@ template class nsDataHashtable; class nsIDHashKey; -class nsIDOMBlob; class nsIEventTarget; class nsIRemoteBlob; template class nsRevocableEventPtr; diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index fecb73663baa..6adf18e222d9 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -20,7 +20,6 @@ struct ChromePackage; -class nsIDOMBlob; class nsIObserver; struct ResourceMapping; struct OverrideMapping; @@ -35,10 +34,6 @@ class PFileDescriptorSetChild; class URIParams; }// namespace ipc -namespace jsipc { -class JavaScriptShared; -} - namespace layers { class PCompositorChild; } // namespace layers @@ -46,7 +41,6 @@ class PCompositorChild; namespace dom { class AlertObserver; -class PrefObserver; class ConsoleListener; class PStorageChild; class ClonedMessageData; diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 722a95002a65..8affe5a57c1d 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -30,9 +30,7 @@ class mozIApplication; class nsConsoleService; class nsICycleCollectorLogSink; -class nsIDOMBlob; class nsIDumpGCAndCCLogsCallback; -class nsIMemoryReporter; class nsITimer; class ParentIdleListener; class nsIWidget; @@ -48,7 +46,6 @@ class TestShellParent; } // namespace ipc namespace jsipc { -class JavaScriptShared; class PJavaScriptParent; } diff --git a/dom/ipc/CrashReporterParent.h b/dom/ipc/CrashReporterParent.h index 63b5c72ec880..4384ef3b011e 100644 --- a/dom/ipc/CrashReporterParent.h +++ b/dom/ipc/CrashReporterParent.h @@ -17,7 +17,6 @@ namespace mozilla { namespace dom { -class ProcessReporter; class CrashReporterParent : public PCrashReporterParent diff --git a/dom/ipc/PreallocatedProcessManager.h b/dom/ipc/PreallocatedProcessManager.h index 9caeaa032eaf..4df86726d693 100644 --- a/dom/ipc/PreallocatedProcessManager.h +++ b/dom/ipc/PreallocatedProcessManager.h @@ -11,8 +11,6 @@ #include "nsCOMPtr.h" #include "nsIObserver.h" -class nsIRunnable; - namespace mozilla { namespace dom { class ContentParent; diff --git a/dom/ipc/ProcessHangMonitor.h b/dom/ipc/ProcessHangMonitor.h index 1a7f818dffb3..3106654e9b1f 100644 --- a/dom/ipc/ProcessHangMonitor.h +++ b/dom/ipc/ProcessHangMonitor.h @@ -10,7 +10,6 @@ #include "mozilla/Atomics.h" #include "nsIObserver.h" -class nsGlobalWindow; class nsITabChild; class MessageLoop; @@ -26,7 +25,6 @@ class ContentParent; } class PProcessHangMonitorParent; -class PProcessHangMonitorChild; class ProcessHangMonitor final : public nsIObserver diff --git a/dom/ipc/StructuredCloneUtils.h b/dom/ipc/StructuredCloneUtils.h index c0171c407542..f6265a2bd18d 100644 --- a/dom/ipc/StructuredCloneUtils.h +++ b/dom/ipc/StructuredCloneUtils.h @@ -14,9 +14,6 @@ #include "js/StructuredClone.h" namespace mozilla { - -struct SerializedStructuredCloneBuffer; - namespace dom { struct diff --git a/dom/mobileconnection/MobileNetworkInfo.h b/dom/mobileconnection/MobileNetworkInfo.h index 7486fd297f20..e5f0edc85c99 100644 --- a/dom/mobileconnection/MobileNetworkInfo.h +++ b/dom/mobileconnection/MobileNetworkInfo.h @@ -15,8 +15,6 @@ namespace mozilla { namespace dom { -class GlobalObject; - class MobileNetworkInfo final : public nsIMobileNetworkInfo , public nsWrapperCache { diff --git a/dom/nfc/MozNDEFRecord.h b/dom/nfc/MozNDEFRecord.h index bddcabb2b221..170561a462f3 100644 --- a/dom/nfc/MozNDEFRecord.h +++ b/dom/nfc/MozNDEFRecord.h @@ -21,7 +21,6 @@ #include "js/GCAPI.h" #include "nsISupports.h" -class nsIGlobalObject; struct JSContext; struct JSStructuredCloneWriter; diff --git a/dom/smil/nsISMILAttr.h b/dom/smil/nsISMILAttr.h index 3d7bed6b4ad4..5ec1553bdcae 100644 --- a/dom/smil/nsISMILAttr.h +++ b/dom/smil/nsISMILAttr.h @@ -9,7 +9,6 @@ #include "nscore.h" class nsSMILValue; -class nsISMILType; class nsIContent; class nsAString; diff --git a/dom/tv/TVChannel.h b/dom/tv/TVChannel.h index ced58da78ab5..c9a0248bb985 100644 --- a/dom/tv/TVChannel.h +++ b/dom/tv/TVChannel.h @@ -18,7 +18,6 @@ namespace mozilla { namespace dom { class Promise; -class TVProgram; class TVSource; class TVChannel final : public DOMEventTargetHelper diff --git a/dom/xbl/XBLChildrenElement.h b/dom/xbl/XBLChildrenElement.h index e6440b72038f..60c668376194 100644 --- a/dom/xbl/XBLChildrenElement.h +++ b/dom/xbl/XBLChildrenElement.h @@ -17,8 +17,6 @@ class nsAnonymousContentList; namespace mozilla { namespace dom { -class ExplicitChildIterator; - class XBLChildrenElement : public nsXMLElement { public: diff --git a/dom/xbl/nsBindingManager.h b/dom/xbl/nsBindingManager.h index d7271a788f72..a2545f374491 100644 --- a/dom/xbl/nsBindingManager.h +++ b/dom/xbl/nsBindingManager.h @@ -25,7 +25,6 @@ class nsIDocument; class nsIURI; class nsXBLDocumentInfo; class nsIStreamListener; -class nsStyleSet; class nsXBLBinding; template class nsRefPtr; typedef nsTArray > nsBindingList; diff --git a/dom/xbl/nsXBLBinding.h b/dom/xbl/nsXBLBinding.h index 00f002500fa1..17ca5eeb429f 100644 --- a/dom/xbl/nsXBLBinding.h +++ b/dom/xbl/nsXBLBinding.h @@ -21,7 +21,6 @@ class nsXBLPrototypeBinding; class nsIContent; class nsIAtom; class nsIDocument; -class nsIScriptContext; namespace mozilla { namespace dom { diff --git a/dom/xbl/nsXBLDocumentInfo.h b/dom/xbl/nsXBLDocumentInfo.h index 67f6588128cd..bcf81b7d1c04 100644 --- a/dom/xbl/nsXBLDocumentInfo.h +++ b/dom/xbl/nsXBLDocumentInfo.h @@ -13,7 +13,6 @@ #include "nsCycleCollectionParticipant.h" class nsXBLPrototypeBinding; -class nsXBLDocGlobalObject; class nsXBLDocumentInfo final : public nsSupportsWeakReference { diff --git a/dom/xbl/nsXBLProtoImplField.h b/dom/xbl/nsXBLProtoImplField.h index 04da70a96ef7..13c0fa95b98d 100644 --- a/dom/xbl/nsXBLProtoImplField.h +++ b/dom/xbl/nsXBLProtoImplField.h @@ -14,7 +14,6 @@ class nsIObjectInputStream; class nsIObjectOutputStream; -class nsIScriptContext; class nsIURI; class nsXBLProtoImplField diff --git a/dom/xbl/nsXBLProtoImplMember.h b/dom/xbl/nsXBLProtoImplMember.h index 0de828b3804a..83654863dece 100644 --- a/dom/xbl/nsXBLProtoImplMember.h +++ b/dom/xbl/nsXBLProtoImplMember.h @@ -13,7 +13,6 @@ #include "nsContentUtils.h" // For NS_CONTENT_DELETE_LIST_MEMBER. #include "nsCycleCollectionParticipant.h" -class nsIContent; class nsIObjectOutputStream; struct nsXBLTextWithLineNumber diff --git a/dom/xslt/xpath/XPathExpression.h b/dom/xslt/xpath/XPathExpression.h index a45ad66f3359..8bd9b59764ff 100644 --- a/dom/xslt/xpath/XPathExpression.h +++ b/dom/xslt/xpath/XPathExpression.h @@ -17,7 +17,6 @@ class Expr; class nsIDocument; class nsINode; class txResultRecycler; -class txXPathNode; namespace mozilla { namespace dom { diff --git a/dom/xslt/xpath/txExpr.h b/dom/xslt/xpath/txExpr.h index a24f78d1b960..474a459a9eff 100644 --- a/dom/xslt/xpath/txExpr.h +++ b/dom/xslt/xpath/txExpr.h @@ -24,7 +24,6 @@ */ class nsIAtom; -class txIParseContext; class txIMatchContext; class txIEvalContext; class txNodeSet; diff --git a/dom/xslt/xpath/txExprParser.h b/dom/xslt/xpath/txExprParser.h index 8c0160bda0fe..238e03399721 100644 --- a/dom/xslt/xpath/txExprParser.h +++ b/dom/xslt/xpath/txExprParser.h @@ -16,7 +16,6 @@ #include "nsAutoPtr.h" #include "nsString.h" -class AttributeValueTemplate; class Expr; class txExprLexer; class FunctionCall; @@ -26,7 +25,6 @@ class PredicateList; class Token; class txIParseContext; class txNodeTest; -class txNodeTypeTest; class txExprParser { diff --git a/dom/xslt/xslt/txBufferingHandler.h b/dom/xslt/xslt/txBufferingHandler.h index 5d4ddba76c31..4d38f3c6f861 100644 --- a/dom/xslt/xslt/txBufferingHandler.h +++ b/dom/xslt/xslt/txBufferingHandler.h @@ -12,7 +12,6 @@ #include "nsAutoPtr.h" class txOutputTransaction; -class txCharacterTransaction; class txResultBuffer { diff --git a/dom/xslt/xslt/txExecutionState.h b/dom/xslt/xslt/txExecutionState.h index a331fb669e08..1f6361930940 100644 --- a/dom/xslt/xslt/txExecutionState.h +++ b/dom/xslt/xslt/txExecutionState.h @@ -21,7 +21,6 @@ class txAOutputHandlerFactory; class txAXMLEventHandler; class txInstruction; -class txIOutputHandlerFactory; class txLoadedDocumentEntry : public nsStringHashKey { diff --git a/dom/xslt/xslt/txMozillaTextOutput.h b/dom/xslt/xslt/txMozillaTextOutput.h index 561d8bdf81be..14f03ab99a45 100644 --- a/dom/xslt/xslt/txMozillaTextOutput.h +++ b/dom/xslt/xslt/txMozillaTextOutput.h @@ -11,7 +11,6 @@ #include "nsWeakPtr.h" #include "txOutputFormat.h" -class nsIDOMCharacterData; class nsIDOMDocument; class nsIDOMDocumentFragment; class nsITransformObserver; diff --git a/dom/xslt/xslt/txMozillaXMLOutput.h b/dom/xslt/xslt/txMozillaXMLOutput.h index 75732d596f31..70156fc182a1 100644 --- a/dom/xslt/xslt/txMozillaXMLOutput.h +++ b/dom/xslt/xslt/txMozillaXMLOutput.h @@ -20,9 +20,6 @@ class nsIContent; class nsIDOMDocument; class nsIAtom; class nsIDOMDocumentFragment; -class nsIDOMElement; -class nsIStyleSheet; -class nsIDOMNode; class nsITransformObserver; class nsNodeInfoManager; class nsIDocument; diff --git a/dom/xslt/xslt/txMozillaXSLTProcessor.h b/dom/xslt/xslt/txMozillaXSLTProcessor.h index 11ab8b2c3d59..c8a70befe7e1 100644 --- a/dom/xslt/xslt/txMozillaXSLTProcessor.h +++ b/dom/xslt/xslt/txMozillaXSLTProcessor.h @@ -22,7 +22,6 @@ class nsINode; class nsIDOMNode; class nsIURI; -class nsIXMLContentSink; class txStylesheet; class txResultRecycler; class txIGlobalParameter; diff --git a/dom/xslt/xslt/txStylesheet.h b/dom/xslt/xslt/txStylesheet.h index 2f8d5a36fa07..978527a13e4d 100644 --- a/dom/xslt/xslt/txStylesheet.h +++ b/dom/xslt/xslt/txStylesheet.h @@ -13,7 +13,6 @@ #include "nsISupportsImpl.h" class txInstruction; -class txToplevelItem; class txTemplateItem; class txVariableItem; class txStripSpaceItem; diff --git a/dom/xslt/xslt/txXSLTFunctions.h b/dom/xslt/xslt/txXSLTFunctions.h index 7433901812f3..9efe4d3dbab4 100644 --- a/dom/xslt/xslt/txXSLTFunctions.h +++ b/dom/xslt/xslt/txXSLTFunctions.h @@ -11,10 +11,7 @@ #include "nsAutoPtr.h" #include "txNamespaceMap.h" -class txPattern; class txStylesheet; -class txKeyValueHashKey; -class txExecutionState; /** * The definition for the XSLT document() function diff --git a/dom/xslt/xslt/txXSLTPatterns.h b/dom/xslt/xslt/txXSLTPatterns.h index 0a6e2a11a02a..d93d54fe0eec 100644 --- a/dom/xslt/xslt/txXSLTPatterns.h +++ b/dom/xslt/xslt/txXSLTPatterns.h @@ -11,8 +11,6 @@ #include "txExpr.h" #include "txXMLUtils.h" -class ProcessorState; - class txPattern { public: diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h index 640508e6f82b..a3e08c2b5fe6 100644 --- a/dom/xul/XULDocument.h +++ b/dom/xul/XULDocument.h @@ -35,7 +35,6 @@ class nsPIWindowRoot; #if 0 // XXXbe save me, scc (need NSCAP_FORWARD_DECL(nsXULPrototypeScript)) class nsIObjectInputStream; class nsIObjectOutputStream; -class nsIXULPrototypeScript; #else #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" diff --git a/dom/xul/nsXULElement.h b/dom/xul/nsXULElement.h index 66b3a3849bad..ac6edc3fd7c5 100644 --- a/dom/xul/nsXULElement.h +++ b/dom/xul/nsXULElement.h @@ -38,7 +38,6 @@ class nsIDocument; class nsString; -class nsIDocShell; class nsXULPrototypeDocument; class nsIObjectInputStream; @@ -365,8 +364,6 @@ ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 3); #undef XUL_ELEMENT_FLAG_BIT -class nsScriptEventHandlerOwnerTearoff; - class nsXULElement final : public nsStyledElement, public nsIDOMXULElement { diff --git a/dom/xul/templates/nsContentTestNode.h b/dom/xul/templates/nsContentTestNode.h index 7eb56a008066..e39c7114acce 100644 --- a/dom/xul/templates/nsContentTestNode.h +++ b/dom/xul/templates/nsContentTestNode.h @@ -12,8 +12,6 @@ #include "nsIAtom.h" #include "nsIDOMDocument.h" -class nsIXULTemplateBuilder; - /** * The nsContentTestNode is always the top node in a query's rule network. It * exists so that Constrain can filter out resources that aren't part of a diff --git a/dom/xul/templates/nsRuleNetwork.h b/dom/xul/templates/nsRuleNetwork.h index d92739d24e06..39fda0041852 100644 --- a/dom/xul/templates/nsRuleNetwork.h +++ b/dom/xul/templates/nsRuleNetwork.h @@ -37,7 +37,6 @@ #include "pldhash.h" #include "nsIRDFNode.h" -class nsIRDFResource; class nsXULTemplateResultSetRDF; class nsXULTemplateQueryProcessorRDF; diff --git a/dom/xul/templates/nsXULContentUtils.h b/dom/xul/templates/nsXULContentUtils.h index 4d027897a1b4..c106fd91ec6e 100644 --- a/dom/xul/templates/nsXULContentUtils.h +++ b/dom/xul/templates/nsXULContentUtils.h @@ -17,10 +17,7 @@ class nsIAtom; class nsIContent; class nsIDocument; -class nsIDOMNodeList; class nsIRDFNode; -class nsCString; -class nsString; class nsIRDFResource; class nsIRDFLiteral; class nsIRDFService; diff --git a/dom/xul/templates/nsXULTemplateBuilder.h b/dom/xul/templates/nsXULTemplateBuilder.h index c68ad4b39e48..98fa63cb4028 100644 --- a/dom/xul/templates/nsXULTemplateBuilder.h +++ b/dom/xul/templates/nsXULTemplateBuilder.h @@ -33,7 +33,6 @@ extern PRLogModuleInfo* gXULTemplateLog; class nsIContent; class nsIObserverService; class nsIRDFCompositeDataSource; -class nsIXULDocument; /** * An object that translates an RDF graph into a presentation using a diff --git a/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h b/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h index aaa4691e5718..65685a34073f 100644 --- a/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h +++ b/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h @@ -34,7 +34,6 @@ extern PRLogModuleInfo* gXULTemplateLog; #endif class nsIContent; -class nsIRDFCompositeDataSource; class nsXULTemplateResultRDF; /** From cb54385682b2df951faacec33dacb1cd075743e3 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 08:29:20 +0200 Subject: [PATCH 084/241] Bug 1156632 - Remove unused forward class declarations - patch 4 - netwerk image and dom, r=ehsan --- caps/DomainPolicy.h | 4 ---- caps/nsJSPrincipals.h | 2 -- caps/nsPrincipal.h | 3 --- caps/nsScriptSecurityManager.h | 3 --- dom/battery/BatteryManager.h | 1 - dom/cache/OfflineStorage.h | 2 -- dom/cache/ReadStream.h | 2 -- dom/camera/GonkCameraControl.h | 3 --- dom/camera/ICameraControl.h | 2 -- dom/canvas/CanvasRenderingContext2D.h | 1 - dom/canvas/CanvasUtils.h | 4 ---- dom/canvas/WebGLContext.h | 2 -- dom/canvas/WebGLFramebuffer.h | 1 - dom/canvas/WebGLObjectModel.h | 1 - dom/canvas/WebGLShaderPrecisionFormat.h | 2 -- dom/canvas/nsICanvasRenderingContextInternal.h | 1 - dom/gamepad/GamepadService.h | 2 -- dom/mobilemessage/MobileMessageCallback.h | 2 -- dom/mobilemessage/ipc/SmsIPCService.h | 2 -- dom/network/TCPServerSocketParent.h | 2 -- dom/network/TCPSocketParent.h | 2 -- dom/offline/nsDOMOfflineResourceList.h | 2 -- dom/plugins/base/android/android_npapi.h | 1 - dom/plugins/base/nsPluginHost.h | 1 - dom/plugins/base/nsPluginInstanceOwner.h | 1 - dom/plugins/base/nsPluginTags.h | 1 - dom/plugins/ipc/PluginInstanceChild.h | 5 ----- dom/plugins/ipc/PluginInstanceParent.h | 3 --- dom/plugins/ipc/PluginModuleChild.h | 1 - dom/plugins/ipc/PluginScriptableObjectParent.h | 1 - dom/quota/Client.h | 1 - dom/quota/QuotaManager.h | 1 - dom/quota/nsIOfflineStorage.h | 2 -- dom/security/nsCORSListenerProxy.h | 1 - dom/vr/VRDevice.h | 2 -- dom/xml/XMLDocument.h | 2 -- dom/xml/nsXMLContentSink.h | 1 - image/encoders/ico/nsICOEncoder.h | 3 --- image/src/DecodePool.h | 1 - image/src/ProgressTracker.h | 1 - image/src/RasterImage.h | 2 -- image/src/SVGDocumentWrapper.h | 1 - image/src/VectorImage.h | 4 ---- ipc/dbus/RawDBusConnection.h | 1 - ipc/glue/GeckoChildProcessHost.h | 2 -- ipc/glue/nsIIPCSerializableInputStream.h | 1 - modules/libjar/nsJAR.h | 1 - modules/libpref/Preferences.h | 2 -- netwerk/base/ChannelDiverterChild.h | 4 ---- netwerk/base/Dashboard.h | 2 -- netwerk/base/Predictor.h | 1 - netwerk/base/nsNativeConnectionHelper.h | 2 -- netwerk/cache/nsDiskCacheStreams.h | 1 - netwerk/cache2/CacheEntry.h | 2 -- netwerk/cache2/CacheFileIOManager.h | 2 -- netwerk/cache2/CacheStorageService.h | 2 -- netwerk/cookie/CookieServiceParent.h | 1 - netwerk/cookie/nsCookieService.h | 1 - netwerk/ipc/ChannelEventQueue.h | 3 --- netwerk/protocol/ftp/FTPChannelParent.h | 1 - netwerk/protocol/http/ASpdySession.h | 2 -- netwerk/protocol/http/HttpChannelParentListener.h | 2 -- netwerk/protocol/http/InterceptedChannel.h | 1 - netwerk/protocol/http/TunnelUtils.h | 1 - netwerk/protocol/http/nsAHttpTransaction.h | 1 - netwerk/protocol/http/nsHttpChannel.h | 1 - netwerk/protocol/rtsp/controller/RtspControllerParent.h | 2 -- netwerk/sctp/datachannel/DataChannel.h | 1 - toolkit/components/jsdownloads/src/DownloadPlatform.h | 3 --- toolkit/components/places/Database.h | 1 - toolkit/components/places/nsNavBookmarks.h | 1 - toolkit/components/places/nsNavHistory.h | 1 - toolkit/components/startup/nsAppStartup.h | 2 -- .../src/tools/mac/crash_report/on_demand_symbol_supplier.h | 1 - toolkit/xre/nsAppRunner.h | 4 ---- uriloader/prefetch/OfflineCacheUpdateParent.h | 4 ---- uriloader/prefetch/nsOfflineCacheUpdate.h | 3 --- uriloader/prefetch/nsPrefetchService.h | 1 - 78 files changed, 143 deletions(-) diff --git a/caps/DomainPolicy.h b/caps/DomainPolicy.h index eea89d476fb8..b0b2a9f8783c 100644 --- a/caps/DomainPolicy.h +++ b/caps/DomainPolicy.h @@ -13,10 +13,6 @@ namespace mozilla { -namespace dom { -class nsIContentParent; -}; - namespace ipc { class URIParams; }; diff --git a/caps/nsJSPrincipals.h b/caps/nsJSPrincipals.h index 5b63574cf436..e53972ff76f5 100644 --- a/caps/nsJSPrincipals.h +++ b/caps/nsJSPrincipals.h @@ -9,8 +9,6 @@ #include "jsapi.h" #include "nsIPrincipal.h" -class nsCString; - struct nsJSPrincipals : nsIPrincipal, JSPrincipals { static bool Subsume(JSPrincipals *jsprin, JSPrincipals *other); diff --git a/caps/nsPrincipal.h b/caps/nsPrincipal.h index 24f9631c38d2..7ef0d8836cc5 100644 --- a/caps/nsPrincipal.h +++ b/caps/nsPrincipal.h @@ -15,9 +15,6 @@ #include "nsNetUtil.h" #include "nsScriptSecurityManager.h" -class nsIObjectInputStream; -class nsIObjectOutputStream; - class nsBasePrincipal : public nsJSPrincipals { public: diff --git a/caps/nsScriptSecurityManager.h b/caps/nsScriptSecurityManager.h index da9b3a299083..6af83712ee23 100644 --- a/caps/nsScriptSecurityManager.h +++ b/caps/nsScriptSecurityManager.h @@ -17,13 +17,10 @@ #include -class nsIDocShell; class nsCString; -class nsIClassInfo; class nsIIOService; class nsIStringBundle; class nsSystemPrincipal; -class ClassInfoData; ///////////////////////////// // nsScriptSecurityManager // diff --git a/dom/battery/BatteryManager.h b/dom/battery/BatteryManager.h index 8fdcc5827939..5eb418aa1e33 100644 --- a/dom/battery/BatteryManager.h +++ b/dom/battery/BatteryManager.h @@ -12,7 +12,6 @@ #include "nsCycleCollectionParticipant.h" class nsPIDOMWindow; -class nsIScriptContext; namespace mozilla { diff --git a/dom/cache/OfflineStorage.h b/dom/cache/OfflineStorage.h index 383f62b60662..51291f545577 100644 --- a/dom/cache/OfflineStorage.h +++ b/dom/cache/OfflineStorage.h @@ -13,8 +13,6 @@ #include "nsIOfflineStorage.h" #include "nsTArray.h" -class nsIThread; - namespace mozilla { namespace dom { namespace cache { diff --git a/dom/cache/ReadStream.h b/dom/cache/ReadStream.h index eaec9bfd1a9b..f4912c407936 100644 --- a/dom/cache/ReadStream.h +++ b/dom/cache/ReadStream.h @@ -15,8 +15,6 @@ #include "nsRefPtr.h" #include "nsTArrayForwardDeclare.h" -class nsIThread; - namespace mozilla { namespace dom { namespace cache { diff --git a/dom/camera/GonkCameraControl.h b/dom/camera/GonkCameraControl.h index 3f589189732d..809b5864e7fb 100644 --- a/dom/camera/GonkCameraControl.h +++ b/dom/camera/GonkCameraControl.h @@ -49,9 +49,6 @@ namespace layers { class ImageContainer; } -class GonkRecorderProfile; -class GonkRecorderProfileManager; - class nsGonkCameraControl : public CameraControlImpl { public: diff --git a/dom/camera/ICameraControl.h b/dom/camera/ICameraControl.h index 6320c0b0a463..c3c9fdfe81f3 100644 --- a/dom/camera/ICameraControl.h +++ b/dom/camera/ICameraControl.h @@ -13,8 +13,6 @@ struct DeviceStorageFileDescriptor; -class nsIFile; - namespace mozilla { class CameraControlListener; diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index 4fd7d5a341e1..0488bbd4088a 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -42,7 +42,6 @@ class ImageData; class StringOrCanvasGradientOrCanvasPattern; class OwningStringOrCanvasGradientOrCanvasPattern; class TextMetrics; -class SVGMatrix; class CanvasFilterChainObserver; class CanvasPath; diff --git a/dom/canvas/CanvasUtils.h b/dom/canvas/CanvasUtils.h index 31347ee651da..1096129370cf 100644 --- a/dom/canvas/CanvasUtils.h +++ b/dom/canvas/CanvasUtils.h @@ -15,10 +15,6 @@ class nsIPrincipal; namespace mozilla { -namespace gfx { -class Matrix; -} - namespace dom { class HTMLCanvasElement; } diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index b6ada05d4261..84b8a3122c8e 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -68,7 +68,6 @@ class nsIDocShell; namespace mozilla { class WebGLActiveInfo; -class WebGLContextBoundObject; class WebGLContextLossHandler; class WebGLBuffer; class WebGLExtensionBase; @@ -84,7 +83,6 @@ class WebGLTexture; class WebGLTransformFeedback; class WebGLUniformLocation; class WebGLVertexArray; -struct WebGLVertexAttribData; namespace dom { class Element; diff --git a/dom/canvas/WebGLFramebuffer.h b/dom/canvas/WebGLFramebuffer.h index 79d95155f827..a4513c1cb108 100644 --- a/dom/canvas/WebGLFramebuffer.h +++ b/dom/canvas/WebGLFramebuffer.h @@ -14,7 +14,6 @@ namespace mozilla { -class WebGLFramebufferAttachable; class WebGLRenderbuffer; class WebGLTexture; diff --git a/dom/canvas/WebGLObjectModel.h b/dom/canvas/WebGLObjectModel.h index 193c419b67e7..311458d36a96 100644 --- a/dom/canvas/WebGLObjectModel.h +++ b/dom/canvas/WebGLObjectModel.h @@ -12,7 +12,6 @@ namespace mozilla { -class WebGLBuffer; class WebGLContext; /* Each WebGL object class WebGLFoo wants to: diff --git a/dom/canvas/WebGLShaderPrecisionFormat.h b/dom/canvas/WebGLShaderPrecisionFormat.h index c7147f4a86a7..1b37dba22e22 100644 --- a/dom/canvas/WebGLShaderPrecisionFormat.h +++ b/dom/canvas/WebGLShaderPrecisionFormat.h @@ -10,8 +10,6 @@ namespace mozilla { -class WebGLBuffer; - class WebGLShaderPrecisionFormat final : public WebGLContextBoundObject { diff --git a/dom/canvas/nsICanvasRenderingContextInternal.h b/dom/canvas/nsICanvasRenderingContextInternal.h index 3b1120f183e0..5134172e1c84 100644 --- a/dom/canvas/nsICanvasRenderingContextInternal.h +++ b/dom/canvas/nsICanvasRenderingContextInternal.h @@ -19,7 +19,6 @@ { 0x3cc9e801, 0x1806, 0x4ff6, \ { 0x86, 0x14, 0xf9, 0xd0, 0xf4, 0xfb, 0x3b, 0x08 } } -class gfxContext; class gfxASurface; class nsDisplayListBuilder; diff --git a/dom/gamepad/GamepadService.h b/dom/gamepad/GamepadService.h index 4225e3c597b0..29e44c0325bc 100644 --- a/dom/gamepad/GamepadService.h +++ b/dom/gamepad/GamepadService.h @@ -16,8 +16,6 @@ #include "nsITimer.h" #include "nsTArray.h" -class nsIDOMDocument; - namespace mozilla { namespace dom { diff --git a/dom/mobilemessage/MobileMessageCallback.h b/dom/mobilemessage/MobileMessageCallback.h index 11c4cae8f914..eb98d44817ca 100644 --- a/dom/mobilemessage/MobileMessageCallback.h +++ b/dom/mobilemessage/MobileMessageCallback.h @@ -10,8 +10,6 @@ #include "nsCOMPtr.h" #include "DOMRequest.h" -class nsIDOMMozMmsMessage; - namespace mozilla { namespace dom { namespace mobilemessage { diff --git a/dom/mobilemessage/ipc/SmsIPCService.h b/dom/mobilemessage/ipc/SmsIPCService.h index c8884a1ae523..c8e76d99f03f 100644 --- a/dom/mobilemessage/ipc/SmsIPCService.h +++ b/dom/mobilemessage/ipc/SmsIPCService.h @@ -16,8 +16,6 @@ namespace mozilla { namespace dom { namespace mobilemessage { -class PSmsChild; - class SmsIPCService final : public nsISmsService , public nsIMmsService , public nsIMobileMessageDatabaseService diff --git a/dom/network/TCPServerSocketParent.h b/dom/network/TCPServerSocketParent.h index db9512f0a96b..74402de0ebb5 100644 --- a/dom/network/TCPServerSocketParent.h +++ b/dom/network/TCPServerSocketParent.h @@ -13,8 +13,6 @@ namespace mozilla { namespace dom { -class PBrowserParent; - class TCPServerSocketParent : public mozilla::net::PTCPServerSocketParent , public nsITCPServerSocketParent { diff --git a/dom/network/TCPSocketParent.h b/dom/network/TCPSocketParent.h index 8a543eaac3aa..439c46be34b2 100644 --- a/dom/network/TCPSocketParent.h +++ b/dom/network/TCPSocketParent.h @@ -19,8 +19,6 @@ namespace mozilla { namespace dom { -class PBrowserParent; - class TCPSocketParentBase : public nsITCPSocketParent , public mozilla::net::DisconnectableParent { diff --git a/dom/offline/nsDOMOfflineResourceList.h b/dom/offline/nsDOMOfflineResourceList.h index 7c5c8cfaeef1..2c33f8e79d55 100644 --- a/dom/offline/nsDOMOfflineResourceList.h +++ b/dom/offline/nsDOMOfflineResourceList.h @@ -26,8 +26,6 @@ #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/ErrorResult.h" -class nsIDOMWindow; - namespace mozilla { namespace dom { class DOMStringList; diff --git a/dom/plugins/base/android/android_npapi.h b/dom/plugins/base/android/android_npapi.h index 2f86a6fa0461..ea7d772bb829 100644 --- a/dom/plugins/base/android/android_npapi.h +++ b/dom/plugins/base/android/android_npapi.h @@ -87,7 +87,6 @@ struct ANPCanvas; struct ANPMatrix; struct ANPPaint; struct ANPPath; -struct ANPRegion; struct ANPTypeface; enum ANPMatrixFlags { diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h index 7e0727017ee0..4966135320e4 100644 --- a/dom/plugins/base/nsPluginHost.h +++ b/dom/plugins/base/nsPluginHost.h @@ -41,7 +41,6 @@ class PluginTag; } // namespace plugins class nsNPAPIPlugin; -class nsIComponentManager; class nsIFile; class nsIChannel; class nsPluginNativeWindow; diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index 2101d3900998..5ed489b57f81 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -40,7 +40,6 @@ class PuppetWidget; using mozilla::widget::PuppetWidget; #ifdef MOZ_X11 -class gfxXlibSurface; #ifdef MOZ_WIDGET_QT #include "gfxQtNativeRenderer.h" #else diff --git a/dom/plugins/base/nsPluginTags.h b/dom/plugins/base/nsPluginTags.h index a51d909fd7b4..86015c7e37b5 100644 --- a/dom/plugins/base/nsPluginTags.h +++ b/dom/plugins/base/nsPluginTags.h @@ -15,7 +15,6 @@ #include "nsITimer.h" #include "nsString.h" -class nsPluginHost; struct PRLibrary; struct nsPluginInfo; class nsNPAPIPlugin; diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index c878616b8a66..04eaf2aacdd8 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -40,11 +40,6 @@ class gfxASurface; namespace mozilla { - -namespace layers { -struct RemoteImageData; -} - namespace plugins { class PBrowserStreamChild; diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index afeb190a7b87..fc740774a7aa 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -24,9 +24,6 @@ #include "nsRect.h" #include "PluginDataResolver.h" -#ifdef MOZ_X11 -class gfxXlibSurface; -#endif #include "mozilla/unused.h" class gfxASurface; diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index 8b63316201f1..ded7f426a44b 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -57,7 +57,6 @@ class NestedLoopTimer; static const int kNestedLoopDetectorIntervalMs = 90; #endif -class PluginScriptableObjectChild; class PluginInstanceChild; class PluginModuleChild : public PPluginModuleChild diff --git a/dom/plugins/ipc/PluginScriptableObjectParent.h b/dom/plugins/ipc/PluginScriptableObjectParent.h index 6372eb0ff75d..0b75152bf18d 100644 --- a/dom/plugins/ipc/PluginScriptableObjectParent.h +++ b/dom/plugins/ipc/PluginScriptableObjectParent.h @@ -16,7 +16,6 @@ namespace mozilla { namespace plugins { -class PluginAsyncSurrogate; class PluginInstanceParent; class PluginScriptableObjectParent; diff --git a/dom/quota/Client.h b/dom/quota/Client.h index 5502cca84b8a..b66735e2d226 100644 --- a/dom/quota/Client.h +++ b/dom/quota/Client.h @@ -20,7 +20,6 @@ class nsIRunnable; BEGIN_QUOTA_NAMESPACE -class OriginOrPatternString; class UsageInfo; // An abstract interface for quota manager clients. diff --git a/dom/quota/QuotaManager.h b/dom/quota/QuotaManager.h index 86dc8ad259ac..af81eff7ba31 100644 --- a/dom/quota/QuotaManager.h +++ b/dom/quota/QuotaManager.h @@ -40,7 +40,6 @@ class ContentParent; BEGIN_QUOTA_NAMESPACE -class AcquireListener; class AsyncUsageRunnable; class CollectOriginsHelper; class FinalizeOriginEvictionRunnable; diff --git a/dom/quota/nsIOfflineStorage.h b/dom/quota/nsIOfflineStorage.h index 987528590f3e..8466fbd3be9d 100644 --- a/dom/quota/nsIOfflineStorage.h +++ b/dom/quota/nsIOfflineStorage.h @@ -12,8 +12,6 @@ #define NS_OFFLINESTORAGE_IID \ {0x91c57bf2, 0x0eda, 0x4db6, {0x9f, 0xf6, 0xcb, 0x38, 0x26, 0x8d, 0xb3, 0x01}} -class nsPIDOMWindow; - namespace mozilla { namespace dom { diff --git a/dom/security/nsCORSListenerProxy.h b/dom/security/nsCORSListenerProxy.h index 46ef16bc5788..a2a200c5abce 100644 --- a/dom/security/nsCORSListenerProxy.h +++ b/dom/security/nsCORSListenerProxy.h @@ -18,7 +18,6 @@ #include "mozilla/Attributes.h" class nsIURI; -class nsIParser; class nsIPrincipal; class nsINetworkInterceptController; diff --git a/dom/vr/VRDevice.h b/dom/vr/VRDevice.h index ab4f549cc696..40ab7e359089 100644 --- a/dom/vr/VRDevice.h +++ b/dom/vr/VRDevice.h @@ -24,8 +24,6 @@ namespace mozilla { namespace dom { -class Element; - class VRFieldOfViewReadOnly : public nsWrapperCache { public: diff --git a/dom/xml/XMLDocument.h b/dom/xml/XMLDocument.h index 1fa9623e2e61..fe55f2199db3 100644 --- a/dom/xml/XMLDocument.h +++ b/dom/xml/XMLDocument.h @@ -11,8 +11,6 @@ #include "nsIDOMXMLDocument.h" #include "nsIScriptContext.h" -class nsIParser; -class nsIDOMNode; class nsIURI; class nsIChannel; diff --git a/dom/xml/nsXMLContentSink.h b/dom/xml/nsXMLContentSink.h index 6b42c9ff1820..01f1a3aceb42 100644 --- a/dom/xml/nsXMLContentSink.h +++ b/dom/xml/nsXMLContentSink.h @@ -22,7 +22,6 @@ class nsIDocument; class nsIURI; class nsIContent; class nsIParser; -class nsViewManager; namespace mozilla { namespace dom { diff --git a/image/encoders/ico/nsICOEncoder.h b/image/encoders/ico/nsICOEncoder.h index ffa5cb138d4b..9bf9b49f5845 100644 --- a/image/encoders/ico/nsICOEncoder.h +++ b/image/encoders/ico/nsICOEncoder.h @@ -14,9 +14,6 @@ #include "nsCOMPtr.h" #include "ICOFileHeaders.h" -class nsBMPEncoder; -class nsPNGEncoder; - #define NS_ICOENCODER_CID \ { /*92AE3AB2-8968-41B1-8709-B6123BCEAF21 */ \ 0x92ae3ab2, \ diff --git a/image/src/DecodePool.h b/image/src/DecodePool.h index 42a690b3b376..4145f7ddb3f9 100644 --- a/image/src/DecodePool.h +++ b/image/src/DecodePool.h @@ -23,7 +23,6 @@ namespace mozilla { namespace image { class Decoder; -class RasterImage; /** * DecodePool is a singleton class that manages decoding of raster images. It diff --git a/image/src/ProgressTracker.h b/image/src/ProgressTracker.h index 099201b70aff..3f4ed024e4dd 100644 --- a/image/src/ProgressTracker.h +++ b/image/src/ProgressTracker.h @@ -15,7 +15,6 @@ #include "nsRect.h" #include "IProgressObserver.h" -class imgIContainer; class nsIRunnable; namespace mozilla { diff --git a/image/src/RasterImage.h b/image/src/RasterImage.h index 591bb5fda950..574747d19bf6 100644 --- a/image/src/RasterImage.h +++ b/image/src/RasterImage.h @@ -39,7 +39,6 @@ #endif class nsIInputStream; -class nsIThreadPool; class nsIRequest; #define NS_RASTERIMAGE_CID \ @@ -123,7 +122,6 @@ class nsIRequest; namespace mozilla { namespace layers { -class LayerManager; class ImageContainer; class Image; } diff --git a/image/src/SVGDocumentWrapper.h b/image/src/SVGDocumentWrapper.h index 64dcb0b37972..41040ef2adf8 100644 --- a/image/src/SVGDocumentWrapper.h +++ b/image/src/SVGDocumentWrapper.h @@ -17,7 +17,6 @@ #include "nsWeakReference.h" #include "nsSize.h" -class nsIAtom; class nsIPresShell; class nsIRequest; class nsILoadGroup; diff --git a/image/src/VectorImage.h b/image/src/VectorImage.h index d2f465d9db98..3282fbe6c6a5 100644 --- a/image/src/VectorImage.h +++ b/image/src/VectorImage.h @@ -14,10 +14,6 @@ class nsIRequest; class gfxDrawable; namespace mozilla { -namespace layers { -class LayerManager; -class ImageContainer; -} namespace image { struct SVGDrawingParameters; diff --git a/ipc/dbus/RawDBusConnection.h b/ipc/dbus/RawDBusConnection.h index 05e8cbcf8b54..20c80f469e8d 100644 --- a/ipc/dbus/RawDBusConnection.h +++ b/ipc/dbus/RawDBusConnection.h @@ -10,7 +10,6 @@ #include "mozilla/Scoped.h" struct DBusConnection; -struct DBusError; struct DBusMessage; namespace mozilla { diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h index ff4d9c68114f..76728058b5b7 100644 --- a/ipc/glue/GeckoChildProcessHost.h +++ b/ipc/glue/GeckoChildProcessHost.h @@ -23,8 +23,6 @@ #include "sandboxBroker.h" #endif -class nsIFile; - namespace mozilla { namespace ipc { diff --git a/ipc/glue/nsIIPCSerializableInputStream.h b/ipc/glue/nsIIPCSerializableInputStream.h index 0c4b48162caf..acfccd1ffd6d 100644 --- a/ipc/glue/nsIIPCSerializableInputStream.h +++ b/ipc/glue/nsIIPCSerializableInputStream.h @@ -8,7 +8,6 @@ #include "nsISupports.h" #include "mozilla/Attributes.h" -struct nsTArrayDefaultAllocator; template class nsTArray; namespace mozilla { diff --git a/modules/libjar/nsJAR.h b/modules/libjar/nsJAR.h index 167054a2f490..26c5a57c444d 100644 --- a/modules/libjar/nsJAR.h +++ b/modules/libjar/nsJAR.h @@ -30,7 +30,6 @@ #include "mozilla/Attributes.h" class nsIX509Cert; -class nsIInputStream; class nsJARManifestItem; class nsZipReaderCache; diff --git a/modules/libpref/Preferences.h b/modules/libpref/Preferences.h index 4a8f03e3696b..6c5c6190716c 100644 --- a/modules/libpref/Preferences.h +++ b/modules/libpref/Preferences.h @@ -20,8 +20,6 @@ #include "mozilla/MemoryReporting.h" class nsIFile; -class nsCString; -class nsString; class nsAdoptingString; class nsAdoptingCString; diff --git a/netwerk/base/ChannelDiverterChild.h b/netwerk/base/ChannelDiverterChild.h index 529ae1da5aa1..a92de2f11019 100644 --- a/netwerk/base/ChannelDiverterChild.h +++ b/netwerk/base/ChannelDiverterChild.h @@ -9,13 +9,9 @@ #include "mozilla/net/PChannelDiverterChild.h" -class nsIDivertableChannel; - namespace mozilla { namespace net { -class ChannelDiverterArgs; - class ChannelDiverterChild : public PChannelDiverterChild { diff --git a/netwerk/base/Dashboard.h b/netwerk/base/Dashboard.h index ca241639567d..2bf3abe32981 100644 --- a/netwerk/base/Dashboard.h +++ b/netwerk/base/Dashboard.h @@ -15,8 +15,6 @@ #include "nsITransport.h" class nsIDNSService; -class nsISocketTransport; -class nsIThread; namespace mozilla { namespace net { diff --git a/netwerk/base/Predictor.h b/netwerk/base/Predictor.h index 2f030c959961..0e29e47fa583 100644 --- a/netwerk/base/Predictor.h +++ b/netwerk/base/Predictor.h @@ -26,7 +26,6 @@ class nsICacheStorage; class nsIDNSService; class nsIIOService; class nsINetworkPredictorVerifier; -class nsIThread; class nsITimer; namespace mozilla { diff --git a/netwerk/base/nsNativeConnectionHelper.h b/netwerk/base/nsNativeConnectionHelper.h index e86852d412b4..728d73e9f8ae 100644 --- a/netwerk/base/nsNativeConnectionHelper.h +++ b/netwerk/base/nsNativeConnectionHelper.h @@ -7,8 +7,6 @@ #include "nscore.h" -class nsISocketTransport; - class nsNativeConnectionHelper { public: diff --git a/netwerk/cache/nsDiskCacheStreams.h b/netwerk/cache/nsDiskCacheStreams.h index 5017eed8072b..247c16a6efd0 100644 --- a/netwerk/cache/nsDiskCacheStreams.h +++ b/netwerk/cache/nsDiskCacheStreams.h @@ -18,7 +18,6 @@ #include "mozilla/Atomics.h" -class nsDiskCacheInputStream; class nsDiskCacheDevice; class nsDiskCacheStreamIO : public nsIOutputStream { diff --git a/netwerk/cache2/CacheEntry.h b/netwerk/cache2/CacheEntry.h index e38f9e54e8ba..98a0f5bbd92c 100644 --- a/netwerk/cache2/CacheEntry.h +++ b/netwerk/cache2/CacheEntry.h @@ -33,7 +33,6 @@ PRTimeToSeconds(PRTime t_usec) #define NowInSeconds() PRTimeToSeconds(PR_Now()) -class nsIStorageStream; class nsIOutputStream; class nsIURI; class nsIThread; @@ -43,7 +42,6 @@ namespace net { class CacheStorageService; class CacheStorage; -class CacheFileOutputStream; class CacheOutputCloseListener; class CacheEntryHandle; diff --git a/netwerk/cache2/CacheFileIOManager.h b/netwerk/cache2/CacheFileIOManager.h index 8ca9eb45aab0..4afae6665613 100644 --- a/netwerk/cache2/CacheFileIOManager.h +++ b/netwerk/cache2/CacheFileIOManager.h @@ -23,7 +23,6 @@ class nsIFile; class nsITimer; class nsIDirectoryEnumerator; class nsILoadContextInfo; -class nsICacheStorageVisitor; namespace mozilla { namespace net { @@ -174,7 +173,6 @@ private: //////////////////////////////////////////////////////////////////////////////// class OpenFileEvent; -class CloseFileEvent; class ReadEvent; class WriteEvent; class MetadataWriteScheduleEvent; diff --git a/netwerk/cache2/CacheStorageService.h b/netwerk/cache2/CacheStorageService.h index fb07a4dffd7f..52e84ba2fb57 100644 --- a/netwerk/cache2/CacheStorageService.h +++ b/netwerk/cache2/CacheStorageService.h @@ -20,7 +20,6 @@ #include "nsTArray.h" class nsIURI; -class nsICacheEntryOpenCallback; class nsICacheEntryDoomCallback; class nsICacheStorageVisitor; class nsIRunnable; @@ -34,7 +33,6 @@ class CacheStorageService; class CacheStorage; class CacheEntry; class CacheEntryHandle; -class CacheEntryTable; class CacheMemoryConsumer { diff --git a/netwerk/cookie/CookieServiceParent.h b/netwerk/cookie/CookieServiceParent.h index bbc092b16605..e449a30dc327 100644 --- a/netwerk/cookie/CookieServiceParent.h +++ b/netwerk/cookie/CookieServiceParent.h @@ -10,7 +10,6 @@ #include "SerializedLoadContext.h" class nsCookieService; -class nsIIOService; namespace mozilla { namespace net { diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h index 1e486e912e35..f92d829169dc 100644 --- a/netwerk/cookie/nsCookieService.h +++ b/netwerk/cookie/nsCookieService.h @@ -42,7 +42,6 @@ class ReadCookieDBListener; struct nsCookieAttributes; struct nsListIter; -struct nsEnumerationData; namespace mozilla { namespace net { diff --git a/netwerk/ipc/ChannelEventQueue.h b/netwerk/ipc/ChannelEventQueue.h index 2410023512ed..ec94c70a4e39 100644 --- a/netwerk/ipc/ChannelEventQueue.h +++ b/netwerk/ipc/ChannelEventQueue.h @@ -13,7 +13,6 @@ class nsISupports; class nsIEventTarget; -class nsIThread; namespace mozilla { namespace net { @@ -33,8 +32,6 @@ class ChannelEvent // instance) to be dispatched and called before mListener->OnStartRequest has // completed. -class AutoEventEnqueuerBase; - class ChannelEventQueue final { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChannelEventQueue) diff --git a/netwerk/protocol/ftp/FTPChannelParent.h b/netwerk/protocol/ftp/FTPChannelParent.h index 8188a26d699e..e47368982161 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.h +++ b/netwerk/protocol/ftp/FTPChannelParent.h @@ -15,7 +15,6 @@ #include "nsIInterfaceRequestor.h" #include "OfflineObserver.h" -class nsFtpChannel; class nsILoadContext; namespace mozilla { diff --git a/netwerk/protocol/http/ASpdySession.h b/netwerk/protocol/http/ASpdySession.h index 92831119670b..c7fbd0802522 100644 --- a/netwerk/protocol/http/ASpdySession.h +++ b/netwerk/protocol/http/ASpdySession.h @@ -15,8 +15,6 @@ class nsISocketTransport; namespace mozilla { namespace net { -class nsHttpConnectionInfo; - class ASpdySession : public nsAHttpTransaction { public: diff --git a/netwerk/protocol/http/HttpChannelParentListener.h b/netwerk/protocol/http/HttpChannelParentListener.h index fcf5356125ac..f7fa16d14cbb 100644 --- a/netwerk/protocol/http/HttpChannelParentListener.h +++ b/netwerk/protocol/http/HttpChannelParentListener.h @@ -12,8 +12,6 @@ #include "nsIChannelEventSink.h" #include "nsIRedirectResultListener.h" -class nsIParentChannel; - namespace mozilla { namespace net { diff --git a/netwerk/protocol/http/InterceptedChannel.h b/netwerk/protocol/http/InterceptedChannel.h index 4ca235edf022..c98d78a12ecc 100644 --- a/netwerk/protocol/http/InterceptedChannel.h +++ b/netwerk/protocol/http/InterceptedChannel.h @@ -13,7 +13,6 @@ class nsICacheEntry; class nsInputStreamPump; -class nsIStorageStream; class nsIStreamListener; namespace mozilla { diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h index 61ccd08f3248..19f976c5847c 100644 --- a/netwerk/protocol/http/TunnelUtils.h +++ b/netwerk/protocol/http/TunnelUtils.h @@ -174,7 +174,6 @@ class SocketTransportShim; class InputStreamShim; class OutputStreamShim; class nsHttpConnection; -class ASpdySession; class SpdyConnectTransaction final : public NullHttpTransaction { diff --git a/netwerk/protocol/http/nsAHttpTransaction.h b/netwerk/protocol/http/nsAHttpTransaction.h index dcd2b5d33233..5c71831d428e 100644 --- a/netwerk/protocol/http/nsAHttpTransaction.h +++ b/netwerk/protocol/http/nsAHttpTransaction.h @@ -10,7 +10,6 @@ #include "nsWeakReference.h" class nsIInterfaceRequestor; -class nsIEventTarget; class nsITransport; class nsILoadGroupConnectionInfo; diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 58ee0f9c0dc7..5cce4f50ebaf 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -23,7 +23,6 @@ #include "TimingStruct.h" #include "AutoClose.h" -class nsIPrincipal; class nsDNSPrefetch; class nsICancelable; class nsIHttpChannelAuthProvider; diff --git a/netwerk/protocol/rtsp/controller/RtspControllerParent.h b/netwerk/protocol/rtsp/controller/RtspControllerParent.h index c78ccb9f8ddb..04c5c5dd0b2a 100644 --- a/netwerk/protocol/rtsp/controller/RtspControllerParent.h +++ b/netwerk/protocol/rtsp/controller/RtspControllerParent.h @@ -15,8 +15,6 @@ #include "nsCOMPtr.h" #include "nsString.h" -class nsIAuthPromptProvider; - namespace mozilla { namespace net { diff --git a/netwerk/sctp/datachannel/DataChannel.h b/netwerk/sctp/datachannel/DataChannel.h index 48dbb4c50570..385220b61ff9 100644 --- a/netwerk/sctp/datachannel/DataChannel.h +++ b/netwerk/sctp/datachannel/DataChannel.h @@ -48,7 +48,6 @@ extern "C" { namespace mozilla { -class DTLSConnection; class DataChannelConnection; class DataChannel; class DataChannelOnMessageAvailable; diff --git a/toolkit/components/jsdownloads/src/DownloadPlatform.h b/toolkit/components/jsdownloads/src/DownloadPlatform.h index b508c12d07cc..75e3b8d571f6 100644 --- a/toolkit/components/jsdownloads/src/DownloadPlatform.h +++ b/toolkit/components/jsdownloads/src/DownloadPlatform.h @@ -9,9 +9,6 @@ #include "nsCOMPtr.h" -class nsIURI; -class nsIFile; - class DownloadPlatform : public mozIDownloadPlatform { protected: diff --git a/toolkit/components/places/Database.h b/toolkit/components/places/Database.h index 7844833c58ff..daf7500deb28 100644 --- a/toolkit/components/places/Database.h +++ b/toolkit/components/places/Database.h @@ -43,7 +43,6 @@ // Fired when the connection has gone, nothing will work from now on. #define TOPIC_PLACES_CONNECTION_CLOSED "places-connection-closed" -class nsIStringBundle; class nsIRunnable; namespace mozilla { diff --git a/toolkit/components/places/nsNavBookmarks.h b/toolkit/components/places/nsNavBookmarks.h index 3db327519c56..ee65d69a5f8b 100644 --- a/toolkit/components/places/nsNavBookmarks.h +++ b/toolkit/components/places/nsNavBookmarks.h @@ -18,7 +18,6 @@ #include "prtime.h" class nsNavBookmarks; -class nsIOutputStream; namespace mozilla { namespace places { diff --git a/toolkit/components/places/nsNavHistory.h b/toolkit/components/places/nsNavHistory.h index d21a5b3b0a3a..536d2ee8faa8 100644 --- a/toolkit/components/places/nsNavHistory.h +++ b/toolkit/components/places/nsNavHistory.h @@ -51,7 +51,6 @@ // Fired after frecency has been updated. #define TOPIC_FRECENCY_UPDATED "places-frecency-updated" -class mozIAnnotationService; class nsNavHistory; class QueryKeyValuePair; class nsIEffectiveTLDService; diff --git a/toolkit/components/startup/nsAppStartup.h b/toolkit/components/startup/nsAppStartup.h index d251b01dbff2..05abce4ca120 100644 --- a/toolkit/components/startup/nsAppStartup.h +++ b/toolkit/components/startup/nsAppStartup.h @@ -22,8 +22,6 @@ #endif //defined(XP_WIN) -struct PLEvent; - // {7DD4D320-C84B-4624-8D45-7BB9B2356977} #define NS_TOOLKIT_APPSTARTUP_CID \ { 0x7dd4d320, 0xc84b, 0x4624, { 0x8d, 0x45, 0x7b, 0xb9, 0xb2, 0x35, 0x69, 0x77 } } diff --git a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h index 28002c6bb21f..704eba21413b 100644 --- a/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h +++ b/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h @@ -41,7 +41,6 @@ namespace google_breakpad { using std::map; using std::string; -class MinidumpModule; class OnDemandSymbolSupplier : public SymbolSupplier { public: diff --git a/toolkit/xre/nsAppRunner.h b/toolkit/xre/nsAppRunner.h index 0aeef9d7e4a1..1295144c7008 100644 --- a/toolkit/xre/nsAppRunner.h +++ b/toolkit/xre/nsAppRunner.h @@ -32,11 +32,7 @@ // and we load localstore from somewhere else. #define NS_LOCALSTORE_UNSAFE_FILE "LStoreS" -class nsACString; -struct nsStaticModuleInfo; - class nsINativeAppSupport; -class nsICmdLineService; class nsXREDirProvider; class nsIToolkitProfileService; class nsIFile; diff --git a/uriloader/prefetch/OfflineCacheUpdateParent.h b/uriloader/prefetch/OfflineCacheUpdateParent.h index 3300d6992865..3cf907744850 100644 --- a/uriloader/prefetch/OfflineCacheUpdateParent.h +++ b/uriloader/prefetch/OfflineCacheUpdateParent.h @@ -14,10 +14,6 @@ namespace mozilla { -namespace dom { -class TabParent; -} - namespace ipc { class URIParams; } // namespace ipc diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.h b/uriloader/prefetch/nsOfflineCacheUpdate.h index 77b169c222ea..40f5a05bf085 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.h +++ b/uriloader/prefetch/nsOfflineCacheUpdate.h @@ -36,9 +36,6 @@ class nsOfflineCacheUpdate; -class nsIUTF8StringEnumerator; -class nsILoadContext; - class nsOfflineCacheUpdateItem : public nsIStreamListener , public nsIRunnable , public nsIInterfaceRequestor diff --git a/uriloader/prefetch/nsPrefetchService.h b/uriloader/prefetch/nsPrefetchService.h index 0ac2636d94e1..0ae2f5264fe7 100644 --- a/uriloader/prefetch/nsPrefetchService.h +++ b/uriloader/prefetch/nsPrefetchService.h @@ -20,7 +20,6 @@ #include "mozilla/Attributes.h" class nsPrefetchService; -class nsPrefetchListener; class nsPrefetchNode; //----------------------------------------------------------------------------- From 085da9302a6660f4eb8d8cce3462395b70a6f769 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 08:29:22 +0200 Subject: [PATCH 085/241] Bug 1156632 - Remove unused forward class declarations - patch 5 - rdf, parser, layout and something else, r=ehsan --- accessible/atk/InterfaceInitFuncs.h | 2 -- accessible/generic/Accessible.h | 2 -- accessible/generic/DocAccessible.h | 2 -- accessible/generic/ImageAccessible.h | 2 -- accessible/html/HTMLSelectAccessible.h | 2 -- accessible/html/HTMLTableAccessible.h | 1 - .../interfaces/nsIAccessibilityService.h | 4 ---- accessible/mac/RootAccessibleWrap.h | 2 -- accessible/windows/msaa/nsWinUtils.h | 1 - accessible/xul/XULListboxAccessible.h | 2 -- dom/xul/templates/nsContentTestNode.h | 2 ++ dom/xul/templates/nsRDFQuery.h | 2 ++ dom/xul/templates/nsRuleNetwork.h | 1 - editor/libeditor/PlaceholderTxn.h | 2 -- editor/libeditor/nsEditor.h | 3 --- editor/libeditor/nsHTMLCSSUtils.h | 1 - editor/libeditor/nsHTMLEditor.h | 2 -- editor/libeditor/nsHTMLEditorEventListener.h | 1 - editor/libeditor/nsIAbsorbingTransaction.h | 1 - editor/libeditor/nsPlaintextEditor.h | 2 -- editor/libeditor/nsTextEditUtils.h | 6 ------ editor/libeditor/nsWSRunObject.h | 1 - editor/txmgr/nsTransactionManager.h | 1 - embedding/browser/nsWebBrowser.h | 2 -- embedding/components/find/nsFind.h | 1 - .../printingui/mac/nsPrintingPromptService.h | 4 ---- .../windowwatcher/nsWindowWatcher.h | 3 --- .../spellcheck/src/mozInlineSpellChecker.h | 1 - layout/base/DisplayItemClip.h | 1 - layout/base/FrameLayerBuilder.h | 2 -- layout/base/GeometryUtils.h | 1 - layout/base/SelectionCarets.h | 5 ----- layout/base/nsCSSFrameConstructor.h | 3 --- layout/base/nsIDocumentViewerPrint.h | 1 - layout/base/nsIPresShell.h | 1 - layout/base/nsLayoutUtils.h | 2 -- layout/base/nsPresContext.h | 5 ----- layout/base/nsPresShell.h | 1 - layout/base/nsRefreshDriver.h | 1 - layout/build/nsContentDLF.h | 2 -- layout/forms/nsFileControlFrame.h | 1 - layout/forms/nsListControlFrame.h | 2 -- layout/forms/nsProgressFrame.h | 2 -- layout/forms/nsRangeFrame.h | 1 - layout/generic/ScrollbarActivity.h | 1 - layout/generic/TextOverflow.h | 1 - layout/generic/nsBlockFrame.h | 1 - layout/generic/nsBlockReflowContext.h | 2 -- layout/generic/nsFrame.h | 1 - layout/generic/nsFrameSelection.h | 1 - layout/generic/nsGfxScrollFrame.h | 1 - layout/generic/nsHTMLParts.h | 2 -- layout/generic/nsIAnonymousContentCreator.h | 1 - layout/generic/nsIFrame.h | 2 -- layout/generic/nsPluginFrame.h | 1 - layout/generic/nsRubyFrame.h | 1 - layout/inspector/inLayoutUtils.h | 4 ---- layout/inspector/nsFontFace.h | 1 - layout/printing/nsPrintEngine.h | 2 -- layout/style/AnimationCommon.h | 1 - layout/style/CSSStyleSheet.h | 1 - layout/style/CSSValue.h | 1 - layout/style/CounterStyleManager.h | 1 - layout/style/Loader.h | 3 --- layout/style/Rule.h | 1 - layout/style/SVGAttrAnimationRuleProcessor.h | 1 - layout/style/StyleRule.h | 1 - layout/style/nsAnimationManager.h | 1 - layout/style/nsCSSRuleProcessor.h | 2 ++ layout/style/nsComputedDOMStyle.h | 21 ------------------- layout/style/nsFontFaceLoader.h | 1 - layout/style/nsICSSPseudoComparator.h | 1 - layout/style/nsIStyleRuleProcessor.h | 1 - layout/style/nsRuleNode.h | 1 - layout/style/nsRuleProcessorData.h | 2 -- layout/style/nsStyleSet.h | 3 ++- layout/style/nsTransitionManager.h | 1 - layout/svg/nsCSSFilterInstance.h | 1 - layout/svg/nsISVGChildFrame.h | 1 - layout/svg/nsSVGContainerFrame.h | 1 - layout/svg/nsSVGFilterFrame.h | 1 - layout/svg/nsSVGFilterInstance.h | 1 - layout/svg/nsSVGForeignObjectFrame.h | 1 - layout/svg/nsSVGPathGeometryFrame.h | 1 - layout/svg/nsSVGPatternFrame.h | 3 --- layout/svg/nsSVGUtils.h | 7 ------- layout/tables/SpanningCellSorter.h | 2 -- layout/tables/nsCellMap.h | 1 - layout/tables/nsTableColFrame.h | 2 -- layout/tables/nsTableFrame.h | 2 -- layout/tables/nsTableRowGroupFrame.h | 1 - layout/xul/BoxObject.h | 1 - layout/xul/grid/nsGrid.h | 2 -- layout/xul/grid/nsGridLayout2.h | 2 -- layout/xul/grid/nsGridRow.h | 2 -- layout/xul/nsBoxLayoutState.h | 4 ---- layout/xul/nsIScrollbarMediator.h | 1 - layout/xul/nsLeafBoxFrame.h | 2 -- layout/xul/nsMenuFrame.h | 1 - layout/xul/nsMenuPopupFrame.h | 1 - layout/xul/nsResizerFrame.h | 1 - layout/xul/nsScrollbarButtonFrame.h | 2 -- layout/xul/nsSliderFrame.h | 1 - parser/html/nsHtml5TreeBuilderCppSupplement.h | 2 -- parser/html/nsHtml5TreeOpExecutor.h | 2 -- parser/html/nsHtml5TreeOperation.h | 1 - parser/htmlparser/CNavDTD.h | 3 --- parser/htmlparser/nsIDTD.h | 2 -- parser/htmlparser/nsParser.h | 1 - parser/htmlparser/nsScanner.h | 2 -- rdf/base/nsRDFXMLSerializer.h | 1 - rdf/base/rdfutil.h | 2 -- testing/gtest/gtest/include/gtest/gtest.h | 1 - tools/profiler/GeckoProfilerImpl.h | 1 - tools/profiler/PseudoStack.h | 2 -- tools/profiler/TableTicker.h | 2 -- 116 files changed, 8 insertions(+), 212 deletions(-) diff --git a/accessible/atk/InterfaceInitFuncs.h b/accessible/atk/InterfaceInitFuncs.h index 20cab6da9e7b..805001e8222d 100644 --- a/accessible/atk/InterfaceInitFuncs.h +++ b/accessible/atk/InterfaceInitFuncs.h @@ -17,8 +17,6 @@ class AccessibleWrap; } // namespace a11y } // namespace mozilla -struct MaiUtilClass; - extern "C" { void actionInterfaceInitCB(AtkActionIface* aIface); void componentInterfaceInitCB(AtkComponentIface* aIface); diff --git a/accessible/generic/Accessible.h b/accessible/generic/Accessible.h index 10528d347ef5..6d9a9cc271af 100644 --- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -23,7 +23,6 @@ struct nsRect; class nsIFrame; class nsIAtom; class nsIPersistentProperties; -class nsView; namespace mozilla { namespace a11y { @@ -39,7 +38,6 @@ class HTMLLIAccessible; class HyperTextAccessible; class ImageAccessible; class KeyBinding; -class MathMLAccessible; class ProxyAccessible; class Relation; class RootAccessible; diff --git a/accessible/generic/DocAccessible.h b/accessible/generic/DocAccessible.h index ad54069cc065..243fbde0f52f 100644 --- a/accessible/generic/DocAccessible.h +++ b/accessible/generic/DocAccessible.h @@ -23,8 +23,6 @@ class nsAccessiblePivot; -class nsIScrollableView; - const uint32_t kDefaultCacheLength = 128; namespace mozilla { diff --git a/accessible/generic/ImageAccessible.h b/accessible/generic/ImageAccessible.h index c63188237088..f2324ae4cd6a 100644 --- a/accessible/generic/ImageAccessible.h +++ b/accessible/generic/ImageAccessible.h @@ -8,8 +8,6 @@ #include "BaseAccessibles.h" -class nsGenericHTMLElement; - namespace mozilla { namespace a11y { diff --git a/accessible/html/HTMLSelectAccessible.h b/accessible/html/HTMLSelectAccessible.h index 2bdd6e1d9a00..42a80330a3ca 100644 --- a/accessible/html/HTMLSelectAccessible.h +++ b/accessible/html/HTMLSelectAccessible.h @@ -8,8 +8,6 @@ #include "HTMLFormControlAccessible.h" -class nsIMutableArray; - namespace mozilla { namespace a11y { diff --git a/accessible/html/HTMLTableAccessible.h b/accessible/html/HTMLTableAccessible.h index 07ad6864a07c..47f6602cb796 100644 --- a/accessible/html/HTMLTableAccessible.h +++ b/accessible/html/HTMLTableAccessible.h @@ -10,7 +10,6 @@ #include "TableAccessible.h" #include "TableCellAccessible.h" -class nsITableLayout; class nsITableCellLayout; namespace mozilla { diff --git a/accessible/interfaces/nsIAccessibilityService.h b/accessible/interfaces/nsIAccessibilityService.h index 6f3e128a811d..2eca2578a8bd 100644 --- a/accessible/interfaces/nsIAccessibilityService.h +++ b/accessible/interfaces/nsIAccessibilityService.h @@ -20,11 +20,7 @@ class Accessible; } // namespace a11y } // namespace mozilla -class nsINode; -class nsIContent; -class nsIFrame; class nsIPresShell; -class nsPluginFrame; // 0e7e6879-854b-4260-bc6e-525b5fb5cf34 #define NS_IACCESSIBILITYSERVICE_IID \ diff --git a/accessible/mac/RootAccessibleWrap.h b/accessible/mac/RootAccessibleWrap.h index d92034ed2cbd..ad225399ac94 100644 --- a/accessible/mac/RootAccessibleWrap.h +++ b/accessible/mac/RootAccessibleWrap.h @@ -15,8 +15,6 @@ namespace mozilla { namespace a11y { -struct objc_class; - class RootAccessibleWrap : public RootAccessible { public: diff --git a/accessible/windows/msaa/nsWinUtils.h b/accessible/windows/msaa/nsWinUtils.h index 8b17df2e03f2..ac3a8b699e12 100644 --- a/accessible/windows/msaa/nsWinUtils.h +++ b/accessible/windows/msaa/nsWinUtils.h @@ -14,7 +14,6 @@ #include "nsCOMPtr.h" #include "nsRefPtrHashtable.h" -class nsIArray; class nsIContent; namespace mozilla { diff --git a/accessible/xul/XULListboxAccessible.h b/accessible/xul/XULListboxAccessible.h index 42e2d39616eb..e90f88acecfd 100644 --- a/accessible/xul/XULListboxAccessible.h +++ b/accessible/xul/XULListboxAccessible.h @@ -14,8 +14,6 @@ #include "XULMenuAccessible.h" #include "XULSelectControlAccessible.h" -class nsIWeakReference; - namespace mozilla { namespace a11y { diff --git a/dom/xul/templates/nsContentTestNode.h b/dom/xul/templates/nsContentTestNode.h index e39c7114acce..ebea5bcf617c 100644 --- a/dom/xul/templates/nsContentTestNode.h +++ b/dom/xul/templates/nsContentTestNode.h @@ -12,6 +12,8 @@ #include "nsIAtom.h" #include "nsIDOMDocument.h" +class nsXULTemplateQueryProcessorRDF; + /** * The nsContentTestNode is always the top node in a query's rule network. It * exists so that Constrain can filter out resources that aren't part of a diff --git a/dom/xul/templates/nsRDFQuery.h b/dom/xul/templates/nsRDFQuery.h index 2a3bafd1d690..56679f23042b 100644 --- a/dom/xul/templates/nsRDFQuery.h +++ b/dom/xul/templates/nsRDFQuery.h @@ -15,6 +15,8 @@ {0x8929ff60, 0x1c9c, 0x4d87, \ { 0xac, 0x02, 0x09, 0x14, 0x15, 0x3b, 0x48, 0xc4 }} +class nsXULTemplateQueryProcessorRDF; + /** * A compiled query in the RDF query processor. This interface should not be * used directly outside of the RDF query processor. diff --git a/dom/xul/templates/nsRuleNetwork.h b/dom/xul/templates/nsRuleNetwork.h index 39fda0041852..f382a3244f2d 100644 --- a/dom/xul/templates/nsRuleNetwork.h +++ b/dom/xul/templates/nsRuleNetwork.h @@ -38,7 +38,6 @@ #include "nsIRDFNode.h" class nsXULTemplateResultSetRDF; -class nsXULTemplateQueryProcessorRDF; //---------------------------------------------------------------------- diff --git a/editor/libeditor/PlaceholderTxn.h b/editor/libeditor/PlaceholderTxn.h index ad0f4b0f1a3a..cb74c84627f5 100644 --- a/editor/libeditor/PlaceholderTxn.h +++ b/editor/libeditor/PlaceholderTxn.h @@ -15,8 +15,6 @@ #include "nsWeakReference.h" #include "nsAutoPtr.h" -class nsHTMLEditor; - namespace mozilla { namespace dom { class IMETextTxn; diff --git a/editor/libeditor/nsEditor.h b/editor/libeditor/nsEditor.h index 42964fcd6a47..8e377cbc247f 100644 --- a/editor/libeditor/nsEditor.h +++ b/editor/libeditor/nsEditor.h @@ -33,10 +33,7 @@ class EditAggregateTxn; class RemoveStyleSheetTxn; class nsIAtom; class nsIContent; -class nsIDOMCharacterData; -class nsIDOMDataTransfer; class nsIDOMDocument; -class nsIDOMElement; class nsIDOMEvent; class nsIDOMEventListener; class nsIDOMEventTarget; diff --git a/editor/libeditor/nsHTMLCSSUtils.h b/editor/libeditor/nsHTMLCSSUtils.h index 6c1c438897e9..c56d3ad04d55 100644 --- a/editor/libeditor/nsHTMLCSSUtils.h +++ b/editor/libeditor/nsHTMLCSSUtils.h @@ -26,7 +26,6 @@ class Element; } // namespace mozilla class nsHTMLEditor; -class nsIDOMWindow; typedef void (*nsProcessValueFunc)(const nsAString * aInputString, nsAString & aOutputString, const char * aDefaultValueString, diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index f7e8141680b5..3fc3765b41b5 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -43,11 +43,9 @@ class nsIDOMKeyEvent; class nsITransferable; -class nsIDocumentEncoder; class nsIClipboard; class TypeInState; class nsIContentFilter; -class nsIURL; class nsILinkHandler; class nsTableOuterFrame; class nsIDOMRange; diff --git a/editor/libeditor/nsHTMLEditorEventListener.h b/editor/libeditor/nsHTMLEditorEventListener.h index 6c386a19d9f7..9b660878f3f8 100644 --- a/editor/libeditor/nsHTMLEditorEventListener.h +++ b/editor/libeditor/nsHTMLEditorEventListener.h @@ -11,7 +11,6 @@ class nsEditor; class nsHTMLEditor; -class nsIDOMEvent; class nsHTMLEditorEventListener : public nsEditorEventListener { diff --git a/editor/libeditor/nsIAbsorbingTransaction.h b/editor/libeditor/nsIAbsorbingTransaction.h index 0346b9451115..900d29cccd13 100644 --- a/editor/libeditor/nsIAbsorbingTransaction.h +++ b/editor/libeditor/nsIAbsorbingTransaction.h @@ -20,7 +20,6 @@ Transaction interface to outside world {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } class nsSelectionState; -class nsIEditor; class nsIAtom; /** diff --git a/editor/libeditor/nsPlaintextEditor.h b/editor/libeditor/nsPlaintextEditor.h index 8e5e9a89701a..cf32364be996 100644 --- a/editor/libeditor/nsPlaintextEditor.h +++ b/editor/libeditor/nsPlaintextEditor.h @@ -16,11 +16,9 @@ #include "nscore.h" class nsIContent; -class nsIDOMDataTransfer; class nsIDOMDocument; class nsIDOMElement; class nsIDOMEvent; -class nsIDOMEventTarget; class nsIDOMKeyEvent; class nsIDOMNode; class nsIDocumentEncoder; diff --git a/editor/libeditor/nsTextEditUtils.h b/editor/libeditor/nsTextEditUtils.h index 441b84570495..2fc613a619e2 100644 --- a/editor/libeditor/nsTextEditUtils.h +++ b/editor/libeditor/nsTextEditUtils.h @@ -8,12 +8,6 @@ #include "nscore.h" -namespace mozilla { -namespace dom { -class Element; -} // namespace dom -} // namespace mozilla - class nsIDOMNode; class nsINode; class nsPlaintextEditor; diff --git a/editor/libeditor/nsWSRunObject.h b/editor/libeditor/nsWSRunObject.h index 21c60bf2d026..a43a37130c0f 100644 --- a/editor/libeditor/nsWSRunObject.h +++ b/editor/libeditor/nsWSRunObject.h @@ -14,7 +14,6 @@ #include "mozilla/dom/Text.h" class nsHTMLEditor; -class nsIDOMDocument; class nsIDOMNode; struct DOMPoint; diff --git a/editor/txmgr/nsTransactionManager.h b/editor/txmgr/nsTransactionManager.h index 2b244f482719..17d21819f31a 100644 --- a/editor/txmgr/nsTransactionManager.h +++ b/editor/txmgr/nsTransactionManager.h @@ -18,7 +18,6 @@ class nsITransaction; class nsITransactionListener; -class nsTransactionItem; /** implementation of a transaction manager object. * diff --git a/embedding/browser/nsWebBrowser.h b/embedding/browser/nsWebBrowser.h index 88eeb413faf2..08dbcbb51caf 100644 --- a/embedding/browser/nsWebBrowser.h +++ b/embedding/browser/nsWebBrowser.h @@ -41,8 +41,6 @@ #include "nsTArray.h" #include "nsWeakPtr.h" -class nsIContentViewerFile; - class nsWebBrowserInitInfo { public: diff --git a/embedding/components/find/nsFind.h b/embedding/components/find/nsFind.h index 9384c379a8ed..f1ed2c359b70 100644 --- a/embedding/components/find/nsFind.h +++ b/embedding/components/find/nsFind.h @@ -16,7 +16,6 @@ #include "nsIContentIterator.h" #include "nsIWordBreaker.h" -class nsIAtom; class nsIContent; #define NS_FIND_CONTRACTID "@mozilla.org/embedcomp/rangefind;1" diff --git a/embedding/components/printingui/mac/nsPrintingPromptService.h b/embedding/components/printingui/mac/nsPrintingPromptService.h index 469f762e38b6..0334db22307b 100644 --- a/embedding/components/printingui/mac/nsPrintingPromptService.h +++ b/embedding/components/printingui/mac/nsPrintingPromptService.h @@ -21,10 +21,6 @@ #include "nsPrintProgress.h" #include "nsIWebProgressListener.h" - -class nsIDOMWindow; -class nsIDialogParamBlock; - class nsPrintingPromptService: public nsIPrintingPromptService, public nsIWebProgressListener { diff --git a/embedding/components/windowwatcher/nsWindowWatcher.h b/embedding/components/windowwatcher/nsWindowWatcher.h index a89a74f4e4a4..0edefdb69d03 100644 --- a/embedding/components/windowwatcher/nsWindowWatcher.h +++ b/embedding/components/windowwatcher/nsWindowWatcher.h @@ -23,10 +23,7 @@ class nsIURI; class nsIDocShellTreeItem; class nsIDocShellTreeOwner; class nsPIDOMWindow; -class nsIWebBrowserChrome; -class nsString; class nsWatcherWindowEnumerator; -class nsIScriptContext; class nsPromptService; struct nsWatcherWindowEntry; struct SizeSpec; diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.h b/extensions/spellcheck/src/mozInlineSpellChecker.h index ad4317cf6ead..dfbc932e7d5b 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.h +++ b/extensions/spellcheck/src/mozInlineSpellChecker.h @@ -24,7 +24,6 @@ #undef KeyPress #endif -class nsIDOMMouseEventListener; class mozInlineSpellWordUtil; class mozInlineSpellChecker; class mozInlineSpellResume; diff --git a/layout/base/DisplayItemClip.h b/layout/base/DisplayItemClip.h index de6fa97f80f7..21db189ab391 100644 --- a/layout/base/DisplayItemClip.h +++ b/layout/base/DisplayItemClip.h @@ -12,7 +12,6 @@ #include "nsStyleConsts.h" class gfxContext; -class nsDisplayItem; class nsPresContext; class nsRegion; diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 6f42801cfb3a..fd204e7c1451 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -50,8 +50,6 @@ public: bool mIsInfinite; }; -struct NewLayerEntry; - struct ContainerLayerParameters { ContainerLayerParameters() : mXScale(1) diff --git a/layout/base/GeometryUtils.h b/layout/base/GeometryUtils.h index 888aa826860f..c9e8c4661ff5 100644 --- a/layout/base/GeometryUtils.h +++ b/layout/base/GeometryUtils.h @@ -16,7 +16,6 @@ */ class nsINode; -class nsIDocument; namespace mozilla { diff --git a/layout/base/SelectionCarets.h b/layout/base/SelectionCarets.h index 42aea9616fbe..b3ece19de289 100644 --- a/layout/base/SelectionCarets.h +++ b/layout/base/SelectionCarets.h @@ -18,16 +18,11 @@ #include "mozilla/EventForwards.h" #include "mozilla/WeakPtr.h" -class nsCanvasFrame; class nsDocShell; class nsFrameSelection; class nsIContent; -class nsIDocument; -class nsIFrame; class nsIPresShell; class nsITimer; -class nsIWidget; -class nsPresContext; namespace mozilla { diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index d8b0ecf1cf27..a48c9c63dc73 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -24,10 +24,8 @@ #include "ScrollbarStyles.h" struct nsFrameItems; -struct nsAbsoluteItems; class nsStyleContext; struct nsStyleDisplay; -class nsIDOMHTMLSelectElement; struct nsGenConInitializer; class nsContainerFrame; @@ -38,7 +36,6 @@ struct PendingBinding; class nsGenericDOMDataNode; class nsFrameConstructorState; -class nsFrameConstructorSaveState; namespace mozilla { diff --git a/layout/base/nsIDocumentViewerPrint.h b/layout/base/nsIDocumentViewerPrint.h index 5ddb516e43a9..842771b4ae1a 100644 --- a/layout/base/nsIDocumentViewerPrint.h +++ b/layout/base/nsIDocumentViewerPrint.h @@ -11,7 +11,6 @@ class nsIDocument; class nsStyleSet; class nsIPresShell; class nsPresContext; -class nsIWidget; class nsViewManager; // {c6f255cf-cadd-4382-b57f-cd2a9874169b} diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 08001f5e8bf3..8422a75dd80f 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -94,7 +94,6 @@ class DocAccessible; } // namespace a11y } // namespace mozilla #endif -class nsIWidget; struct nsArenaMemoryStats; class nsITimer; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 5ebcc3e7dbf6..2653455c048a 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -34,7 +34,6 @@ #include #include -class nsIFormControlFrame; class nsPresContext; class nsIContent; class nsIAtom; @@ -80,7 +79,6 @@ struct RectCornerRadii; } // namespace gfx namespace layers { class Layer; -class ClientLayerManager; } } diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index e06465dd9a35..f308c11ac9a1 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -39,7 +39,6 @@ #include "nsIMessageManager.h" #include "mozilla/RestyleLogging.h" -class nsBidiPresUtils; class nsAString; class nsIPrintSettings; class nsDocShell; @@ -52,14 +51,10 @@ class nsIFrame; class nsFrameManager; class nsILinkHandler; class nsIAtom; -class nsICSSPseudoComparator; -struct nsStyleBackground; -struct nsStyleBorder; class nsIRunnable; class gfxUserFontEntry; class gfxUserFontSet; class gfxTextPerfMetrics; -struct nsFontFaceRuleContainer; class nsPluginFrame; class nsTransitionManager; class nsAnimationManager; diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 13dee775939c..51417fc1b431 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -38,7 +38,6 @@ #include "mozilla/MemoryReporting.h" class nsRange; -class nsIDragService; struct RangePaintInfo; struct nsCallbackEventRequest; diff --git a/layout/base/nsRefreshDriver.h b/layout/base/nsRefreshDriver.h index 9bc464b5ea34..3dc86c4031a4 100644 --- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -28,7 +28,6 @@ class nsPresContext; class nsIPresShell; class nsIDocument; class imgIRequest; -class nsIRunnable; namespace mozilla { class RefreshDriverTimer; diff --git a/layout/build/nsContentDLF.h b/layout/build/nsContentDLF.h index 0c0d0b24212c..02e8cb9f822f 100644 --- a/layout/build/nsContentDLF.h +++ b/layout/build/nsContentDLF.h @@ -11,8 +11,6 @@ class nsIChannel; class nsIContentViewer; -class nsIFile; -class nsIInputStream; class nsILoadGroup; class nsIStreamListener; diff --git a/layout/forms/nsFileControlFrame.h b/layout/forms/nsFileControlFrame.h index 274a9eed39df..60748f5c5520 100644 --- a/layout/forms/nsFileControlFrame.h +++ b/layout/forms/nsFileControlFrame.h @@ -13,7 +13,6 @@ #include "nsIAnonymousContentCreator.h" #include "nsCOMPtr.h" -class nsTextControlFrame; class nsIDOMDataTransfer; class nsFileControlFrame : public nsBlockFrame, diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index e83e92a82c08..53133c9e1064 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -29,8 +29,6 @@ #undef KeyPress #endif -class nsIDOMHTMLSelectElement; -class nsIDOMHTMLOptionsCollection; class nsIComboboxControlFrame; class nsPresContext; class nsListEventListener; diff --git a/layout/forms/nsProgressFrame.h b/layout/forms/nsProgressFrame.h index e014ab00a0c0..980e8ba9e2d8 100644 --- a/layout/forms/nsProgressFrame.h +++ b/layout/forms/nsProgressFrame.h @@ -11,8 +11,6 @@ #include "nsIAnonymousContentCreator.h" #include "nsCOMPtr.h" -class nsBaseContentList; - class nsProgressFrame : public nsContainerFrame, public nsIAnonymousContentCreator { diff --git a/layout/forms/nsRangeFrame.h b/layout/forms/nsRangeFrame.h index 85460ffb8ae3..32dba33df30a 100644 --- a/layout/forms/nsRangeFrame.h +++ b/layout/forms/nsRangeFrame.h @@ -14,7 +14,6 @@ #include "nsIDOMEventListener.h" #include "nsCOMPtr.h" -class nsBaseContentList; class nsDisplayRangeFocusRing; class nsRangeFrame : public nsContainerFrame, diff --git a/layout/generic/ScrollbarActivity.h b/layout/generic/ScrollbarActivity.h index b390fefbfcd5..c3c94840f681 100644 --- a/layout/generic/ScrollbarActivity.h +++ b/layout/generic/ScrollbarActivity.h @@ -15,7 +15,6 @@ class nsIContent; class nsIScrollbarMediator; class nsITimer; -class nsIAtom; namespace mozilla { namespace layout { diff --git a/layout/generic/TextOverflow.h b/layout/generic/TextOverflow.h index 3708f7e2f849..4fda77ce2e8e 100644 --- a/layout/generic/TextOverflow.h +++ b/layout/generic/TextOverflow.h @@ -13,7 +13,6 @@ #include class nsIScrollableFrame; -class gfxTextRun; class nsLineBox; namespace mozilla { diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 14ff69940d95..aeccdbcf8cb2 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -44,7 +44,6 @@ enum LineReflowStatus { class nsBlockReflowState; class nsBlockInFlowLineIterator; class nsBulletFrame; -class nsFirstLineFrame; /** * Some invariants: diff --git a/layout/generic/nsBlockReflowContext.h b/layout/generic/nsBlockReflowContext.h index d0c1018df452..7afec5ae3a55 100644 --- a/layout/generic/nsBlockReflowContext.h +++ b/layout/generic/nsBlockReflowContext.h @@ -16,8 +16,6 @@ class nsBlockReflowState; struct nsHTMLReflowState; class nsLineBox; class nsPresContext; -class nsLineLayout; -struct nsBlockHorizontalAlign; /** * An encapsulation of the state and algorithm for reflowing block frames. diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 614faca3e31a..c171a9bb3016 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -97,7 +97,6 @@ //---------------------------------------------------------------------- struct nsBoxLayoutMetrics; -class nsDisplayBackgroundImage; struct nsRect; /** diff --git a/layout/generic/nsFrameSelection.h b/layout/generic/nsFrameSelection.h index 0c389c053e02..6004b004101d 100644 --- a/layout/generic/nsFrameSelection.h +++ b/layout/generic/nsFrameSelection.h @@ -20,7 +20,6 @@ #include "nsBidiPresUtils.h" class nsRange; -class nsTableOuterFrame; // IID for the nsFrameSelection interface // 3c6ae2d0-4cf1-44a1-9e9d-2411867f19c6 diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index a0cc47d6f099..1164fcf76a2b 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -27,7 +27,6 @@ class nsPresContext; class nsIPresShell; class nsIContent; class nsIAtom; -class nsIScrollFrameInternal; class nsPresState; class nsIScrollPositionListener; struct ScrollReflowState; diff --git a/layout/generic/nsHTMLParts.h b/layout/generic/nsHTMLParts.h index 8dd96d6edf9e..89fa3cd5d8f5 100644 --- a/layout/generic/nsHTMLParts.h +++ b/layout/generic/nsHTMLParts.h @@ -14,14 +14,12 @@ class nsIAtom; class nsNodeInfoManager; class nsIContent; -class nsIContentIterator; class nsIDocument; class nsIFrame; class nsIHTMLContentSink; class nsIFragmentContentSink; class nsStyleContext; class nsIURI; -class nsString; class nsIPresShell; class nsIChannel; class nsTableColFrame; diff --git a/layout/generic/nsIAnonymousContentCreator.h b/layout/generic/nsIAnonymousContentCreator.h index a2a2f716ced3..69d08867a8c8 100644 --- a/layout/generic/nsIAnonymousContentCreator.h +++ b/layout/generic/nsIAnonymousContentCreator.h @@ -15,7 +15,6 @@ #include "nsStyleContext.h" #include "nsTArrayForwardDeclare.h" -class nsBaseContentList; class nsIContent; class nsIFrame; diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 2b665c918903..b45157c11d32 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -59,14 +59,12 @@ */ struct nsHTMLReflowState; -class nsHTMLReflowCommand; class nsIAtom; class nsPresContext; class nsIPresShell; class nsRenderingContext; class nsView; class nsIWidget; -class nsIDOMRange; class nsISelectionController; class nsBoxLayoutState; class nsBoxLayout; diff --git a/layout/generic/nsPluginFrame.h b/layout/generic/nsPluginFrame.h index 2f28b2fabdb9..ac99fa1ca544 100644 --- a/layout/generic/nsPluginFrame.h +++ b/layout/generic/nsPluginFrame.h @@ -29,7 +29,6 @@ class nsPresContext; class nsRootPresContext; class nsDisplayPlugin; -class nsIOSurface; class PluginBackgroundSink; class nsPluginInstanceOwner; diff --git a/layout/generic/nsRubyFrame.h b/layout/generic/nsRubyFrame.h index 5cfd340503e1..ab84de7326cf 100644 --- a/layout/generic/nsRubyFrame.h +++ b/layout/generic/nsRubyFrame.h @@ -12,7 +12,6 @@ #include "nsInlineFrame.h" class nsRubyBaseContainerFrame; -class nsRubyTextContainerFrame; typedef nsInlineFrame nsRubyFrameSuper; diff --git a/layout/inspector/inLayoutUtils.h b/layout/inspector/inLayoutUtils.h index 826c19ef3362..e427b2500319 100644 --- a/layout/inspector/inLayoutUtils.h +++ b/layout/inspector/inLayoutUtils.h @@ -10,10 +10,6 @@ class nsIDocument; class nsIDOMDocument; class nsIDOMElement; class nsIDOMNode; -class nsIDOMWindow; -class nsIFrame; -class nsIPresShell; -class nsISupports; namespace mozilla { class EventStateManager; diff --git a/layout/inspector/nsFontFace.h b/layout/inspector/nsFontFace.h index 89d801513df2..3da0d98be5b1 100644 --- a/layout/inspector/nsFontFace.h +++ b/layout/inspector/nsFontFace.h @@ -10,7 +10,6 @@ class gfxFontEntry; class gfxFontGroup; -class nsCSSFontFaceRule; class nsFontFace : public nsIDOMFontFace { diff --git a/layout/printing/nsPrintEngine.h b/layout/printing/nsPrintEngine.h index 1d99c08b3412..e893a8c90af8 100644 --- a/layout/printing/nsPrintEngine.h +++ b/layout/printing/nsPrintEngine.h @@ -25,13 +25,11 @@ // Classes class nsPagePrintTimer; class nsIDocShell; -class nsDeviceContext; class nsIDocument; class nsIDocumentViewerPrint; class nsPrintObject; class nsIDocShell; class nsIPageSequenceFrame; -class nsIWeakReference; //------------------------------------------------------------------------ // nsPrintEngine Class diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index c3e2a866ffff..51ba7ee30c1c 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -28,7 +28,6 @@ class nsIFrame; class nsPresContext; -class nsStyleChangeList; namespace mozilla { diff --git a/layout/style/CSSStyleSheet.h b/layout/style/CSSStyleSheet.h index 108510f17d21..89eb84cad05b 100644 --- a/layout/style/CSSStyleSheet.h +++ b/layout/style/CSSStyleSheet.h @@ -29,7 +29,6 @@ class CSSRuleListImpl; class nsCSSRuleProcessor; -class nsICSSRuleList; class nsIPrincipal; class nsIURI; class nsMediaList; diff --git a/layout/style/CSSValue.h b/layout/style/CSSValue.h index 14d35fde1fb5..452a2b7b4af3 100644 --- a/layout/style/CSSValue.h +++ b/layout/style/CSSValue.h @@ -12,7 +12,6 @@ #include "nsWrapperCache.h" #include "nsStringFwd.h" -class nsIDOMCSSValue; class nsROCSSPrimitiveValue; namespace mozilla { class ErrorResult; diff --git a/layout/style/CounterStyleManager.h b/layout/style/CounterStyleManager.h index 61932af5aca3..b44553066c22 100644 --- a/layout/style/CounterStyleManager.h +++ b/layout/style/CounterStyleManager.h @@ -17,7 +17,6 @@ #include "nsCSSValue.h" class nsPresContext; -class nsCSSCounterStyleRule; namespace mozilla { diff --git a/layout/style/Loader.h b/layout/style/Loader.h index 0247b637f5d1..8b7dc23a2fef 100644 --- a/layout/style/Loader.h +++ b/layout/style/Loader.h @@ -23,14 +23,11 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/net/ReferrerPolicy.h" -class nsIAtom; class nsICSSLoaderObserver; class nsIContent; class nsIDocument; -class nsCSSParser; class nsMediaList; class nsIStyleSheetLinkingElement; -class nsCycleCollectionTraversalCallback; namespace mozilla { class CSSStyleSheet; diff --git a/layout/style/Rule.h b/layout/style/Rule.h index 77c4e21560c0..093543c56d30 100644 --- a/layout/style/Rule.h +++ b/layout/style/Rule.h @@ -13,7 +13,6 @@ #include "nsIStyleRule.h" #include "nsIDOMCSSRule.h" -class nsIStyleSheet; class nsIDocument; struct nsRuleData; template struct already_AddRefed; diff --git a/layout/style/SVGAttrAnimationRuleProcessor.h b/layout/style/SVGAttrAnimationRuleProcessor.h index e181b77e8152..149d892c9c0f 100644 --- a/layout/style/SVGAttrAnimationRuleProcessor.h +++ b/layout/style/SVGAttrAnimationRuleProcessor.h @@ -14,7 +14,6 @@ #include "nsIStyleRuleProcessor.h" -class nsIDocument; class nsRuleWalker; namespace mozilla { diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index efa2d3be1fc9..6bce38497e56 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -22,7 +22,6 @@ class nsIAtom; struct nsCSSSelectorList; -class nsCSSCompressedDataBlock; namespace mozilla { class CSSStyleSheet; diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 372207bcc5d2..35d6f512119a 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -13,7 +13,6 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/TimeStamp.h" -class nsCSSKeyframesRule; class nsStyleContext; namespace mozilla { diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index 0d6cd63aa2f9..5ccbda211fc1 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -22,8 +22,10 @@ #include "mozilla/UniquePtr.h" struct CascadeEnumData; +struct ElementDependentRuleProcessorData; struct nsCSSSelector; struct nsCSSSelectorList; +struct nsFontFaceRuleContainer; struct RuleCascadeData; struct TreeMatchContext; class nsCSSKeyframesRule; diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 549c05a482b7..750be353f97c 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -34,33 +34,12 @@ class nsDOMCSSValueList; struct nsMargin; class nsROCSSPrimitiveValue; struct nsStyleBackground; -struct nsStyleBorder; -struct nsStyleContent; -struct nsStyleColumn; -struct nsStyleColor; class nsStyleCoord; class nsStyleCorners; -struct nsStyleDisplay; struct nsStyleFilter; -struct nsStyleFont; class nsStyleGradient; struct nsStyleImage; -struct nsStyleList; -struct nsStyleMargin; -struct nsStyleOutline; -struct nsStylePadding; -struct nsStylePosition; -struct nsStyleQuotes; class nsStyleSides; -struct nsStyleSVG; -struct nsStyleSVGReset; -struct nsStyleTable; -struct nsStyleText; -struct nsStyleTextReset; -class nsStyleTimingFunction; -struct nsStyleUIReset; -struct nsStyleVisibility; -struct nsStyleXUL; struct nsTimingFunction; class gfx3DMatrix; diff --git a/layout/style/nsFontFaceLoader.h b/layout/style/nsFontFaceLoader.h index 858a2aa508a7..e47b12088fb7 100644 --- a/layout/style/nsFontFaceLoader.h +++ b/layout/style/nsFontFaceLoader.h @@ -18,7 +18,6 @@ #include "nsTHashtable.h" #include "nsCSSRules.h" -class nsPresContext; class nsIPrincipal; class nsFontFaceLoader : public nsIStreamLoaderObserver diff --git a/layout/style/nsICSSPseudoComparator.h b/layout/style/nsICSSPseudoComparator.h index 20b3f5cb10a0..0ea207891657 100644 --- a/layout/style/nsICSSPseudoComparator.h +++ b/layout/style/nsICSSPseudoComparator.h @@ -8,7 +8,6 @@ #ifndef nsICSSPseudoComparator_h___ #define nsICSSPseudoComparator_h___ -class nsIAtom; struct nsCSSSelector; class nsICSSPseudoComparator diff --git a/layout/style/nsIStyleRuleProcessor.h b/layout/style/nsIStyleRuleProcessor.h index 6132549c94bb..00182dd38070 100644 --- a/layout/style/nsIStyleRuleProcessor.h +++ b/layout/style/nsIStyleRuleProcessor.h @@ -17,7 +17,6 @@ #include "nsChangeHint.h" struct RuleProcessorData; -struct ElementDependentRuleProcessorData; struct ElementRuleProcessorData; struct PseudoElementRuleProcessorData; struct AnonBoxRuleProcessorData; diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index b7c6ac2ae3a2..9cb38eabdaf0 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -20,7 +20,6 @@ class nsIStyleRule; struct nsCSSValueList; class nsCSSPropertySet; class nsCSSValue; -struct nsCSSRect; class nsStyleCoord; struct nsCSSValuePairList; diff --git a/layout/style/nsRuleProcessorData.h b/layout/style/nsRuleProcessorData.h index 60da99188c53..67dbd9ad2c4c 100644 --- a/layout/style/nsRuleProcessorData.h +++ b/layout/style/nsRuleProcessorData.h @@ -23,11 +23,9 @@ #include "mozilla/EventStates.h" #include "mozilla/GuardObjects.h" -class nsAttrValue; class nsIAtom; class nsIContent; class nsICSSPseudoComparator; -class nsIStyleSheet; struct TreeMatchContext; /** diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 1e0731612237..a031c5ee45bd 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -26,13 +26,14 @@ #include "nsCSSPseudoElements.h" class gfxFontFeatureValueSet; -class nsCSSFontFaceRule; class nsCSSKeyframesRule; class nsCSSFontFeatureValuesRule; class nsCSSPageRule; class nsCSSCounterStyleRule; +class nsICSSPseudoComparator; class nsRuleWalker; struct ElementDependentRuleProcessorData; +struct nsFontFaceRuleContainer; struct TreeMatchContext; namespace mozilla { diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index bf267bf1cc98..6baa6913cb18 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -18,7 +18,6 @@ class nsStyleContext; class nsPresContext; class nsCSSPropertySet; -struct ElementDependentRuleProcessorData; namespace mozilla { struct StyleTransition; diff --git a/layout/svg/nsCSSFilterInstance.h b/layout/svg/nsCSSFilterInstance.h index 16ae11598482..5d60eb3e77ae 100644 --- a/layout/svg/nsCSSFilterInstance.h +++ b/layout/svg/nsCSSFilterInstance.h @@ -13,7 +13,6 @@ #include "mozilla/gfx/Types.h" #include "nsColor.h" -class nsIFrame; struct nsStyleFilter; template class nsTArray; diff --git a/layout/svg/nsISVGChildFrame.h b/layout/svg/nsISVGChildFrame.h index 380a58612f27..6908e3af9644 100644 --- a/layout/svg/nsISVGChildFrame.h +++ b/layout/svg/nsISVGChildFrame.h @@ -14,7 +14,6 @@ class gfxMatrix; class nsIFrame; class SVGBBox; -struct nsPoint; struct nsRect; namespace mozilla { diff --git a/layout/svg/nsSVGContainerFrame.h b/layout/svg/nsSVGContainerFrame.h index 759a61db41b0..1f059fcd399d 100644 --- a/layout/svg/nsSVGContainerFrame.h +++ b/layout/svg/nsSVGContainerFrame.h @@ -21,7 +21,6 @@ class nsIContent; class nsIPresShell; class nsStyleContext; -struct nsPoint; struct nsRect; typedef nsContainerFrame nsSVGContainerFrameBase; diff --git a/layout/svg/nsSVGFilterFrame.h b/layout/svg/nsSVGFilterFrame.h index c83dbb385393..772c0f2a0dd5 100644 --- a/layout/svg/nsSVGFilterFrame.h +++ b/layout/svg/nsSVGFilterFrame.h @@ -17,7 +17,6 @@ class nsIContent; class nsIFrame; class nsIPresShell; class nsStyleContext; -class nsSVGIntegerPair; class nsSVGLength2; struct nsRect; diff --git a/layout/svg/nsSVGFilterInstance.h b/layout/svg/nsSVGFilterInstance.h index 0e0394d71e59..3bbdbc0a68b1 100644 --- a/layout/svg/nsSVGFilterInstance.h +++ b/layout/svg/nsSVGFilterInstance.h @@ -13,7 +13,6 @@ #include "nsSVGNumberPair.h" #include "nsTArray.h" -class nsIFrame; class nsSVGFilterFrame; struct nsStyleFilter; diff --git a/layout/svg/nsSVGForeignObjectFrame.h b/layout/svg/nsSVGForeignObjectFrame.h index 077de2964db3..ef3c9d419e57 100644 --- a/layout/svg/nsSVGForeignObjectFrame.h +++ b/layout/svg/nsSVGForeignObjectFrame.h @@ -14,7 +14,6 @@ #include "nsSVGUtils.h" class gfxContext; -class nsSVGOuterSVGFrame; typedef nsContainerFrame nsSVGForeignObjectFrameBase; diff --git a/layout/svg/nsSVGPathGeometryFrame.h b/layout/svg/nsSVGPathGeometryFrame.h index 6f293f23626d..c478153b69a9 100644 --- a/layout/svg/nsSVGPathGeometryFrame.h +++ b/layout/svg/nsSVGPathGeometryFrame.h @@ -30,7 +30,6 @@ class nsStyleContext; class nsSVGMarkerFrame; class nsSVGMarkerProperty; -struct nsPoint; struct nsRect; typedef nsFrame nsSVGPathGeometryFrameBase; diff --git a/layout/svg/nsSVGPatternFrame.h b/layout/svg/nsSVGPatternFrame.h index 7d9f8f21326d..62954e310f24 100644 --- a/layout/svg/nsSVGPatternFrame.h +++ b/layout/svg/nsSVGPatternFrame.h @@ -12,10 +12,7 @@ #include "mozilla/RefPtr.h" #include "nsSVGPaintServerFrame.h" -class gfxASurface; -class gfxContext; class nsIFrame; -class nsSVGElement; class nsSVGLength2; class nsSVGPathGeometryFrame; class nsSVGViewBox; diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index 6d2d50e13857..ab3009de61b9 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -28,15 +28,12 @@ #include class gfxContext; -class gfxPattern; class nsFrameList; class nsIContent; class nsIDocument; class nsIFrame; class nsPresContext; class nsStyleContext; -class nsStyleCoord; -class nsSVGClipPathFrame; class nsSVGDisplayContainerFrame; class nsSVGElement; class nsSVGEnum; @@ -49,11 +46,8 @@ class gfxTextContextPaint; struct nsStyleSVG; struct nsStyleSVGPaint; struct nsRect; -struct nsPoint; namespace mozilla { -class SVGAnimatedPreserveAspectRatio; -class SVGPreserveAspectRatio; namespace dom { class Element; class UserSpaceMetrics; @@ -61,7 +55,6 @@ class UserSpaceMetrics; namespace gfx { class DrawTarget; class GeneralPattern; -class SourceSurface; } } // namespace mozilla diff --git a/layout/tables/SpanningCellSorter.h b/layout/tables/SpanningCellSorter.h index b83e8acf80db..de8c21434528 100644 --- a/layout/tables/SpanningCellSorter.h +++ b/layout/tables/SpanningCellSorter.h @@ -15,8 +15,6 @@ #include "nsDebug.h" #include "StackArena.h" -class nsIPresShell; - /** * The SpanningCellSorter is responsible for accumulating lists of cells * with colspans so that those cells can later be enumerated, sorted diff --git a/layout/tables/nsCellMap.h b/layout/tables/nsCellMap.h index 333892305061..6fe38ddc477d 100644 --- a/layout/tables/nsCellMap.h +++ b/layout/tables/nsCellMap.h @@ -17,7 +17,6 @@ #undef DEBUG_TABLE_CELLMAP -class nsTableColFrame; class nsTableCellFrame; class nsTableRowFrame; class nsTableRowGroupFrame; diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h index 14ccb7870682..5a80baa38353 100644 --- a/layout/tables/nsTableColFrame.h +++ b/layout/tables/nsTableColFrame.h @@ -11,8 +11,6 @@ #include "nsContainerFrame.h" #include "nsTArray.h" -class nsTableCellFrame; - enum nsTableColType { eColContent = 0, // there is real col content associated eColAnonymousCol = 1, // the result of a span on a col diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 6993e5b1af56..dcb55610735b 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -21,7 +21,6 @@ class nsTableCellFrame; class nsTableCellMap; class nsTableColFrame; -class nsColGroupFrame; class nsTableRowGroupFrame; class nsTableRowFrame; class nsTableColGroupFrame; @@ -29,7 +28,6 @@ class nsITableLayoutStrategy; class nsStyleContext; struct nsTableReflowState; -struct nsStylePosition; struct BCPropertyData; static inline bool IS_TABLE_CELL(nsIAtom* frameType) { diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index ffbc2a07d9dc..1c4448503dad 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -15,7 +15,6 @@ class nsTableFrame; class nsTableRowFrame; -class nsTableCellFrame; struct nsRowGroupReflowState { const nsHTMLReflowState& reflowState; // Our reflow state diff --git a/layout/xul/BoxObject.h b/layout/xul/BoxObject.h index 1f7a7113e4e4..39511e47a2da 100644 --- a/layout/xul/BoxObject.h +++ b/layout/xul/BoxObject.h @@ -20,7 +20,6 @@ #include "nsRect.h" class nsIFrame; -class nsIDocShell; class nsIPresShell; namespace mozilla { diff --git a/layout/xul/grid/nsGrid.h b/layout/xul/grid/nsGrid.h index 7be0944c6d4f..b21700ed2866 100644 --- a/layout/xul/grid/nsGrid.h +++ b/layout/xul/grid/nsGrid.h @@ -11,8 +11,6 @@ #include "nsIGridPart.h" #include "nsCOMPtr.h" -class nsGridRowGroupLayout; -class nsGridRowLayout; class nsBoxLayoutState; class nsGridCell; diff --git a/layout/xul/grid/nsGridLayout2.h b/layout/xul/grid/nsGridLayout2.h index 04e231e279fa..9fb9c67e635d 100644 --- a/layout/xul/grid/nsGridLayout2.h +++ b/layout/xul/grid/nsGridLayout2.h @@ -13,12 +13,10 @@ #include "nsCoord.h" #include "nsGrid.h" -class nsIPresContext; class nsGridRowGroupLayout; class nsGridRowLayout; class nsGridRow; class nsBoxLayoutState; -class nsGridCell; /** * The nsBoxLayout implementation for a grid. diff --git a/layout/xul/grid/nsGridRow.h b/layout/xul/grid/nsGridRow.h index 86b983ba5016..e2eadeb7e90a 100644 --- a/layout/xul/grid/nsGridRow.h +++ b/layout/xul/grid/nsGridRow.h @@ -15,8 +15,6 @@ #include "nsCoord.h" -class nsGridLayout2; -class nsBoxLayoutState; class nsIFrame; /** diff --git a/layout/xul/nsBoxLayoutState.h b/layout/xul/nsBoxLayoutState.h index cf07e64094c3..9375b75b45f0 100644 --- a/layout/xul/nsBoxLayoutState.h +++ b/layout/xul/nsBoxLayoutState.h @@ -18,11 +18,7 @@ #include "nsIPresShell.h" class nsRenderingContext; -class nsCalculatedBoxInfo; -class nsHTMLReflowMetrics; struct nsHTMLReflowState; -class nsString; -class nsHTMLReflowCommand; class MOZ_STACK_CLASS nsBoxLayoutState { diff --git a/layout/xul/nsIScrollbarMediator.h b/layout/xul/nsIScrollbarMediator.h index e4de93cc79ad..d25e4d8ccdae 100644 --- a/layout/xul/nsIScrollbarMediator.h +++ b/layout/xul/nsIScrollbarMediator.h @@ -10,7 +10,6 @@ #include "nsCoord.h" class nsScrollbarFrame; -class nsIDOMEventTarget; class nsIFrame; class nsIScrollbarMediator : public nsQueryFrame diff --git a/layout/xul/nsLeafBoxFrame.h b/layout/xul/nsLeafBoxFrame.h index 7631ae353ce4..f0c51e4720a3 100644 --- a/layout/xul/nsLeafBoxFrame.h +++ b/layout/xul/nsLeafBoxFrame.h @@ -9,8 +9,6 @@ #include "nsLeafFrame.h" #include "nsBox.h" -class nsAccessKeyInfo; - class nsLeafBoxFrame : public nsLeafFrame { public: diff --git a/layout/xul/nsMenuFrame.h b/layout/xul/nsMenuFrame.h index 0dc31c949da7..32d3eb6d0316 100644 --- a/layout/xul/nsMenuFrame.h +++ b/layout/xul/nsMenuFrame.h @@ -25,7 +25,6 @@ nsIFrame* NS_NewMenuFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* NS_NewMenuItemFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); class nsIContent; -class nsMenuBarFrame; #define NS_STATE_ACCELTEXT_IS_DERIVED NS_STATE_BOX_CHILD_RESERVED diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h index 2d32c193b844..d68ed46dff75 100644 --- a/layout/xul/nsMenuPopupFrame.h +++ b/layout/xul/nsMenuPopupFrame.h @@ -125,7 +125,6 @@ enum FlipType { nsIFrame* NS_NewMenuPopupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -class nsViewManager; class nsView; class nsMenuPopupFrame; diff --git a/layout/xul/nsResizerFrame.h b/layout/xul/nsResizerFrame.h index e69f5a7c8b34..a339573b0e8a 100644 --- a/layout/xul/nsResizerFrame.h +++ b/layout/xul/nsResizerFrame.h @@ -10,7 +10,6 @@ #include "nsTitleBarFrame.h" class nsIBaseWindow; -class nsMenuPopupFrame; class nsResizerFrame : public nsTitleBarFrame { diff --git a/layout/xul/nsScrollbarButtonFrame.h b/layout/xul/nsScrollbarButtonFrame.h index dbc468568973..017f42fd993c 100644 --- a/layout/xul/nsScrollbarButtonFrame.h +++ b/layout/xul/nsScrollbarButtonFrame.h @@ -18,8 +18,6 @@ #include "nsITimer.h" #include "nsRepeatService.h" -class nsSliderFrame; - class nsScrollbarButtonFrame : public nsButtonBoxFrame { public: diff --git a/layout/xul/nsSliderFrame.h b/layout/xul/nsSliderFrame.h index 216a6704a9e9..2b2a74818f74 100644 --- a/layout/xul/nsSliderFrame.h +++ b/layout/xul/nsSliderFrame.h @@ -14,7 +14,6 @@ #include "nsITimer.h" #include "nsIDOMEventListener.h" -class nsString; class nsITimer; class nsSliderFrame; diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h index faecc546a64f..14c06643807e 100644 --- a/parser/html/nsHtml5TreeBuilderCppSupplement.h +++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h @@ -10,8 +10,6 @@ #include "nsIFrame.h" #include "mozilla/Likely.h" -class nsPresContext; - nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder) : scriptingEnabled(false) , fragment(false) diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h index ec922c1bea27..aaaabc4d92a6 100644 --- a/parser/html/nsHtml5TreeOpExecutor.h +++ b/parser/html/nsHtml5TreeOpExecutor.h @@ -25,8 +25,6 @@ #include "mozilla/net/ReferrerPolicy.h" class nsHtml5Parser; -class nsHtml5TreeBuilder; -class nsHtml5Tokenizer; class nsHtml5StreamParser; class nsIContent; class nsIDocument; diff --git a/parser/html/nsHtml5TreeOperation.h b/parser/html/nsHtml5TreeOperation.h index a5c4928cc25b..8dd486d5a133 100644 --- a/parser/html/nsHtml5TreeOperation.h +++ b/parser/html/nsHtml5TreeOperation.h @@ -12,7 +12,6 @@ class nsIContent; class nsHtml5TreeOpExecutor; -class nsHtml5StateSnapshot; class nsHtml5DocumentBuilder; enum eHtml5TreeOperation { diff --git a/parser/htmlparser/CNavDTD.h b/parser/htmlparser/CNavDTD.h index 8817b591b163..ae08c337c774 100644 --- a/parser/htmlparser/CNavDTD.h +++ b/parser/htmlparser/CNavDTD.h @@ -11,9 +11,6 @@ #include "nsISupports.h" #include "nsCOMPtr.h" -// This class is no longer useful. -class nsIHTMLContentSink; - #ifdef _MSC_VER #pragma warning( disable : 4275 ) #endif diff --git a/parser/htmlparser/nsIDTD.h b/parser/htmlparser/nsIDTD.h index 628c5378c039..cbae4d5071c6 100644 --- a/parser/htmlparser/nsIDTD.h +++ b/parser/htmlparser/nsIDTD.h @@ -46,8 +46,6 @@ enum nsDTDMode { }; -class nsIParser; -class nsIURI; class nsIContentSink; class CParserContext; diff --git a/parser/htmlparser/nsParser.h b/parser/htmlparser/nsParser.h index 858ee23d706f..bd9fcb26bb74 100644 --- a/parser/htmlparser/nsParser.h +++ b/parser/htmlparser/nsParser.h @@ -54,7 +54,6 @@ #include "nsWeakReference.h" class nsIDTD; -class nsScanner; class nsIRunnable; #ifdef _MSC_VER diff --git a/parser/htmlparser/nsScanner.h b/parser/htmlparser/nsScanner.h index f6ac9c33db20..6cdacf1bc85c 100644 --- a/parser/htmlparser/nsScanner.h +++ b/parser/htmlparser/nsScanner.h @@ -25,8 +25,6 @@ #include "nsIUnicodeDecoder.h" #include "nsScannerString.h" -class nsParser; - class nsReadEndCondition { public: const char16_t *mChars; diff --git a/rdf/base/nsRDFXMLSerializer.h b/rdf/base/nsRDFXMLSerializer.h index f6ad9a4551a3..b31a088cd0f6 100644 --- a/rdf/base/nsRDFXMLSerializer.h +++ b/rdf/base/nsRDFXMLSerializer.h @@ -16,7 +16,6 @@ #include "nsDataHashtable.h" #include "rdfITripleVisitor.h" -class nsString; class nsIOutputStream; class nsIRDFContainerUtils; diff --git a/rdf/base/rdfutil.h b/rdf/base/rdfutil.h index 284f8e57ae58..c11581a4a4ae 100644 --- a/rdf/base/rdfutil.h +++ b/rdf/base/rdfutil.h @@ -25,8 +25,6 @@ class nsACString; class nsCString; -class nsString; -class nsIURI; nsresult rdf_MakeRelativeRef(const nsCSubstring& aBaseURI, nsCString& aURI); diff --git a/testing/gtest/gtest/include/gtest/gtest.h b/testing/gtest/gtest/include/gtest/gtest.h index cd01c7ba74d2..333298228454 100644 --- a/testing/gtest/gtest/include/gtest/gtest.h +++ b/testing/gtest/gtest/include/gtest/gtest.h @@ -151,7 +151,6 @@ class AssertHelper; class DefaultGlobalTestPartResultReporter; class ExecDeathTest; class NoExecDeathTest; -class FinalSuccessChecker; class GTestFlagSaver; class TestResultAccessor; class TestEventListenersAccessor; diff --git a/tools/profiler/GeckoProfilerImpl.h b/tools/profiler/GeckoProfilerImpl.h index 16da7dceed38..b81ab98a7f49 100644 --- a/tools/profiler/GeckoProfilerImpl.h +++ b/tools/profiler/GeckoProfilerImpl.h @@ -37,7 +37,6 @@ #endif class TableTicker; -class JSCustomObject; namespace mozilla { class TimeStamp; diff --git a/tools/profiler/PseudoStack.h b/tools/profiler/PseudoStack.h index 3f46b1a301ac..392842b4f418 100644 --- a/tools/profiler/PseudoStack.h +++ b/tools/profiler/PseudoStack.h @@ -75,8 +75,6 @@ class ProfilerMarkerPayload; template class ProfilerLinkedList; class JSStreamWriter; -class JSCustomArray; -class ThreadProfile; class ProfilerMarker { friend class ProfilerLinkedList; public: diff --git a/tools/profiler/TableTicker.h b/tools/profiler/TableTicker.h index c30e7946d41d..24bb26f0f4ff 100644 --- a/tools/profiler/TableTicker.h +++ b/tools/profiler/TableTicker.h @@ -45,8 +45,6 @@ extern mozilla::TimeStamp sLastTracerEvent; extern int sFrameNumber; extern int sLastFrameNumber; -class BreakpadSampler; - class TableTicker: public Sampler { public: TableTicker(double aInterval, int aEntrySize, From ade28310357b1ad29bfea96c548db278a639d0f6 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 08:29:24 +0200 Subject: [PATCH 086/241] Bug 1156632 - Remove unused forward class declarations - patch 6 - the rest of the tree, r=ehsan --- docshell/base/IHistory.h | 1 - docshell/base/LoadContext.h | 2 -- docshell/base/nsDocShell.h | 1 - docshell/base/nsILinkHandler.h | 1 - gfx/2d/2D.h | 1 - gfx/2d/DrawTargetD2D1.h | 2 -- gfx/2d/PathCairo.h | 1 - gfx/2d/QuartzSupport.h | 1 - gfx/2d/ScaledFontBase.h | 2 -- gfx/2d/SourceSurfaceSkia.h | 2 -- gfx/gl/AndroidSurfaceTexture.h | 2 -- gfx/gl/GLContext.h | 4 ---- gfx/gl/TextureImageCGL.h | 2 -- gfx/layers/Compositor.h | 1 - gfx/layers/CopyableCanvasLayer.h | 7 +++++-- gfx/layers/ImageContainer.h | 3 --- gfx/layers/LayerTreeInvalidation.h | 2 -- gfx/layers/Layers.h | 6 ------ gfx/layers/LayersTypes.h | 1 - gfx/layers/apz/src/APZCTreeManager.h | 1 - gfx/layers/apz/src/InputQueue.h | 1 - gfx/layers/apz/util/ActiveElementManager.h | 1 - gfx/layers/apz/util/ChromeProcessController.h | 1 - gfx/layers/basic/BasicCanvasLayer.h | 2 -- gfx/layers/basic/BasicCompositor.h | 2 -- gfx/layers/basic/BasicImplData.h | 1 - gfx/layers/basic/BasicLayers.h | 3 --- gfx/layers/basic/BasicLayersImpl.h | 1 - gfx/layers/client/ClientPaintedLayer.h | 2 -- gfx/layers/client/ClientTiledPaintedLayer.h | 2 -- gfx/layers/client/CompositableClient.h | 1 - gfx/layers/client/ContentClient.h | 3 --- gfx/layers/client/TextureClient.h | 3 --- gfx/layers/client/TiledContentClient.h | 1 - gfx/layers/composite/CompositableHost.h | 2 -- gfx/layers/composite/ContentHost.h | 1 - gfx/layers/composite/FPSCounter.h | 4 ---- gfx/layers/composite/ImageHost.h | 1 - gfx/layers/composite/LayerManagerComposite.h | 6 ------ gfx/layers/composite/TextureHost.h | 3 --- gfx/layers/composite/TiledContentHost.h | 2 -- gfx/layers/d3d11/TextureD3D11.h | 2 -- gfx/layers/d3d9/DeviceManagerD3D9.h | 1 - gfx/layers/ipc/CompositableForwarder.h | 1 - gfx/layers/ipc/CompositableTransactionParent.h | 1 - gfx/layers/ipc/CompositorChild.h | 2 -- gfx/layers/ipc/CompositorParent.h | 1 - gfx/layers/ipc/ISurfaceAllocator.h | 8 -------- gfx/layers/ipc/ImageBridgeChild.h | 1 - gfx/layers/ipc/ShadowLayerParent.h | 1 - gfx/layers/ipc/ShadowLayerUtilsGralloc.h | 1 - gfx/layers/ipc/ShadowLayers.h | 17 ----------------- gfx/layers/ipc/SharedPlanarYCbCrImage.h | 2 -- gfx/layers/ipc/SharedRGBImage.h | 6 ------ gfx/layers/opengl/Composer2D.h | 5 ----- gfx/layers/opengl/CompositorOGL.h | 1 - gfx/layers/opengl/TextureClientOGL.h | 2 -- gfx/layers/opengl/TextureHostOGL.h | 2 -- gfx/src/FilterSupport.h | 1 - gfx/src/nsColor.h | 1 - gfx/src/nsITheme.h | 2 -- gfx/thebes/gfx2DGlue.h | 8 -------- gfx/thebes/gfxAndroidPlatform.h | 2 -- gfx/thebes/gfxBlur.h | 1 - gfx/thebes/gfxDrawable.h | 1 - gfx/thebes/gfxPattern.h | 2 -- gfx/thebes/gfxPlatform.h | 2 -- gfx/thebes/gfxQtNativeRenderer.h | 2 -- gfx/thebes/gfxWindowsPlatform.h | 2 -- storage/src/StorageBaseStatementInternal.h | 1 - storage/src/mozStorageAsyncStatement.h | 1 - storage/src/mozStorageAsyncStatementParams.h | 2 -- storage/src/mozStorageConnection.h | 1 - storage/src/mozStoragePrivateHelpers.h | 2 -- widget/PuppetWidget.h | 2 -- widget/android/AndroidBridge.h | 6 ------ widget/android/AndroidJavaWrappers.h | 1 - widget/android/GfxInfo.h | 4 ---- widget/cocoa/nsAppShell.h | 2 -- widget/cocoa/nsChildView.h | 1 - widget/cocoa/nsMenuBarX.h | 1 - widget/cocoa/nsMenuGroupOwnerX.h | 2 -- widget/gonk/HwcComposer2D.h | 1 - widget/gonk/libdisplay/FramebufferSurface.h | 1 - widget/gonk/libdisplay/GonkDisplay.h | 4 ---- .../GonkBufferQueueLL/GonkBufferQueueProducer.h | 2 -- widget/gonk/nsWindow.h | 14 -------------- widget/gtk/nsPSPrinters.h | 2 -- widget/gtk/nsWindow.h | 1 - widget/nsBaseClipboard.h | 1 - widget/nsBaseDragService.h | 2 -- widget/nsIWidget.h | 3 --- widget/nsPrintOptionsImpl.h | 1 - widget/nsTransferable.h | 1 - widget/qt/nsWindow.h | 1 - widget/windows/KeyboardLayout.h | 1 - widget/windows/nsClipboard.h | 1 - widget/windows/nsDataObjCollection.h | 2 -- widget/windows/nsDragService.h | 3 --- widget/windows/nsNativeDragTarget.h | 2 -- widget/windows/nsTextStore.h | 4 ---- widget/windows/nsWindow.h | 2 -- xpcom/base/nsMemoryInfoDumper.h | 2 -- xpcom/build/Omnijar.h | 2 -- xpcom/build/nsXPCOMPrivate.h | 1 - xpcom/components/ManifestParser.h | 2 -- xpcom/ds/nsObserverList.h | 4 ---- xpcom/glue/nsCOMPtr.h | 3 --- xpcom/reflect/xptinfo/ShimInterfaceInfo.h | 1 - xpcom/reflect/xptinfo/xptinfo.h | 2 -- 110 files changed, 5 insertions(+), 251 deletions(-) diff --git a/docshell/base/IHistory.h b/docshell/base/IHistory.h index bdaa85238a7d..b913bed37e44 100644 --- a/docshell/base/IHistory.h +++ b/docshell/base/IHistory.h @@ -10,7 +10,6 @@ #include "nsISupports.h" class nsIURI; -class nsString; namespace mozilla { diff --git a/docshell/base/LoadContext.h b/docshell/base/LoadContext.h index 1ab5cba4144b..22fd28583dad 100644 --- a/docshell/base/LoadContext.h +++ b/docshell/base/LoadContext.h @@ -14,8 +14,6 @@ #include "nsIInterfaceRequestor.h" #include "nsILoadContext.h" -class mozIApplication; - namespace mozilla { /** diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 317bd9628ef9..a590c6d239df 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -88,7 +88,6 @@ class nsIURIFixup; class nsIURILoader; class nsIWebBrowserFind; class nsIWidget; -class ProfilerMarkerTracing; /* load commands were moved to nsIDocShell.h */ /* load types were moved to nsDocShellLoadTypes.h */ diff --git a/docshell/base/nsILinkHandler.h b/docshell/base/nsILinkHandler.h index 862a6bcb52ce..797b3fe13402 100644 --- a/docshell/base/nsILinkHandler.h +++ b/docshell/base/nsILinkHandler.h @@ -13,7 +13,6 @@ class nsIContent; class nsIDocShell; class nsIInputStream; class nsIRequest; -class nsString; // Interface ID for nsILinkHandler #define NS_ILINKHANDLER_IID \ diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 4a7c6f022d13..9bae3a3f61a7 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -44,7 +44,6 @@ struct ID2D1Device; struct IDWriteRenderingParams; class GrContext; -struct GrGLInterface; struct CGContext; typedef struct CGContext *CGContextRef; diff --git a/gfx/2d/DrawTargetD2D1.h b/gfx/2d/DrawTargetD2D1.h index 447a3e230e7f..eb8010d3dbee 100644 --- a/gfx/2d/DrawTargetD2D1.h +++ b/gfx/2d/DrawTargetD2D1.h @@ -23,8 +23,6 @@ namespace mozilla { namespace gfx { class SourceSurfaceD2D1; -class GradientStopsD2D; -class ScaledFontDWrite; const int32_t kLayerCacheSize1 = 5; diff --git a/gfx/2d/PathCairo.h b/gfx/2d/PathCairo.h index 898181242c77..0f315bb3cff7 100644 --- a/gfx/2d/PathCairo.h +++ b/gfx/2d/PathCairo.h @@ -13,7 +13,6 @@ namespace mozilla { namespace gfx { -class DrawTargetCairo; class PathCairo; class PathBuilderCairo : public PathBuilder diff --git a/gfx/2d/QuartzSupport.h b/gfx/2d/QuartzSupport.h index a85c8e2d902f..60a5b9c299ea 100644 --- a/gfx/2d/QuartzSupport.h +++ b/gfx/2d/QuartzSupport.h @@ -20,7 +20,6 @@ CGColorSpaceRef CreateSystemColorSpace(); // Manages a CARenderer -struct _CGLPBufferObject; struct _CGLContextObject; enum AllowOfflineRendererEnum { ALLOW_OFFLINE_RENDERER, DISALLOW_OFFLINE_RENDERER }; diff --git a/gfx/2d/ScaledFontBase.h b/gfx/2d/ScaledFontBase.h index 93f4441be3ac..4251828b0ad7 100644 --- a/gfx/2d/ScaledFontBase.h +++ b/gfx/2d/ScaledFontBase.h @@ -21,8 +21,6 @@ #include "cairo.h" #endif -class gfxFont; - namespace mozilla { namespace gfx { diff --git a/gfx/2d/SourceSurfaceSkia.h b/gfx/2d/SourceSurfaceSkia.h index de57602b4155..d13d38737596 100644 --- a/gfx/2d/SourceSurfaceSkia.h +++ b/gfx/2d/SourceSurfaceSkia.h @@ -11,8 +11,6 @@ #include "skia/SkCanvas.h" #include "skia/SkBitmap.h" -class GrContext; - namespace mozilla { namespace gfx { diff --git a/gfx/gl/AndroidSurfaceTexture.h b/gfx/gl/AndroidSurfaceTexture.h index d128656228ae..3b1ca1a1fbd8 100644 --- a/gfx/gl/AndroidSurfaceTexture.h +++ b/gfx/gl/AndroidSurfaceTexture.h @@ -18,8 +18,6 @@ #include "SurfaceTexture.h" #include "AndroidNativeWindow.h" -class gfxASurface; - namespace mozilla { namespace gfx { class Matrix4x4; diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 4fbb585c9785..4656ddcc9558 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -51,10 +51,6 @@ #include "gfx2DGlue.h" #include "GeckoProfiler.h" -class nsIntRegion; -class nsIRunnable; -class nsIThread; - namespace android { class GraphicBuffer; } diff --git a/gfx/gl/TextureImageCGL.h b/gfx/gl/TextureImageCGL.h index 3f3e4908e1e6..395252f6be4b 100644 --- a/gfx/gl/TextureImageCGL.h +++ b/gfx/gl/TextureImageCGL.h @@ -11,8 +11,6 @@ #include "nsAutoPtr.h" #include "nsSize.h" -class gfxASurface; - namespace mozilla { namespace gl { diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index 031c285b5725..5faa7f0d66d7 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -120,7 +120,6 @@ namespace layers { struct Effect; struct EffectChain; class Image; -class ISurfaceAllocator; class Layer; class TextureSource; class DataTextureSource; diff --git a/gfx/layers/CopyableCanvasLayer.h b/gfx/layers/CopyableCanvasLayer.h index 6ed1510af94d..c3c2ceb10085 100644 --- a/gfx/layers/CopyableCanvasLayer.h +++ b/gfx/layers/CopyableCanvasLayer.h @@ -21,9 +21,12 @@ #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc namespace mozilla { -namespace layers { -class CanvasClientWebGL; +namespace gl { +class SharedSurface; +} + +namespace layers { /** * A shared CanvasLayer implementation that supports copying diff --git a/gfx/layers/ImageContainer.h b/gfx/layers/ImageContainer.h index fc93fc2d763e..fb26e05d0772 100644 --- a/gfx/layers/ImageContainer.h +++ b/gfx/layers/ImageContainer.h @@ -95,7 +95,6 @@ typedef void* HANDLE; namespace mozilla { -class CrossProcessMutex; namespace layers { @@ -103,8 +102,6 @@ class ImageClient; class SharedPlanarYCbCrImage; class TextureClient; class CompositableClient; -class CompositableForwarder; -class SurfaceDescriptor; class GrallocImage; struct ImageBackendData diff --git a/gfx/layers/LayerTreeInvalidation.h b/gfx/layers/LayerTreeInvalidation.h index 1d6b2af0fe70..d262480380a7 100644 --- a/gfx/layers/LayerTreeInvalidation.h +++ b/gfx/layers/LayerTreeInvalidation.h @@ -10,8 +10,6 @@ #include "mozilla/UniquePtr.h" // for UniquePtr #include "mozilla/gfx/Point.h" -class nsPresContext; - namespace mozilla { namespace layers { diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 962c7bcc4cc2..c02cb07b477d 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -57,11 +57,9 @@ namespace mozilla { class ComputedTimingFunction; class FrameLayerBuilder; class StyleAnimationValue; -class WebGLContext; namespace gl { class GLContext; -class SharedSurface; } namespace gfx { @@ -78,7 +76,6 @@ class Animation; class AnimationData; class AsyncPanZoomController; class ClientLayerManager; -class CommonLayerAttributes; class Layer; class LayerMetricsWrapper; class PaintedLayer; @@ -95,10 +92,7 @@ class ShadowableLayer; class ShadowLayerForwarder; class LayerManagerComposite; class SpecificLayerAttributes; -class SurfaceDescriptor; class Compositor; -struct TextureFactoryIdentifier; -struct EffectMask; namespace layerscope { class LayersPacket; diff --git a/gfx/layers/LayersTypes.h b/gfx/layers/LayersTypes.h index d79c438987f9..d8d3eda9eb07 100644 --- a/gfx/layers/LayersTypes.h +++ b/gfx/layers/LayersTypes.h @@ -26,7 +26,6 @@ # define MOZ_LAYERS_LOG_IF_SHADOWABLE(layer, _args) \ do { if (layer->AsShadowableLayer()) { PR_LOG(LayerManager::GetLog(), PR_LOG_DEBUG, _args); } } while (0) #else -struct PRLogModuleInfo; # define MOZ_LAYERS_LOG(_args) # define MOZ_LAYERS_LOG_IF_SHADOWABLE(layer, _args) #endif // if defined(DEBUG) || defined(PR_LOGGING) diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index 09c6722f9201..5403e1fa4776 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -41,7 +41,6 @@ enum AllowedTouchBehavior { class Layer; class AsyncPanZoomController; class CompositorParent; -class APZPaintLogHelper; class OverscrollHandoffChain; struct OverscrollHandoffState; class LayerMetricsWrapper; diff --git a/gfx/layers/apz/src/InputQueue.h b/gfx/layers/apz/src/InputQueue.h index a268992bdab4..eb216497c79d 100644 --- a/gfx/layers/apz/src/InputQueue.h +++ b/gfx/layers/apz/src/InputQueue.h @@ -20,7 +20,6 @@ class ScrollWheelInput; namespace layers { class AsyncPanZoomController; -class OverscrollHandoffChain; class CancelableBlockState; class TouchBlockState; class WheelBlockState; diff --git a/gfx/layers/apz/util/ActiveElementManager.h b/gfx/layers/apz/util/ActiveElementManager.h index 65d4287f4192..addac185e88b 100644 --- a/gfx/layers/apz/util/ActiveElementManager.h +++ b/gfx/layers/apz/util/ActiveElementManager.h @@ -9,7 +9,6 @@ #include "nsCOMPtr.h" #include "nsISupportsImpl.h" -class inIDOMUtils; class CancelableTask; namespace mozilla { diff --git a/gfx/layers/apz/util/ChromeProcessController.h b/gfx/layers/apz/util/ChromeProcessController.h index 24df410fc2e1..19e301d1f3e9 100644 --- a/gfx/layers/apz/util/ChromeProcessController.h +++ b/gfx/layers/apz/util/ChromeProcessController.h @@ -22,7 +22,6 @@ namespace mozilla { namespace layers { class APZEventState; -class CompositorParent; // A ChromeProcessController is attached to the root of a compositor's layer // tree. diff --git a/gfx/layers/basic/BasicCanvasLayer.h b/gfx/layers/basic/BasicCanvasLayer.h index 50e405fe923f..b7326b5a56cb 100644 --- a/gfx/layers/basic/BasicCanvasLayer.h +++ b/gfx/layers/basic/BasicCanvasLayer.h @@ -13,8 +13,6 @@ #include "nsDebug.h" // for NS_ASSERTION #include "nsRegion.h" // for nsIntRegion -class gfxContext; - namespace mozilla { namespace layers { diff --git a/gfx/layers/basic/BasicCompositor.h b/gfx/layers/basic/BasicCompositor.h index 07b0061ad885..0fdb7819af6f 100644 --- a/gfx/layers/basic/BasicCompositor.h +++ b/gfx/layers/basic/BasicCompositor.h @@ -11,8 +11,6 @@ #include "mozilla/gfx/2D.h" #include "nsAutoPtr.h" -class gfxContext; - namespace mozilla { namespace layers { diff --git a/gfx/layers/basic/BasicImplData.h b/gfx/layers/basic/BasicImplData.h index 6e73da76dc6d..202ba1b8fb02 100644 --- a/gfx/layers/basic/BasicImplData.h +++ b/gfx/layers/basic/BasicImplData.h @@ -15,7 +15,6 @@ namespace mozilla { namespace layers { class ReadbackProcessor; -class SurfaceDescriptor; /** * This is the ImplData for all Basic layers. It also exposes methods diff --git a/gfx/layers/basic/BasicLayers.h b/gfx/layers/basic/BasicLayers.h index 8bf6e81940d6..8f709757d7b5 100644 --- a/gfx/layers/basic/BasicLayers.h +++ b/gfx/layers/basic/BasicLayers.h @@ -20,18 +20,15 @@ #include "nsRegion.h" // for nsIntRegion #include "nscore.h" // for nsAString, etc -class gfxPattern; class nsIWidget; namespace mozilla { namespace layers { -class BasicShadowableLayer; class ImageFactory; class ImageLayer; class PaintLayerContext; class ReadbackLayer; -class ReadbackProcessor; /** * This is a cairo/Thebes-only, main-thread-only implementation of layers. diff --git a/gfx/layers/basic/BasicLayersImpl.h b/gfx/layers/basic/BasicLayersImpl.h index c6f29ba0340a..b9ae4b0ad6c9 100644 --- a/gfx/layers/basic/BasicLayersImpl.h +++ b/gfx/layers/basic/BasicLayersImpl.h @@ -25,7 +25,6 @@ class DrawTarget; namespace layers { class AutoMoz2DMaskData; -class BasicContainerLayer; class Layer; class AutoSetOperator { diff --git a/gfx/layers/client/ClientPaintedLayer.h b/gfx/layers/client/ClientPaintedLayer.h index b8f2b7496160..54a6e9476a9e 100644 --- a/gfx/layers/client/ClientPaintedLayer.h +++ b/gfx/layers/client/ClientPaintedLayer.h @@ -18,8 +18,6 @@ #include "nsRegion.h" // for nsIntRegion #include "mozilla/layers/PLayerTransaction.h" // for PaintedLayerAttributes -class gfxContext; - namespace mozilla { namespace layers { diff --git a/gfx/layers/client/ClientTiledPaintedLayer.h b/gfx/layers/client/ClientTiledPaintedLayer.h index 57999a2baddd..40b0ed467d29 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.h +++ b/gfx/layers/client/ClientTiledPaintedLayer.h @@ -12,8 +12,6 @@ #include "nsDebug.h" // for NS_RUNTIMEABORT #include "nsRegion.h" // for nsIntRegion -class gfxContext; - namespace mozilla { namespace layers { diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 14f451badc2f..75a88991bf09 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -27,7 +27,6 @@ class BufferTextureClient; class ImageBridgeChild; class CompositableForwarder; class CompositableChild; -class SurfaceDescriptor; class PCompositableChild; /** diff --git a/gfx/layers/client/ContentClient.h b/gfx/layers/client/ContentClient.h index 5778ec98dd92..f23ddcb80aa2 100644 --- a/gfx/layers/client/ContentClient.h +++ b/gfx/layers/client/ContentClient.h @@ -28,8 +28,6 @@ #include "nsRegion.h" // for nsIntRegion #include "nsTArray.h" // for nsTArray -class gfxContext; - namespace mozilla { namespace gfx { class DrawTarget; @@ -37,7 +35,6 @@ class DrawTarget; namespace layers { -class BasicLayerManager; class PaintedLayer; /** diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index b6355fd6a0b0..ae6095666824 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -29,7 +29,6 @@ #include "nsISupportsImpl.h" // for TextureImage::AddRef, etc #include "GfxTexturesReporter.h" -class gfxReusableSurfaceWrapper; class gfxImageSurface; namespace mozilla { @@ -47,11 +46,9 @@ class SharedSurface; namespace layers { class AsyncTransactionTracker; -class ContentClient; class CompositableForwarder; class ISurfaceAllocator; class CompositableClient; -class PlanarYCbCrImage; struct PlanarYCbCrData; class Image; class PTextureChild; diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h index b54b0a95efdb..41156efb8390 100644 --- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -41,7 +41,6 @@ namespace mozilla { namespace layers { -class BasicTileDescriptor; class ClientTiledPaintedLayer; class ClientLayerManager; diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 3624ceb26965..52e1e1cec2a1 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -37,9 +37,7 @@ class DataSourceSurface; namespace layers { class Layer; -class SurfaceDescriptor; class Compositor; -class ISurfaceAllocator; class ThebesBufferData; class TiledLayerComposer; class CompositableParentManager; diff --git a/gfx/layers/composite/ContentHost.h b/gfx/layers/composite/ContentHost.h index cb7854ed2b1e..2723a4df530c 100644 --- a/gfx/layers/composite/ContentHost.h +++ b/gfx/layers/composite/ContentHost.h @@ -42,7 +42,6 @@ class Compositor; class ThebesBufferData; class TiledLayerComposer; struct EffectChain; -class TextureImageTextureSourceOGL; struct TexturedEffect; diff --git a/gfx/layers/composite/FPSCounter.h b/gfx/layers/composite/FPSCounter.h index 2a493d3e4f01..f1a3cd58610c 100644 --- a/gfx/layers/composite/FPSCounter.h +++ b/gfx/layers/composite/FPSCounter.h @@ -16,13 +16,9 @@ #include "prio.h" // for NSPR file i/o namespace mozilla { -namespace gl { -class GLContext; -} namespace layers { class DataTextureSource; -class ShaderProgramOGL; class Compositor; // Dump the FPS histogram every 10 seconds or kMaxFrameFPS diff --git a/gfx/layers/composite/ImageHost.h b/gfx/layers/composite/ImageHost.h index 5bd4930a5b97..3c23d653ffd3 100644 --- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -31,7 +31,6 @@ class Matrix4x4; namespace layers { class Compositor; -class ISurfaceAllocator; struct EffectChain; /** diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 34b851079afe..f7f477cf7f3f 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -43,11 +43,6 @@ namespace gfx { class DrawTarget; } -namespace gl { -class GLContext; -class TextureImage; -} - namespace layers { class CanvasLayerComposite; @@ -60,7 +55,6 @@ class ImageLayer; class ImageLayerComposite; class LayerComposite; class RefLayerComposite; -class SurfaceDescriptor; class PaintedLayerComposite; class TiledLayerComposer; class TextRenderer; diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index c734a64a121f..68e8093385d5 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -30,8 +30,6 @@ #include "mozilla/layers/AtomicRefCountedWithFinalize.h" #include "mozilla/gfx/Rect.h" -class gfxReusableSurfaceWrapper; - namespace mozilla { namespace gl { class SharedSurface; @@ -43,7 +41,6 @@ class Shmem; namespace layers { class Compositor; -class CompositableHost; class CompositableParentManager; class SurfaceDescriptor; class SharedSurfaceDescriptor; diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index 6281aa9e3a89..13a89a20797d 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -31,8 +31,6 @@ #include #endif -class gfxReusableSurfaceWrapper; - namespace mozilla { namespace gfx { class Matrix4x4; diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index 906ff1e70599..c47830dc5b45 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -14,8 +14,6 @@ #include #include -class gfxD2DSurface; - namespace mozilla { namespace layers { diff --git a/gfx/layers/d3d9/DeviceManagerD3D9.h b/gfx/layers/d3d9/DeviceManagerD3D9.h index 18419aba22e4..b773e2195a6b 100644 --- a/gfx/layers/d3d9/DeviceManagerD3D9.h +++ b/gfx/layers/d3d9/DeviceManagerD3D9.h @@ -18,7 +18,6 @@ namespace mozilla { namespace layers { class DeviceManagerD3D9; -class LayerD3D9; class Nv3DVUtils; class Layer; class TextureSourceD3D9; diff --git a/gfx/layers/ipc/CompositableForwarder.h b/gfx/layers/ipc/CompositableForwarder.h index 3f08962b94cf..63a283403f27 100644 --- a/gfx/layers/ipc/CompositableForwarder.h +++ b/gfx/layers/ipc/CompositableForwarder.h @@ -26,7 +26,6 @@ struct TextureFactoryIdentifier; class SurfaceDescriptor; class SurfaceDescriptorTiles; class ThebesBufferData; -class ClientTiledLayerBuffer; class PTextureChild; /** diff --git a/gfx/layers/ipc/CompositableTransactionParent.h b/gfx/layers/ipc/CompositableTransactionParent.h index c9541c270e82..958923c87e9d 100644 --- a/gfx/layers/ipc/CompositableTransactionParent.h +++ b/gfx/layers/ipc/CompositableTransactionParent.h @@ -18,7 +18,6 @@ namespace mozilla { namespace layers { class CompositableHost; -class PTextureChild; typedef std::vector EditReplyVector; diff --git a/gfx/layers/ipc/CompositorChild.h b/gfx/layers/ipc/CompositorChild.h index 09a9249ec51f..78d2d0e167ed 100644 --- a/gfx/layers/ipc/CompositorChild.h +++ b/gfx/layers/ipc/CompositorChild.h @@ -20,8 +20,6 @@ #include "ThreadSafeRefcountingWithMainThreadDestruction.h" #include "nsWeakReference.h" -class nsIObserver; - namespace mozilla { namespace dom { diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index e673d014b43f..5e86a22be288 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -39,7 +39,6 @@ class CancelableTask; class MessageLoop; -class gfxContext; class nsIWidget; namespace mozilla { diff --git a/gfx/layers/ipc/ISurfaceAllocator.h b/gfx/layers/ipc/ISurfaceAllocator.h index e7f7a5697297..afb3e344ab2c 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.h +++ b/gfx/layers/ipc/ISurfaceAllocator.h @@ -30,12 +30,6 @@ #define MOZ_HAVE_SURFACEDESCRIPTORGRALLOC #endif -class gfxSharedImageSurface; - -namespace base { -class Thread; -} - namespace mozilla { namespace ipc { class Shmem; @@ -47,8 +41,6 @@ class DataSourceSurface; namespace layers { class MaybeMagicGrallocBufferHandle; -class MemoryTextureClient; -class MemoryTextureHost; enum BufferCapabilities { DEFAULT_BUFFER_CAPS = 0, diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index 39fec3bd6772..26ab9eff4aa2 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -32,7 +32,6 @@ class Shmem; namespace layers { -class ClientTiledLayerBuffer; class AsyncTransactionTracker; class ImageClient; class ImageContainer; diff --git a/gfx/layers/ipc/ShadowLayerParent.h b/gfx/layers/ipc/ShadowLayerParent.h index 73029c5c28d7..01d24df73038 100644 --- a/gfx/layers/ipc/ShadowLayerParent.h +++ b/gfx/layers/ipc/ShadowLayerParent.h @@ -18,7 +18,6 @@ namespace layers { class ContainerLayer; class Layer; -class LayerManager; class CanvasLayerComposite; class ColorLayerComposite; diff --git a/gfx/layers/ipc/ShadowLayerUtilsGralloc.h b/gfx/layers/ipc/ShadowLayerUtilsGralloc.h index 0200af9e86f3..6a1aaed5d73e 100644 --- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.h +++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.h @@ -22,7 +22,6 @@ namespace layers { class MaybeMagicGrallocBufferHandle; class SurfaceDescriptor; -class TextureHost; struct GrallocBufferRef { base::ProcessId mOwner; diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 81cf4bd34e78..fd59262da070 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -26,33 +26,16 @@ namespace mozilla { namespace layers { -class ClientTiledLayerBuffer; -class CanvasClient; -class CanvasLayerComposite; -class CanvasSurface; -class ColorLayerComposite; -class CompositableChild; -class ContainerLayerComposite; -class ContentClient; -class ContentClientRemote; class EditReply; -class ImageClient; -class ImageLayerComposite; class Layer; -class OptionalThebesBuffer; class PLayerChild; class PLayerTransactionChild; -class PLayerTransactionParent; class LayerTransactionChild; -class RefLayerComposite; class ShadowableLayer; -class ShmemTextureClient; class SurfaceDescriptor; class TextureClient; -class PaintedLayerComposite; class ThebesBuffer; class ThebesBufferData; -class TiledLayerComposer; class Transaction; diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.h b/gfx/layers/ipc/SharedPlanarYCbCrImage.h index 7fa277bd1da2..8c3d39cda6ec 100644 --- a/gfx/layers/ipc/SharedPlanarYCbCrImage.h +++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.h @@ -20,8 +20,6 @@ namespace layers { class BufferTextureClient; class ImageClient; -class ISurfaceAllocator; -class SurfaceDescriptor; class TextureClient; class SharedPlanarYCbCrImage : public PlanarYCbCrImage diff --git a/gfx/layers/ipc/SharedRGBImage.h b/gfx/layers/ipc/SharedRGBImage.h index 255fcda3bdfb..d55f96e62449 100644 --- a/gfx/layers/ipc/SharedRGBImage.h +++ b/gfx/layers/ipc/SharedRGBImage.h @@ -16,17 +16,11 @@ #include "nsCOMPtr.h" // for already_AddRefed namespace mozilla { -namespace ipc { -class Shmem; -} - namespace layers { class BufferTextureClient; class ImageClient; -class ISurfaceAllocator; class TextureClient; -class SurfaceDescriptor; already_AddRefed CreateSharedRGBImage(ImageContainer* aImageContainer, nsIntSize aSize, diff --git a/gfx/layers/opengl/Composer2D.h b/gfx/layers/opengl/Composer2D.h index 698d2469ddce..78c34c4befd3 100644 --- a/gfx/layers/opengl/Composer2D.h +++ b/gfx/layers/opengl/Composer2D.h @@ -27,11 +27,6 @@ */ namespace mozilla { - -namespace gfx { -class Matrix; -} - namespace layers { class Layer; diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 94f7205ded7a..2893a157e32b 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -40,7 +40,6 @@ class nsIWidget; namespace mozilla { -class TimeStamp; namespace gfx { class Matrix4x4; diff --git a/gfx/layers/opengl/TextureClientOGL.h b/gfx/layers/opengl/TextureClientOGL.h index 9631d15b6cfb..55d2e5e5ae21 100644 --- a/gfx/layers/opengl/TextureClientOGL.h +++ b/gfx/layers/opengl/TextureClientOGL.h @@ -20,8 +20,6 @@ namespace mozilla { namespace layers { -class CompositableForwarder; - class EGLImageTextureClient : public TextureClient { public: diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h index 1859178ca4c3..3aeb4d9becd5 100644 --- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -37,7 +37,6 @@ #endif #endif -class gfxReusableSurfaceWrapper; class nsIntRegion; namespace mozilla { @@ -54,7 +53,6 @@ namespace layers { class Compositor; class CompositorOGL; class TextureImageTextureSourceOGL; -class TextureSharedDataGonkOGL; class GLTextureSource; inline void ApplyFilterToBoundTexture(gl::GLContext* aGL, diff --git a/gfx/src/FilterSupport.h b/gfx/src/FilterSupport.h index 4441250a84ac..44724ca81fa0 100644 --- a/gfx/src/FilterSupport.h +++ b/gfx/src/FilterSupport.h @@ -158,7 +158,6 @@ enum AttributeName { class DrawTarget; class SourceSurface; -class FilterNode; struct FilterAttribute; enum class AttributeType { diff --git a/gfx/src/nsColor.h b/gfx/src/nsColor.h index ca6603fc32fa..24769542e734 100644 --- a/gfx/src/nsColor.h +++ b/gfx/src/nsColor.h @@ -13,7 +13,6 @@ class nsAString; class nsString; -class nsCString; // A color is a 32 bit unsigned integer with four components: R, G, B // and A. diff --git a/gfx/src/nsITheme.h b/gfx/src/nsITheme.h index 1ef57a4f0a2c..79572d30c480 100644 --- a/gfx/src/nsITheme.h +++ b/gfx/src/nsITheme.h @@ -15,13 +15,11 @@ #include "Units.h" struct nsRect; -struct nsFont; struct nsIntMargin; class nsPresContext; class nsRenderingContext; class nsDeviceContext; class nsIFrame; -class nsIContent; class nsIAtom; class nsIWidget; diff --git a/gfx/thebes/gfx2DGlue.h b/gfx/thebes/gfx2DGlue.h index 520c5409c9ae..4c5e09518de0 100644 --- a/gfx/thebes/gfx2DGlue.h +++ b/gfx/thebes/gfx2DGlue.h @@ -16,14 +16,6 @@ #include "mozilla/gfx/2D.h" #include "gfxColor.h" -namespace mozilla { -namespace gfx { -class DrawTarget; -class SourceSurface; -class ScaledFont; -} -} - namespace mozilla { namespace gfx { diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index edbf4a5d37f4..2f63eedc4b2e 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -12,8 +12,6 @@ #include "nsCOMPtr.h" #include "nsTArray.h" -class nsIMemoryReporter; - namespace mozilla { namespace dom { class FontListEntry; diff --git a/gfx/thebes/gfxBlur.h b/gfx/thebes/gfxBlur.h index bac188ba1369..8400a8137688 100644 --- a/gfx/thebes/gfxBlur.h +++ b/gfx/thebes/gfxBlur.h @@ -16,7 +16,6 @@ class gfxContext; struct gfxRect; struct gfxRGBA; -class gfxMatrix; namespace mozilla { namespace gfx { diff --git a/gfx/thebes/gfxDrawable.h b/gfx/thebes/gfxDrawable.h index 703aff4f99b9..306771200e5e 100644 --- a/gfx/thebes/gfxDrawable.h +++ b/gfx/thebes/gfxDrawable.h @@ -12,7 +12,6 @@ #include "GraphicsFilter.h" #include "mozilla/gfx/2D.h" -class gfxASurface; class gfxContext; class gfxPattern; diff --git a/gfx/thebes/gfxPattern.h b/gfx/thebes/gfxPattern.h index 5ceea203b6f8..00837c71be25 100644 --- a/gfx/thebes/gfxPattern.h +++ b/gfx/thebes/gfxPattern.h @@ -17,8 +17,6 @@ #include "nsAutoPtr.h" #include "nsTArray.h" -class gfxContext; -class gfxASurface; struct gfxRGBA; typedef struct _cairo_pattern cairo_pattern_t; diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index d5efd2d36f13..17e1753dd4b2 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -38,11 +38,9 @@ class nsIURI; class nsIAtom; class nsIObserver; class SRGBOverrideObserver; -struct gfxRGBA; namespace mozilla { namespace gl { -class GLContext; class SkiaGLGlue; } namespace gfx { diff --git a/gfx/thebes/gfxQtNativeRenderer.h b/gfx/thebes/gfxQtNativeRenderer.h index 393ce4a710c6..1b58caa1a2a3 100644 --- a/gfx/thebes/gfxQtNativeRenderer.h +++ b/gfx/thebes/gfxQtNativeRenderer.h @@ -11,8 +11,6 @@ #include "gfxXlibSurface.h" #include "mozilla/gfx/Rect.h" -class QRect; - /** * This class lets us take code that draws into an Xlib surface drawable and lets us * use it to draw into any Thebes context. The user should subclass this class, diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 212e19598eef..81f77eb31b26 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -57,8 +57,6 @@ struct IDirect3DDevice9; struct ID3D11Device; struct IDXGIAdapter1; -class nsIMemoryReporter; - /** * Utility to get a Windows HDC from a Moz2D DrawTarget. If the DrawTarget is * not backed by a HDC this will get the HDC for the screen device context diff --git a/storage/src/StorageBaseStatementInternal.h b/storage/src/StorageBaseStatementInternal.h index 77793c6d1a64..20b289fc1bf4 100644 --- a/storage/src/StorageBaseStatementInternal.h +++ b/storage/src/StorageBaseStatementInternal.h @@ -13,7 +13,6 @@ struct sqlite3; struct sqlite3_stmt; -class mozIStorageError; class mozIStorageBindingParamsArray; class mozIStorageBindingParams; class mozIStorageStatementCallback; diff --git a/storage/src/mozStorageAsyncStatement.h b/storage/src/mozStorageAsyncStatement.h index 72534d077047..565d6127030b 100644 --- a/storage/src/mozStorageAsyncStatement.h +++ b/storage/src/mozStorageAsyncStatement.h @@ -19,7 +19,6 @@ #include "mozilla/Attributes.h" class nsIXPConnectJSObjectHolder; -struct sqlite3_stmt; namespace mozilla { namespace storage { diff --git a/storage/src/mozStorageAsyncStatementParams.h b/storage/src/mozStorageAsyncStatementParams.h index 71f53dab65ba..f753c6399f58 100644 --- a/storage/src/mozStorageAsyncStatementParams.h +++ b/storage/src/mozStorageAsyncStatementParams.h @@ -11,8 +11,6 @@ #include "nsIXPCScriptable.h" #include "mozilla/Attributes.h" -class mozIStorageAsyncStatement; - namespace mozilla { namespace storage { diff --git a/storage/src/mozStorageConnection.h b/storage/src/mozStorageConnection.h index 647541679fc3..ae1611aef74e 100644 --- a/storage/src/mozStorageConnection.h +++ b/storage/src/mozStorageConnection.h @@ -27,7 +27,6 @@ #include "sqlite3.h" -struct PRLock; class nsIFile; class nsIFileURL; class nsIEventTarget; diff --git a/storage/src/mozStoragePrivateHelpers.h b/storage/src/mozStoragePrivateHelpers.h index 92bd2c6c1b56..718ad402c1bb 100644 --- a/storage/src/mozStoragePrivateHelpers.h +++ b/storage/src/mozStoragePrivateHelpers.h @@ -19,8 +19,6 @@ #include "Variant.h" class mozIStorageCompletionCallback; -class mozIStorageBaseStatement; -class mozIStorageBindingParams; class nsIRunnable; namespace mozilla { diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 602f7224c11f..0a052982afaf 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -24,8 +24,6 @@ #include "mozilla/Attributes.h" #include "mozilla/EventForwards.h" -class gfxASurface; - namespace mozilla { namespace dom { diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h index 8e1aaf625d4b..2ab5c1e89a5f 100644 --- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -36,8 +36,6 @@ // #define DEBUG_ANDROID_EVENTS // #define DEBUG_ANDROID_WIDGET -class nsWindow; -class nsIDOMMozSmsMessage; class nsIObserver; class Task; @@ -62,10 +60,6 @@ struct SmsFilterData; } // namespace mobilemessage } // namespace dom -namespace layers { -class CompositorParent; -} // namespace layers - // The order and number of the members in this structure must correspond // to the attrsAppearance array in GeckoAppShell.getSystemColors() typedef struct AndroidSystemColors { diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index 9f71e217a58a..5868bb7b0e41 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -27,7 +27,6 @@ //#define FORCE_ALOG 1 class nsIAndroidDisplayport; -class nsIAndroidViewport; class nsIWidget; namespace mozilla { diff --git a/widget/android/GfxInfo.h b/widget/android/GfxInfo.h index b451cca40cf5..d9e92e4509b1 100644 --- a/widget/android/GfxInfo.h +++ b/widget/android/GfxInfo.h @@ -16,10 +16,6 @@ namespace mozilla { -namespace gl { -class GLContext; -} - namespace widget { class GfxInfo : public GfxInfoBase diff --git a/widget/cocoa/nsAppShell.h b/widget/cocoa/nsAppShell.h index ca0f90945f70..bf5b06a49437 100644 --- a/widget/cocoa/nsAppShell.h +++ b/widget/cocoa/nsAppShell.h @@ -11,8 +11,6 @@ #ifndef nsAppShell_h_ #define nsAppShell_h_ -class nsCocoaWindow; - #include "nsBaseAppShell.h" #include "nsTArray.h" diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index 4b8ea6ab2577..c1f8c470983a 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -33,7 +33,6 @@ #import #import -class gfxASurface; class nsChildView; class nsCocoaWindow; diff --git a/widget/cocoa/nsMenuBarX.h b/widget/cocoa/nsMenuBarX.h index a27d373b9600..e0594bc18127 100644 --- a/widget/cocoa/nsMenuBarX.h +++ b/widget/cocoa/nsMenuBarX.h @@ -17,7 +17,6 @@ class nsMenuX; class nsMenuBarX; -class nsMenuItemX; class nsIWidget; class nsIContent; diff --git a/widget/cocoa/nsMenuGroupOwnerX.h b/widget/cocoa/nsMenuGroupOwnerX.h index caed9a50cc44..5972fa9ddc08 100644 --- a/widget/cocoa/nsMenuGroupOwnerX.h +++ b/widget/cocoa/nsMenuGroupOwnerX.h @@ -16,12 +16,10 @@ #include "nsString.h" -class nsMenuX; class nsMenuItemX; class nsChangeObserver; class nsIWidget; class nsIContent; -class nsIDocument; class nsMenuGroupOwnerX : public nsMenuObjectX, public nsIMutationObserver { diff --git a/widget/gonk/HwcComposer2D.h b/widget/gonk/HwcComposer2D.h index 0de54caf2cde..bb68ff6cf8b4 100644 --- a/widget/gonk/HwcComposer2D.h +++ b/widget/gonk/HwcComposer2D.h @@ -38,7 +38,6 @@ namespace gl { namespace layers { class CompositorParent; -class ContainerLayer; class Layer; } diff --git a/widget/gonk/libdisplay/FramebufferSurface.h b/widget/gonk/libdisplay/FramebufferSurface.h index 0e4c2aa40236..f90dcd8dacf6 100644 --- a/widget/gonk/libdisplay/FramebufferSurface.h +++ b/widget/gonk/libdisplay/FramebufferSurface.h @@ -28,7 +28,6 @@ namespace android { class Rect; class String8; -class HWComposer; #if ANDROID_VERSION >= 21 typedef IGraphicBufferConsumer StreamConsumer; diff --git a/widget/gonk/libdisplay/GonkDisplay.h b/widget/gonk/libdisplay/GonkDisplay.h index d90a0f96837c..c5b33c650b99 100644 --- a/widget/gonk/libdisplay/GonkDisplay.h +++ b/widget/gonk/libdisplay/GonkDisplay.h @@ -21,10 +21,6 @@ namespace mozilla { -namespace layers { -class Layer; -} - typedef void * EGLDisplay; typedef void * EGLSurface; diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h index 17f94c201c88..a1a22416addb 100644 --- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h +++ b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h @@ -23,8 +23,6 @@ namespace android { -class GonkBufferSlot; - class GonkBufferQueueProducer : public BnGraphicBufferProducer, private IBinder::DeathRecipient { public: diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index 934d470187a4..1c3991a66ca3 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -23,22 +23,8 @@ #include "Units.h" extern nsIntRect gScreenBounds; - -namespace mozilla { -namespace gl { -class GLContext; -} -namespace layers { -class LayersManager; -} -} - class ANativeWindowBuffer; -namespace android { -class FramebufferNativeWindow; -} - namespace widget { struct InputContext; struct InputContextAction; diff --git a/widget/gtk/nsPSPrinters.h b/widget/gtk/nsPSPrinters.h index e47b31eef57d..b584ef715a27 100644 --- a/widget/gtk/nsPSPrinters.h +++ b/widget/gtk/nsPSPrinters.h @@ -10,8 +10,6 @@ #include "nsString.h" #include "nsTArray.h" -class nsCUPSShim; - class nsPSPrinterList { public: nsPSPrinterList(); diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 355aadc8e69a..cc2a0efcada3 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -61,7 +61,6 @@ extern PRLogModuleInfo *gWidgetDrawLog; class gfxASurface; class gfxPattern; -class nsDragService; class nsPluginNativeWindowGtk; #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) # define MOZ_HAVE_SHMIMAGE diff --git a/widget/nsBaseClipboard.h b/widget/nsBaseClipboard.h index 8ceafdb1301f..538389ce96e1 100644 --- a/widget/nsBaseClipboard.h +++ b/widget/nsBaseClipboard.h @@ -10,7 +10,6 @@ #include "nsITransferable.h" class nsITransferable; -class nsDataObj; class nsIClipboardOwner; class nsIWidget; diff --git a/widget/nsBaseDragService.h b/widget/nsBaseDragService.h index a86ff3c02d7a..60713916da8a 100644 --- a/widget/nsBaseDragService.h +++ b/widget/nsBaseDragService.h @@ -24,10 +24,8 @@ class nsIContent; class nsIDOMNode; -class nsIFrame; class nsPresContext; class nsIImageLoadingContent; -class nsICanvasElementExternal; namespace mozilla { namespace gfx { diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 5b9e5772b67f..74e752541f47 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -28,9 +28,6 @@ #include "Units.h" // forward declarations -class nsFontMetrics; -class nsDeviceContext; -struct nsFont; class nsIRollupListener; class imgIContainer; class nsIContent; diff --git a/widget/nsPrintOptionsImpl.h b/widget/nsPrintOptionsImpl.h index 262518b5ecf4..8b2616907bc1 100644 --- a/widget/nsPrintOptionsImpl.h +++ b/widget/nsPrintOptionsImpl.h @@ -15,7 +15,6 @@ #include "nsFont.h" class nsIPrintSettings; -class nsIWebBrowserPrint; /** * Class nsPrintOptions diff --git a/widget/nsTransferable.h b/widget/nsTransferable.h index da94ed27f66b..135f0411d3e0 100644 --- a/widget/nsTransferable.h +++ b/widget/nsTransferable.h @@ -14,7 +14,6 @@ #include "nsWeakPtr.h" class nsString; -class nsDataObj; // // DataStruct diff --git a/widget/qt/nsWindow.h b/widget/qt/nsWindow.h index f8d054bba2af..2675939eeb18 100644 --- a/widget/qt/nsWindow.h +++ b/widget/qt/nsWindow.h @@ -59,7 +59,6 @@ extern PRLogModuleInfo *gWidgetDrawLog; #endif /* MOZ_LOGGING */ -class nsIdleService; class QCloseEvent; class QFocusEvent; class QHideEvent; diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h index 79979044c6e6..4d57e3786a1d 100644 --- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -37,7 +37,6 @@ #define VK_OEM_CLEAR 0xFE class nsIIdleServiceInternal; -struct nsModifierKeyState; namespace mozilla { namespace widget { diff --git a/widget/windows/nsClipboard.h b/widget/windows/nsClipboard.h index 8037d340da36..b1157eb510e6 100644 --- a/widget/windows/nsClipboard.h +++ b/widget/windows/nsClipboard.h @@ -12,7 +12,6 @@ #include class nsITransferable; -class nsIClipboardOwner; class nsIWidget; class nsIFile; struct IDataObject; diff --git a/widget/windows/nsDataObjCollection.h b/widget/windows/nsDataObjCollection.h index 5a1cd3315bd1..35f1429dbfad 100644 --- a/widget/windows/nsDataObjCollection.h +++ b/widget/windows/nsDataObjCollection.h @@ -14,8 +14,6 @@ #include "nsDataObj.h" #include "mozilla/Attributes.h" -class CEnumFormatEtc; - #define MULTI_MIME "Mozilla/IDataObjectCollectionFormat" EXTERN_C const IID IID_IDataObjCollection; diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h index 236910adae6b..eb165da6e9d4 100644 --- a/widget/windows/nsDragService.h +++ b/widget/windows/nsDragService.h @@ -10,11 +10,8 @@ #include #include -struct IDropSource; struct IDataObject; -class nsNativeDragTarget; class nsDataObjCollection; -class nsString; /** * Native Win32 DragService wrapper diff --git a/widget/windows/nsNativeDragTarget.h b/widget/windows/nsNativeDragTarget.h index 102f7c5901e0..703fa96d8882 100644 --- a/widget/windows/nsNativeDragTarget.h +++ b/widget/windows/nsNativeDragTarget.h @@ -20,8 +20,6 @@ class nsIDragService; class nsIWidget; -struct IDataObject; - /* * nsNativeDragTarget implements the IDropTarget interface and gets most of its * behavior from the associated adapter (m_dragDrop). diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 88c1c67ef9c4..4f1412b1e040 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -38,10 +38,6 @@ struct ITfDocumentMgr; struct ITfDisplayAttributeMgr; struct ITfCategoryMgr; class nsWindow; -#ifdef MOZ_METRO -class MetroWidget; -#endif -class TSFStaticSink; namespace mozilla { namespace widget { diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 95d5f08d51e1..1bc14a8594b8 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -49,14 +49,12 @@ class nsNativeDragTarget; class nsIRollupListener; -class nsIFile; class nsIntRegion; class imgIContainer; namespace mozilla { namespace widget { class NativeKey; -class ModifierKeyState; struct MSGResult; } // namespace widget } // namespacw mozilla; diff --git a/xpcom/base/nsMemoryInfoDumper.h b/xpcom/base/nsMemoryInfoDumper.h index 39ed8f62ce70..6bba176f2deb 100644 --- a/xpcom/base/nsMemoryInfoDumper.h +++ b/xpcom/base/nsMemoryInfoDumper.h @@ -10,8 +10,6 @@ #include "nsIMemoryInfoDumper.h" #include -class nsACString; - /** * This class facilitates dumping information about our memory usage to disk. * diff --git a/xpcom/build/Omnijar.h b/xpcom/build/Omnijar.h index 7d2688a4a0b2..72277c85fef8 100644 --- a/xpcom/build/Omnijar.h +++ b/xpcom/build/Omnijar.h @@ -13,8 +13,6 @@ #include "nsIFile.h" #include "nsZipArchive.h" -class nsIURI; - namespace mozilla { class Omnijar diff --git a/xpcom/build/nsXPCOMPrivate.h b/xpcom/build/nsXPCOMPrivate.h index 613ef3f0d801..4898abae3dd9 100644 --- a/xpcom/build/nsXPCOMPrivate.h +++ b/xpcom/build/nsXPCOMPrivate.h @@ -14,7 +14,6 @@ class nsStringContainer; class nsCStringContainer; -class nsIComponentLoader; class nsPurpleBufferEntry; /** diff --git a/xpcom/components/ManifestParser.h b/xpcom/components/ManifestParser.h index 1f360930b94d..2f63a8c69a18 100644 --- a/xpcom/components/ManifestParser.h +++ b/xpcom/components/ManifestParser.h @@ -13,8 +13,6 @@ #endif // !defined(MOZILLA_XPCOMRT_API) #include "mozilla/FileLocation.h" -class nsIFile; - void ParseManifest(NSLocationType aType, mozilla::FileLocation& aFile, char* aBuf, bool aChromeOnly, bool aXPTOnly = false); diff --git a/xpcom/ds/nsObserverList.h b/xpcom/ds/nsObserverList.h index 4e8c3e08431c..c69025a9f9e2 100644 --- a/xpcom/ds/nsObserverList.h +++ b/xpcom/ds/nsObserverList.h @@ -17,10 +17,6 @@ #include "nsISimpleEnumerator.h" #include "mozilla/Attributes.h" -namespace mozilla { -class ObserverServiceReporter; -} // namespace mozilla - struct ObserverRef { ObserverRef(const ObserverRef& aO) : isWeakRef(aO.isWeakRef), ref(aO.ref) {} diff --git a/xpcom/glue/nsCOMPtr.h b/xpcom/glue/nsCOMPtr.h index 8b3fad79c20b..f3a5de4aca97 100644 --- a/xpcom/glue/nsCOMPtr.h +++ b/xpcom/glue/nsCOMPtr.h @@ -109,9 +109,6 @@ #endif namespace mozilla { - -struct unused_t; - namespace dom { template class OwningNonNull; } // namespace dom diff --git a/xpcom/reflect/xptinfo/ShimInterfaceInfo.h b/xpcom/reflect/xptinfo/ShimInterfaceInfo.h index ebc86f19c444..ecfa158605f3 100644 --- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.h +++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.h @@ -19,7 +19,6 @@ namespace mozilla { namespace dom { -struct ConstantSpec; struct NativePropertyHooks; } } diff --git a/xpcom/reflect/xptinfo/xptinfo.h b/xpcom/reflect/xptinfo/xptinfo.h index b107583352c6..5e1981607ec9 100644 --- a/xpcom/reflect/xptinfo/xptinfo.h +++ b/xpcom/reflect/xptinfo/xptinfo.h @@ -11,8 +11,6 @@ #include "nscore.h" #include "xpt_struct.h" -class nsIInterfaceInfoManager; - // Flyweight wrapper classes for xpt_struct.h structs. // Everything here is dependent upon - and sensitive to changes in - // xpcom/typelib/xpt/xpt_struct.h! From a4369a04c4826e8f14a3984df65c2a39b5411d41 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 08:29:26 +0200 Subject: [PATCH 087/241] Bug 1156632 - Remove unused forward class declarations - patch 7 - JS, r=sfink --- js/ipc/CPOWTimer.h | 2 -- js/ipc/JavaScriptShared.h | 5 ----- js/public/Class.h | 1 - js/public/ProfilingFrameIterator.h | 1 - js/src/asmjs/AsmJSFrameIterator.h | 1 - js/src/gc/Barrier.h | 1 - js/src/gc/GCRuntime.h | 3 --- js/src/gc/Heap.h | 2 -- js/src/gc/Memory.h | 2 -- js/src/gc/Nursery.h | 5 ----- js/src/gc/Statistics.h | 2 -- js/src/jit/Bailouts.h | 2 -- js/src/jit/BaselineIC.h | 3 --- js/src/jit/C1Spewer.h | 2 -- js/src/jit/CodeGenerator.h | 1 - js/src/jit/IonCaches.h | 3 --- js/src/jit/IonCode.h | 7 ------- js/src/jit/JSONSpewer.h | 2 -- js/src/jit/JitCompartment.h | 1 - js/src/jit/LIR.h | 2 -- js/src/jit/MIRGenerator.h | 2 -- js/src/jit/Safepoints.h | 1 - js/src/jit/ValueNumbering.h | 1 - js/src/jit/arm/MoveEmitter-arm.h | 2 -- js/src/jit/mips/Assembler-mips.h | 2 -- js/src/jit/mips/MoveEmitter-mips.h | 2 -- js/src/jit/none/MacroAssembler-none.h | 2 -- js/src/jit/shared/Lowering-shared.h | 2 -- js/src/jit/x86-shared/MoveEmitter-x86-shared.h | 2 -- js/src/jsapi.h | 1 - js/src/jscntxt.h | 3 --- js/src/jscompartment.h | 5 +---- js/src/jsgcinlines.h | 3 --- js/src/jsobj.h | 7 ------- js/src/jsscript.h | 2 +- js/src/jsstr.h | 3 --- js/src/jswrapper.h | 2 -- js/src/vm/ErrorObject.h | 2 -- js/src/vm/NativeObject.h | 2 -- js/src/vm/RegExpObject.h | 1 + js/src/vm/Runtime.h | 2 -- js/src/vm/Shape.h | 1 - js/src/vm/Stack.h | 1 - js/xpconnect/loader/mozJSLoaderUtils.h | 1 - js/xpconnect/public/nsAXPCNativeCallContext.h | 2 -- js/xpconnect/src/XPCWrapper.h | 2 -- 46 files changed, 3 insertions(+), 101 deletions(-) diff --git a/js/ipc/CPOWTimer.h b/js/ipc/CPOWTimer.h index 158ea9e98180..d1f0f5622ef9 100644 --- a/js/ipc/CPOWTimer.h +++ b/js/ipc/CPOWTimer.h @@ -10,8 +10,6 @@ #include "prinrval.h" -class JSObject; - /** * A stopwatch measuring the duration of a CPOW call. * diff --git a/js/ipc/JavaScriptShared.h b/js/ipc/JavaScriptShared.h index 1693797fa476..8b87400366c6 100644 --- a/js/ipc/JavaScriptShared.h +++ b/js/ipc/JavaScriptShared.h @@ -14,11 +14,6 @@ #include "nsJSUtils.h" namespace mozilla { - -namespace dom { -class CPOWManagerGetter; -} - namespace jsipc { class ObjectId { diff --git a/js/public/Class.h b/js/public/Class.h index b5a316f9781b..cdcc760b6be5 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -31,7 +31,6 @@ namespace js { struct Class; class FreeOp; -class PropertyName; class Shape; // This is equal to JSFunction::class_. Use it in places where you don't want diff --git a/js/public/ProfilingFrameIterator.h b/js/public/ProfilingFrameIterator.h index b184209e6a7d..93dbd885fbe7 100644 --- a/js/public/ProfilingFrameIterator.h +++ b/js/public/ProfilingFrameIterator.h @@ -14,7 +14,6 @@ #include "js/Utility.h" -class JSAtom; struct JSRuntime; namespace js { diff --git a/js/src/asmjs/AsmJSFrameIterator.h b/js/src/asmjs/AsmJSFrameIterator.h index 3c493d2311e4..84ddfea8761f 100644 --- a/js/src/asmjs/AsmJSFrameIterator.h +++ b/js/src/asmjs/AsmJSFrameIterator.h @@ -24,7 +24,6 @@ #include "js/ProfilingFrameIterator.h" class JSAtom; -struct JSContext; namespace js { diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 06e928847b64..c30fe5b9e89f 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -173,7 +173,6 @@ class GlobalObject; class LazyScript; class NativeObject; class NestedScopeObject; -class Nursery; class PlainObject; class PropertyName; class SavedFrame; diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 0484948ec2c3..4940ffb77041 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -30,11 +30,8 @@ namespace gc { typedef Vector ZoneVector; -struct FinalizePhase; class MarkingValidator; -struct AutoPrepareForTracing; class AutoTraceSession; -struct ArenasToUpdate; struct MovingTracer; class ChunkPool diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index c1f5e5b53809..8c58c869a78a 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -27,8 +27,6 @@ #include "js/HeapAPI.h" #include "js/TracingAPI.h" -struct JSCompartment; - struct JSRuntime; namespace JS { diff --git a/js/src/gc/Memory.h b/js/src/gc/Memory.h index 2739544a3c35..4902cfc4ea48 100644 --- a/js/src/gc/Memory.h +++ b/js/src/gc/Memory.h @@ -9,8 +9,6 @@ #include -struct JSRuntime; - namespace js { namespace gc { diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h index 60c8f5c047ae..66ba3990cbb4 100644 --- a/js/src/gc/Nursery.h +++ b/js/src/gc/Nursery.h @@ -27,7 +27,6 @@ struct Zone; namespace js { -class TypedArrayObject; class ObjectElements; class NativeObject; class HeapSlot; @@ -37,15 +36,11 @@ void SetGCZeal(JSRuntime*, uint8_t, uint32_t); namespace gc { struct Cell; -class Collector; class MinorCollectionTracer; } /* namespace gc */ namespace jit { -class CodeGenerator; class MacroAssembler; -class ICStubCompiler; -class BaselineCompiler; } class Nursery diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index 6fde2d3d0f05..22ab0dbc1ae3 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -18,8 +18,6 @@ #include "js/GCAPI.h" #include "js/Vector.h" -struct JSCompartment; - namespace js { class GCParallelTask; diff --git a/js/src/jit/Bailouts.h b/js/src/jit/Bailouts.h index dc10d1aa5553..624c9cfa8d78 100644 --- a/js/src/jit/Bailouts.h +++ b/js/src/jit/Bailouts.h @@ -104,8 +104,6 @@ static const uint32_t BAILOUT_RETURN_OVERRECURSED = 2; // are making an attempt to mark the stack during a bailout. static uint8_t * const FAKE_JIT_TOP_FOR_BAILOUT = reinterpret_cast(0xba1); -class JitCompartment; - // BailoutStack is an architecture specific pointer to the stack, given by the // bailout handler. class BailoutStack; diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 29235a416d38..b0949ba825e1 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -22,9 +22,6 @@ #include "vm/UnboxedObject.h" namespace js { - -class TypedArrayLayout; - namespace jit { // diff --git a/js/src/jit/C1Spewer.h b/js/src/jit/C1Spewer.h index c5057bd19cef..9caa6f11b62a 100644 --- a/js/src/jit/C1Spewer.h +++ b/js/src/jit/C1Spewer.h @@ -17,8 +17,6 @@ namespace js { namespace jit { class BacktrackingAllocator; -class MDefinition; -class MInstruction; class MBasicBlock; class MIRGraph; class LNode; diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 423e520d42a6..8bf8f1afc8b5 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -37,7 +37,6 @@ class OutOfLineInterruptCheckImplicit; class OutOfLineUnboxFloatingPoint; class OutOfLineStoreElementHole; class OutOfLineTypeOfV; -class OutOfLineLoadTypedArray; class OutOfLineUpdateCache; class OutOfLineCallPostWriteBarrier; class OutOfLineIsCallable; diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index f4b49b4ea37e..5ccada748fc7 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -17,9 +17,6 @@ #include "vm/TypedArrayCommon.h" namespace js { - -class LockedJSContext; - namespace jit { class LInstruction; diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index 94a2d026013d..48cd78fa63d8 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -22,13 +22,9 @@ #include "vm/TypeInference.h" namespace js { - -class AsmJSModule; - namespace jit { class MacroAssembler; -class CodeOffsetLabel; class PatchableBackedge; class IonBuilder; @@ -728,9 +724,6 @@ struct IonScriptCounts struct VMFunction; -class JitCompartment; -class JitRuntime; - struct AutoFlushICache { private: diff --git a/js/src/jit/JSONSpewer.h b/js/src/jit/JSONSpewer.h index d77910efbbe2..db121a8dfab8 100644 --- a/js/src/jit/JSONSpewer.h +++ b/js/src/jit/JSONSpewer.h @@ -16,8 +16,6 @@ namespace jit { class BacktrackingAllocator; class MDefinition; -class MInstruction; -class MBasicBlock; class MIRGraph; class MResumePoint; class LNode; diff --git a/js/src/jit/JitCompartment.h b/js/src/jit/JitCompartment.h index 4d4beab5beac..f263e0516116 100644 --- a/js/src/jit/JitCompartment.h +++ b/js/src/jit/JitCompartment.h @@ -57,7 +57,6 @@ typedef void (*EnterJitCode)(void* code, unsigned argc, Value* argv, Interpreter CalleeToken calleeToken, JSObject* scopeChain, size_t numStackValues, Value* vp); -class IonBuilder; class JitcodeGlobalTable; // ICStubSpace is an abstraction for allocation policy and storage for stub data. diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index bbcea06186f2..085c2902ad41 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -32,9 +32,7 @@ class LStackSlot; class LArgument; class LConstantIndex; class MBasicBlock; -class MTableSwitch; class MIRGenerator; -class MSnapshot; static const uint32_t VREG_INCREMENT = 1; diff --git a/js/src/jit/MIRGenerator.h b/js/src/jit/MIRGenerator.h index 9d76f41d5691..69866ae5a740 100644 --- a/js/src/jit/MIRGenerator.h +++ b/js/src/jit/MIRGenerator.h @@ -29,9 +29,7 @@ namespace js { namespace jit { -class MBasicBlock; class MIRGraph; -class MStart; class OptimizationInfo; class MIRGenerator diff --git a/js/src/jit/Safepoints.h b/js/src/jit/Safepoints.h index 3081137cbbc6..783ad65e683c 100644 --- a/js/src/jit/Safepoints.h +++ b/js/src/jit/Safepoints.h @@ -15,7 +15,6 @@ namespace js { namespace jit { struct SafepointSlotEntry; -struct SafepointNunboxEntry; class LAllocation; class LSafepoint; diff --git a/js/src/jit/ValueNumbering.h b/js/src/jit/ValueNumbering.h index 4134316b3565..9539de643deb 100644 --- a/js/src/jit/ValueNumbering.h +++ b/js/src/jit/ValueNumbering.h @@ -17,7 +17,6 @@ class MDefinition; class MBasicBlock; class MIRGraph; class MPhi; -class MInstruction; class MIRGenerator; class MResumePoint; diff --git a/js/src/jit/arm/MoveEmitter-arm.h b/js/src/jit/arm/MoveEmitter-arm.h index 24bc2f201f96..fb7e6460f1de 100644 --- a/js/src/jit/arm/MoveEmitter-arm.h +++ b/js/src/jit/arm/MoveEmitter-arm.h @@ -13,8 +13,6 @@ namespace js { namespace jit { -class CodeGenerator; - class MoveEmitterARM { uint32_t inCycle_; diff --git a/js/src/jit/mips/Assembler-mips.h b/js/src/jit/mips/Assembler-mips.h index b273fc6ac6d1..320df5633d82 100644 --- a/js/src/jit/mips/Assembler-mips.h +++ b/js/src/jit/mips/Assembler-mips.h @@ -256,7 +256,6 @@ class Instruction; class InstReg; class InstImm; class InstJump; -class BranchInstBlock; uint32_t RS(Register r); uint32_t RT(Register r); @@ -445,7 +444,6 @@ enum FunctionField { ff_null = 0 }; -class MacroAssemblerMIPS; class Operand; // A BOffImm16 is a 16 bit immediate that is used for branches. diff --git a/js/src/jit/mips/MoveEmitter-mips.h b/js/src/jit/mips/MoveEmitter-mips.h index 643eb4d48364..de0f7118b63f 100644 --- a/js/src/jit/mips/MoveEmitter-mips.h +++ b/js/src/jit/mips/MoveEmitter-mips.h @@ -13,8 +13,6 @@ namespace js { namespace jit { -class CodeGenerator; - class MoveEmitterMIPS { uint32_t inCycle_; diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 888c7cb608b2..99973dbe5915 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -15,8 +15,6 @@ namespace js { namespace jit { -class MDefinition; - static MOZ_CONSTEXPR_VAR Register StackPointer = { Registers::invalid_reg }; static MOZ_CONSTEXPR_VAR Register FramePointer = { Registers::invalid_reg }; static MOZ_CONSTEXPR_VAR Register ReturnReg = { Registers::invalid_reg }; diff --git a/js/src/jit/shared/Lowering-shared.h b/js/src/jit/shared/Lowering-shared.h index c6b960f3540a..a0b199084a98 100644 --- a/js/src/jit/shared/Lowering-shared.h +++ b/js/src/jit/shared/Lowering-shared.h @@ -16,8 +16,6 @@ namespace js { namespace jit { -class MBasicBlock; -class MTableSwitch; class MIRGenerator; class MIRGraph; class MDefinition; diff --git a/js/src/jit/x86-shared/MoveEmitter-x86-shared.h b/js/src/jit/x86-shared/MoveEmitter-x86-shared.h index 238e82aa66fa..b7397e98ccaf 100644 --- a/js/src/jit/x86-shared/MoveEmitter-x86-shared.h +++ b/js/src/jit/x86-shared/MoveEmitter-x86-shared.h @@ -13,8 +13,6 @@ namespace js { namespace jit { -class CodeGenerator; - class MoveEmitterX86 { bool inCycle_; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 806cce2c1599..d651c5266dda 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -37,7 +37,6 @@ namespace JS { -class Latin1CharsZ; class TwoByteChars; #ifdef JS_DEBUG diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index bcf115c3849c..341bce8388a2 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -25,7 +25,6 @@ namespace js { namespace jit { class JitContext; -class CompileCompartment; class DebugModeOSRVolatileJitFrameIterator; } @@ -62,8 +61,6 @@ extern void TraceCycleDetectionSet(JSTracer* trc, ObjectSet& set); struct AutoResolving; -class DtoaCache; -class RegExpStatics; namespace frontend { struct CompileError; } diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 4883c071b518..b9c3c94e2643 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -125,13 +125,10 @@ typedef HashMap extern JSString* ConcatStrings(ExclusiveContext* cx, diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h index 6ea102fe8068..f43ceb313b84 100644 --- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -13,8 +13,6 @@ namespace js { -class DummyFrameGuard; - /* * Helper for Wrapper::New default options. * diff --git a/js/src/vm/ErrorObject.h b/js/src/vm/ErrorObject.h index 858d347faa8e..40f87e1234b3 100644 --- a/js/src/vm/ErrorObject.h +++ b/js/src/vm/ErrorObject.h @@ -13,8 +13,6 @@ #include "vm/SavedStacks.h" #include "vm/Shape.h" -struct JSExnPrivate; - namespace js { /* diff --git a/js/src/vm/NativeObject.h b/js/src/vm/NativeObject.h index fd3a4bdc548c..7c4376538ce3 100644 --- a/js/src/vm/NativeObject.h +++ b/js/src/vm/NativeObject.h @@ -282,11 +282,9 @@ extern HeapSlot* const emptyObjectElements; struct Class; class GCMarker; -struct ObjectOps; class Shape; class NewObjectCache; -class TaggedProto; #ifdef DEBUG static inline bool diff --git a/js/src/vm/RegExpObject.h b/js/src/vm/RegExpObject.h index ec7a1222baa2..3c8ce26ce5cc 100644 --- a/js/src/vm/RegExpObject.h +++ b/js/src/vm/RegExpObject.h @@ -41,6 +41,7 @@ namespace js { struct MatchPair; class MatchPairs; class RegExpShared; +class RegExpStatics; namespace frontend { class TokenStream; } diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 8e6d1cc11193..1edbf8ccc89d 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -569,8 +569,6 @@ class PerThreadData : public PerThreadDataFriendFields }; class AutoLockForExclusiveAccess; - -struct AutoStopwatch; } // namespace js struct JSRuntime : public JS::shadow::Runtime, diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index 705fe260408f..22489dbd949f 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -110,7 +110,6 @@ namespace js { class Bindings; -class Debugger; class Nursery; class StaticBlockObject; diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 56b73ff35a88..19f96ac697ee 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -28,7 +28,6 @@ class AsmJSModule; class InterpreterRegs; class CallObject; class ScopeObject; -class ClonedBlockObject; class ScriptFrameIter; class SPSProfiler; class InterpreterFrame; diff --git a/js/xpconnect/loader/mozJSLoaderUtils.h b/js/xpconnect/loader/mozJSLoaderUtils.h index f2840288e546..b3a3b6fec1b4 100644 --- a/js/xpconnect/loader/mozJSLoaderUtils.h +++ b/js/xpconnect/loader/mozJSLoaderUtils.h @@ -9,7 +9,6 @@ #include "nsString.h" -class nsIURI; namespace mozilla { namespace scache { class StartupCache; diff --git a/js/xpconnect/public/nsAXPCNativeCallContext.h b/js/xpconnect/public/nsAXPCNativeCallContext.h index 73b2adb65e58..e37da20e8c83 100644 --- a/js/xpconnect/public/nsAXPCNativeCallContext.h +++ b/js/xpconnect/public/nsAXPCNativeCallContext.h @@ -7,8 +7,6 @@ #ifndef nsAXPCNativeCallContext_h__ #define nsAXPCNativeCallContext_h__ -class nsIXPConnectWrappedNative; - /** * A native call context is allocated on the stack when XPConnect calls a * native method. Holding a pointer to this object beyond the currently diff --git a/js/xpconnect/src/XPCWrapper.h b/js/xpconnect/src/XPCWrapper.h index 920185f3298e..0bdc483d44b0 100644 --- a/js/xpconnect/src/XPCWrapper.h +++ b/js/xpconnect/src/XPCWrapper.h @@ -10,8 +10,6 @@ #include "xpcprivate.h" #include "jswrapper.h" -class nsIScriptSecurityManager; - namespace XPCNativeWrapper { // Given an XPCWrappedNative pointer and the name of the function on From 22bdb1930e3431c388aeb3c745faa2501af688aa Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Tue, 21 Apr 2015 23:34:05 -0700 Subject: [PATCH 088/241] (no bug) Fix typo in nsStyleContext.h (s/currenlty/currently/). Comment-only, DONTBUILD --- layout/style/nsStyleContext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 9dd9bfb0ff6f..f0cf8e418598 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -161,7 +161,7 @@ public: // true, the line should not be broken inside, which means inlines act // as if nowrap is set,
is suppressed, and blocks are inlinized. // This bit is propogated to all children of line partitipants. It is - // currenlty used by ruby to make its content frames unbreakable. + // currently used by ruby to make its content frames unbreakable. bool ShouldSuppressLineBreak() const { return !!(mBits & NS_STYLE_SUPPRESS_LINEBREAK); } From ccaa0be578fced5d3c16dd2ab1ed63f02cd5d912 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 08:53:33 +0200 Subject: [PATCH 089/241] Bug 1140448 - Improving the performances of how AudioEventTimeline calculates values, r=padenot --- dom/media/webaudio/AudioEventTimeline.h | 282 ++++++++++++++---------- dom/media/webaudio/AudioParamTimeline.h | 46 +++- dom/media/webaudio/DelayNode.cpp | 5 +- dom/media/webaudio/GainNode.cpp | 7 +- dom/media/webaudio/StereoPannerNode.cpp | 10 +- 5 files changed, 219 insertions(+), 131 deletions(-) diff --git a/dom/media/webaudio/AudioEventTimeline.h b/dom/media/webaudio/AudioEventTimeline.h index 2a8903c79089..06ff9b51959b 100644 --- a/dom/media/webaudio/AudioEventTimeline.h +++ b/dom/media/webaudio/AudioEventTimeline.h @@ -261,143 +261,100 @@ public: template float GetValueAtTime(TimeType aTime) { - mComputedValue = GetValueAtTimeHelper(aTime); + GetValuesAtTimeHelper(aTime, &mComputedValue, 1); return mComputedValue; } + template + void GetValuesAtTime(TimeType aTime, float* aBuffer, const size_t aSize) + { + MOZ_ASSERT(aBuffer); + GetValuesAtTimeHelper(aTime, aBuffer, aSize); + mComputedValue = aBuffer[aSize - 1]; + } + // This method computes the AudioParam value at a given time based on the event timeline template - float GetValueAtTimeHelper(TimeType aTime) + void GetValuesAtTimeHelper(TimeType aTime, float* aBuffer, const size_t aSize) { + MOZ_ASSERT(aBuffer); + MOZ_ASSERT(aSize); + + size_t lastEventId = 0; const AudioTimelineEvent* previous = nullptr; const AudioTimelineEvent* next = nullptr; - bool bailOut = false; - for (unsigned i = 0; !bailOut && i < mEvents.Length(); ++i) { - switch (mEvents[i].mType) { - case AudioTimelineEvent::SetValue: - case AudioTimelineEvent::SetTarget: - case AudioTimelineEvent::LinearRamp: - case AudioTimelineEvent::ExponentialRamp: - case AudioTimelineEvent::SetValueCurve: - if (TimesEqual(aTime, mEvents[i].template Time())) { + + // Let's remove old events except the last one: we need it to calculate some curves. + while (mEvents.Length() > 1 && + aTime > mEvents[1].template Time()) { + mEvents.RemoveElementAt(0); + } + + for (size_t bufferIndex = 0; bufferIndex < aSize; ++bufferIndex, ++aTime) { + for (; !bailOut && lastEventId < mEvents.Length(); ++lastEventId) { + +#ifdef DEBUG + const AudioTimelineEvent* current = &mEvents[lastEventId]; + MOZ_ASSERT(current->mType == AudioTimelineEvent::SetValue || + current->mType == AudioTimelineEvent::SetTarget || + current->mType == AudioTimelineEvent::LinearRamp || + current->mType == AudioTimelineEvent::ExponentialRamp || + current->mType == AudioTimelineEvent::SetValueCurve); +#endif + + if (TimesEqual(aTime, mEvents[lastEventId].template Time())) { mLastComputedValue = mComputedValue; // Find the last event with the same time - do { - ++i; - } while (i < mEvents.Length() && - aTime == mEvents[i].template Time()); - - // SetTarget nodes can be handled no matter what their next node is (if they have one) - if (mEvents[i - 1].mType == AudioTimelineEvent::SetTarget) { - // Follow the curve, without regard to the next event, starting at - // the last value of the last event. - return ExponentialApproach(mEvents[i - 1].template Time(), - mLastComputedValue, mEvents[i - 1].mValue, - mEvents[i - 1].mTimeConstant, aTime); + while (lastEventId < mEvents.Length() - 1 && + TimesEqual(aTime, mEvents[lastEventId + 1].template Time())) { + ++lastEventId; } - - // SetValueCurve events can be handled no matter what their event node is (if they have one) - if (mEvents[i - 1].mType == AudioTimelineEvent::SetValueCurve) { - return ExtractValueFromCurve(mEvents[i - 1].template Time(), - mEvents[i - 1].mCurve, - mEvents[i - 1].mCurveLength, - mEvents[i - 1].mDuration, aTime); - } - - // For other event types - return mEvents[i - 1].mValue; + break; } + previous = next; - next = &mEvents[i]; - if (aTime < mEvents[i].template Time()) { + next = &mEvents[lastEventId]; + if (aTime < mEvents[lastEventId].template Time()) { bailOut = true; } - break; - default: - MOZ_ASSERT(false, "unreached"); + } + + // The time was found in the list of events. + if (!bailOut && lastEventId < mEvents.Length()) { + MOZ_ASSERT(TimesEqual(aTime, mEvents[lastEventId].template Time())); + + // SetTarget nodes can be handled no matter what their next node is (if they have one) + if (mEvents[lastEventId].mType == AudioTimelineEvent::SetTarget) { + // Follow the curve, without regard to the next event, starting at + // the last value of the last event. + aBuffer[bufferIndex] = ExponentialApproach(mEvents[lastEventId].template Time(), + mLastComputedValue, mEvents[lastEventId].mValue, + mEvents[lastEventId].mTimeConstant, aTime); + continue; + } + + // SetValueCurve events can be handled no matter what their event node is (if they have one) + if (mEvents[lastEventId].mType == AudioTimelineEvent::SetValueCurve) { + aBuffer[bufferIndex] = ExtractValueFromCurve(mEvents[lastEventId].template Time(), + mEvents[lastEventId].mCurve, + mEvents[lastEventId].mCurveLength, + mEvents[lastEventId].mDuration, aTime); + continue; + } + + // For other event types + aBuffer[bufferIndex] = mEvents[lastEventId].mValue; + continue; + } + + // Handle the case where the time is past all of the events + if (!bailOut) { + aBuffer[bufferIndex] = GetValuesAtTimeHelperInternal(aTime, next, nullptr); + } else { + aBuffer[bufferIndex] = GetValuesAtTimeHelperInternal(aTime, previous, next); } } - // Handle the case where the time is past all of the events - if (!bailOut) { - previous = next; - next = nullptr; - } - - // Just return the default value if we did not find anything - if (!previous && !next) { - return mValue; - } - - // If the requested time is before all of the existing events - if (!previous) { - return mValue; - } - - // SetTarget nodes can be handled no matter what their next node is (if they have one) - if (previous->mType == AudioTimelineEvent::SetTarget) { - return ExponentialApproach(previous->template Time(), - mLastComputedValue, previous->mValue, - previous->mTimeConstant, aTime); - } - - // SetValueCurve events can be handled no mattar what their next node is (if they have one) - if (previous->mType == AudioTimelineEvent::SetValueCurve) { - return ExtractValueFromCurve(previous->template Time(), - previous->mCurve, previous->mCurveLength, - previous->mDuration, aTime); - } - - // If the requested time is after all of the existing events - if (!next) { - switch (previous->mType) { - case AudioTimelineEvent::SetValue: - case AudioTimelineEvent::LinearRamp: - case AudioTimelineEvent::ExponentialRamp: - // The value will be constant after the last event - return previous->mValue; - case AudioTimelineEvent::SetValueCurve: - return ExtractValueFromCurve(previous->template Time(), - previous->mCurve, previous->mCurveLength, - previous->mDuration, aTime); - case AudioTimelineEvent::SetTarget: - MOZ_ASSERT(false, "unreached"); - } - MOZ_ASSERT(false, "unreached"); - } - - // Finally, handle the case where we have both a previous and a next event - - // First, handle the case where our range ends up in a ramp event - switch (next->mType) { - case AudioTimelineEvent::LinearRamp: - return LinearInterpolate(previous->template Time(), previous->mValue, next->template Time(), next->mValue, aTime); - case AudioTimelineEvent::ExponentialRamp: - return ExponentialInterpolate(previous->template Time(), previous->mValue, next->template Time(), next->mValue, aTime); - case AudioTimelineEvent::SetValue: - case AudioTimelineEvent::SetTarget: - case AudioTimelineEvent::SetValueCurve: - break; - } - - // Now handle all other cases - switch (previous->mType) { - case AudioTimelineEvent::SetValue: - case AudioTimelineEvent::LinearRamp: - case AudioTimelineEvent::ExponentialRamp: - // If the next event type is neither linear or exponential ramp, the - // value is constant. - return previous->mValue; - case AudioTimelineEvent::SetValueCurve: - return ExtractValueFromCurve(previous->template Time(), - previous->mCurve, previous->mCurveLength, - previous->mDuration, aTime); - case AudioTimelineEvent::SetTarget: - MOZ_ASSERT(false, "unreached"); - } - - MOZ_ASSERT(false, "unreached"); - return 0.0f; } // Return the number of events scheduled @@ -445,6 +402,92 @@ public: } private: + template + float GetValuesAtTimeHelperInternal(TimeType aTime, + const AudioTimelineEvent* aPrevious, + const AudioTimelineEvent* aNext) + { + // If the requested time is before all of the existing events + if (!aPrevious) { + return mValue; + } + + // SetTarget nodes can be handled no matter what their next node is (if + // they have one) + if (aPrevious->mType == AudioTimelineEvent::SetTarget) { + return ExponentialApproach(aPrevious->template Time(), + mLastComputedValue, aPrevious->mValue, + aPrevious->mTimeConstant, aTime); + } + + // SetValueCurve events can be handled no mattar what their next node is + // (if they have one) + if (aPrevious->mType == AudioTimelineEvent::SetValueCurve) { + return ExtractValueFromCurve(aPrevious->template Time(), + aPrevious->mCurve, aPrevious->mCurveLength, + aPrevious->mDuration, aTime); + } + + // If the requested time is after all of the existing events + if (!aNext) { + switch (aPrevious->mType) { + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::LinearRamp: + case AudioTimelineEvent::ExponentialRamp: + // The value will be constant after the last event + return aPrevious->mValue; + case AudioTimelineEvent::SetValueCurve: + return ExtractValueFromCurve(aPrevious->template Time(), + aPrevious->mCurve, aPrevious->mCurveLength, + aPrevious->mDuration, aTime); + case AudioTimelineEvent::SetTarget: + MOZ_ASSERT(false, "unreached"); + } + MOZ_ASSERT(false, "unreached"); + } + + // Finally, handle the case where we have both a previous and a next event + + // First, handle the case where our range ends up in a ramp event + switch (aNext->mType) { + case AudioTimelineEvent::LinearRamp: + return LinearInterpolate(aPrevious->template Time(), + aPrevious->mValue, + aNext->template Time(), + aNext->mValue, aTime); + + case AudioTimelineEvent::ExponentialRamp: + return ExponentialInterpolate(aPrevious->template Time(), + aPrevious->mValue, + aNext->template Time(), + aNext->mValue, aTime); + + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::SetTarget: + case AudioTimelineEvent::SetValueCurve: + break; + } + + // Now handle all other cases + switch (aPrevious->mType) { + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::LinearRamp: + case AudioTimelineEvent::ExponentialRamp: + // If the next event type is neither linear or exponential ramp, the + // value is constant. + return aPrevious->mValue; + case AudioTimelineEvent::SetValueCurve: + return ExtractValueFromCurve(aPrevious->template Time(), + aPrevious->mCurve, aPrevious->mCurveLength, + aPrevious->mDuration, aTime); + case AudioTimelineEvent::SetTarget: + MOZ_ASSERT(false, "unreached"); + } + + MOZ_ASSERT(false, "unreached"); + return 0.0f; + } + const AudioTimelineEvent* GetPreviousEvent(double aTime) const { const AudioTimelineEvent* previous = nullptr; @@ -579,4 +622,3 @@ private: } #endif - diff --git a/dom/media/webaudio/AudioParamTimeline.h b/dom/media/webaudio/AudioParamTimeline.h index ec4bb40c5279..a99c7c0ac578 100644 --- a/dom/media/webaudio/AudioParamTimeline.h +++ b/dom/media/webaudio/AudioParamTimeline.h @@ -44,13 +44,26 @@ public: return BaseClass::HasSimpleValue() && !mStream; } + template + float GetValueAtTime(TimeType aTime) + { + return GetValueAtTime(aTime, 0); + } + // Get the value of the AudioParam at time aTime + aCounter. // aCounter here is an offset to aTime if we try to get the value in ticks, // otherwise it should always be zero. aCounter is meant to be used when + template + float GetValueAtTime(TimeType aTime, size_t aCounter); + + // Get the values of the AudioParam at time aTime + (0 to aSize). + // aBuffer must have the correct aSize. + // aSize here is an offset to aTime if we try to get the value in ticks, + // otherwise it should always be zero. aSize is meant to be used when // getting the value of an a-rate AudioParam for each tick inside an // AudioNodeEngine implementation. template - float GetValueAtTime(TimeType aTime, size_t aCounter = 0); + void GetValuesAtTime(TimeType aTime, float* aBuffer, const size_t aSize); virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { @@ -81,7 +94,6 @@ AudioParamTimeline::GetValueAtTime(double aTime, size_t aCounter) return BaseClass::GetValueAtTime(aTime); } - template<> inline float AudioParamTimeline::GetValueAtTime(int64_t aTime, size_t aCounter) { @@ -93,8 +105,36 @@ AudioParamTimeline::GetValueAtTime(int64_t aTime, size_t aCounter) (mStream ? AudioNodeInputValue(aCounter) : 0.0f); } +template<> inline void +AudioParamTimeline::GetValuesAtTime(double aTime, float* aBuffer, + const size_t aSize) +{ + MOZ_ASSERT(aBuffer); + MOZ_ASSERT(aSize == 1); + + // Getting an AudioParam value on an AudioNode does not consider input from + // other AudioNodes, which is managed only on the graph thread. + *aBuffer = BaseClass::GetValueAtTime(aTime); +} + +template<> inline void +AudioParamTimeline::GetValuesAtTime(int64_t aTime, float* aBuffer, + const size_t aSize) +{ + MOZ_ASSERT(aBuffer); + MOZ_ASSERT(aSize <= WEBAUDIO_BLOCK_SIZE); + MOZ_ASSERT(aSize == 1 || !HasSimpleValue()); + + // Mix the value of the AudioParam itself with that of the AudioNode inputs. + BaseClass::GetValuesAtTime(aTime, aBuffer, aSize); + if (mStream) { + for (size_t i = 0; i < aSize; ++i) { + aBuffer[i] += AudioNodeInputValue(i); + } + } +} + } } #endif - diff --git a/dom/media/webaudio/DelayNode.cpp b/dom/media/webaudio/DelayNode.cpp index b983a84c4819..dc03dd594a55 100644 --- a/dom/media/webaudio/DelayNode.cpp +++ b/dom/media/webaudio/DelayNode.cpp @@ -137,9 +137,12 @@ public: // If this DelayNode is in a cycle, make sure the delay value is at least // one block. StreamTime tick = mSource->GetCurrentPosition(); + float values[WEBAUDIO_BLOCK_SIZE]; + mDelay.GetValuesAtTime(tick, values,WEBAUDIO_BLOCK_SIZE); + double computedDelay[WEBAUDIO_BLOCK_SIZE]; for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) { - double delayAtTick = mDelay.GetValueAtTime(tick, counter) * sampleRate; + double delayAtTick = values[counter] * sampleRate; double delayAtTickClamped = std::max(minDelay, std::min(delayAtTick, maxDelay)); computedDelay[counter] = delayAtTickClamped; diff --git a/dom/media/webaudio/GainNode.cpp b/dom/media/webaudio/GainNode.cpp index bf685f1cfad8..9ce140208a23 100644 --- a/dom/media/webaudio/GainNode.cpp +++ b/dom/media/webaudio/GainNode.cpp @@ -84,11 +84,12 @@ public: AllocateAudioBlock(aInput.mChannelData.Length(), aOutput); // Compute the gain values for the duration of the input AudioChunk - // XXX we need to add a method to AudioEventTimeline to compute this buffer directly. + StreamTime tick = aStream->GetCurrentPosition(); float computedGain[WEBAUDIO_BLOCK_SIZE]; + mGain.GetValuesAtTime(tick, computedGain, WEBAUDIO_BLOCK_SIZE); + for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) { - StreamTime tick = aStream->GetCurrentPosition(); - computedGain[counter] = mGain.GetValueAtTime(tick, counter) * aInput.mVolume; + computedGain[counter] *= aInput.mVolume; } // Apply the gain to the output buffer diff --git a/dom/media/webaudio/StereoPannerNode.cpp b/dom/media/webaudio/StereoPannerNode.cpp index 417251607469..860911005a18 100644 --- a/dom/media/webaudio/StereoPannerNode.cpp +++ b/dom/media/webaudio/StereoPannerNode.cpp @@ -145,15 +145,17 @@ public: float computedGain[2][WEBAUDIO_BLOCK_SIZE]; bool onLeft[WEBAUDIO_BLOCK_SIZE]; + float values[WEBAUDIO_BLOCK_SIZE]; + StreamTime tick = aStream->GetCurrentPosition(); + mPan.GetValuesAtTime(tick, values, WEBAUDIO_BLOCK_SIZE); + for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) { - StreamTime tick = aStream->GetCurrentPosition(); float left, right; - float panning = mPan.GetValueAtTime(tick, counter); - GetGainValuesForPanning(panning, monoToStereo, left, right); + GetGainValuesForPanning(values[counter], monoToStereo, left, right); computedGain[0][counter] = left * aInput.mVolume; computedGain[1][counter] = right * aInput.mVolume; - onLeft[counter] = panning <= 0; + onLeft[counter] = values[counter] <= 0; } // Apply the gain to the output buffer From 8bef21375a72ea0b047e8adbf24a782f981b33ce Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 22 Apr 2015 09:03:52 +0200 Subject: [PATCH 090/241] Bug 1155546 - Implement WorkerControlRunnable::Cancel(), r=bent --- dom/workers/WorkerRunnable.cpp | 17 ++++++++++++++++- dom/workers/WorkerRunnable.h | 5 ++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp index fe1d193a739c..b07d62051ccb 100644 --- a/dom/workers/WorkerRunnable.cpp +++ b/dom/workers/WorkerRunnable.cpp @@ -305,7 +305,12 @@ WorkerRunnable::Run() MOZ_ASSERT(isMainThread == NS_IsMainThread()); nsRefPtr kungFuDeathGrip; if (targetIsWorkerThread) { - JSObject* global = JS::CurrentGlobalOrNull(GetCurrentThreadJSContext()); + JSContext* cx = GetCurrentThreadJSContext(); + if (NS_WARN_IF(!cx)) { + return NS_ERROR_FAILURE; + } + + JSObject* global = JS::CurrentGlobalOrNull(cx); if (global) { globalObject = GetGlobalObjectForGlobal(global); } else { @@ -499,6 +504,16 @@ WorkerControlRunnable::WorkerControlRunnable(WorkerPrivate* aWorkerPrivate, } #endif +NS_IMETHODIMP +WorkerControlRunnable::Cancel() +{ + if (NS_FAILED(Run())) { + NS_WARNING("WorkerControlRunnable::Run() failed."); + } + + return WorkerRunnable::Cancel(); +} + bool WorkerControlRunnable::DispatchInternal() { diff --git a/dom/workers/WorkerRunnable.h b/dom/workers/WorkerRunnable.h index 937348129b3e..d489e0648003 100644 --- a/dom/workers/WorkerRunnable.h +++ b/dom/workers/WorkerRunnable.h @@ -320,6 +320,9 @@ protected: virtual ~WorkerControlRunnable() { } + NS_IMETHOD + Cancel() override; + public: NS_DECL_ISUPPORTS_INHERITED @@ -402,7 +405,7 @@ public: bool Dispatch(JSContext* aCx); private: - NS_IMETHOD Run() override; + NS_IMETHOD Run() override; }; END_WORKERS_NAMESPACE From 71409e1dc38e6d6e5cf82c7cd7ce2d1e40e6be6c Mon Sep 17 00:00:00 2001 From: Maksim Lebedev Date: Wed, 22 Apr 2015 16:09:10 +0900 Subject: [PATCH 091/241] Bug 974305 - Add a test for WidgetPointerEvent::AssignPointerEventData(). r=smaug --- widget/tests/test_assign_event_data.html | 62 ++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/widget/tests/test_assign_event_data.html b/widget/tests/test_assign_event_data.html index fa8ce02a18a1..1f03fa397c24 100644 --- a/widget/tests/test_assign_event_data.html +++ b/widget/tests/test_assign_event_data.html @@ -29,6 +29,31 @@ margin-left: 0; } } + #pointer-target { + border: 1px dashed red; + background: yellow; + margin: 0px 10px; + padding: 0px 10px; + } + #scrollable-div { + background: green; + overflow: auto; + width: 30px; + height: 30px; + } + #scrolled-div { + background: magenta; + width: 10px; + height: 10px; + } + #form { + background: silver; + padding: 0px 10px; + } + #animated-div { + background: cyan; + padding: 0px 10px; + } @@ -36,9 +61,10 @@ hyper link -
-
-
+ span +
+
form
+
 
@@ -48,7 +74,7 @@ + + +
+ + diff --git a/dom/animation/test/mochitest.ini b/dom/animation/test/mochitest.ini index 7665362b5b94..ffcec00d1622 100644 --- a/dom/animation/test/mochitest.ini +++ b/dom/animation/test/mochitest.ini @@ -4,6 +4,7 @@ support-files = [css-animations/test_animations-dynamic-changes.html] [css-animations/test_animation-currenttime.html] +[css-animations/test_animation-finish.html] [css-animations/test_animation-finished.html] [css-animations/test_animation-pausing.html] [css-animations/test_animation-playstate.html] From 71628632b1eed466bb6617664a5a5a90b08f5816 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Fri, 17 Apr 2015 13:45:20 +0100 Subject: [PATCH 095/241] Bug 1157053 - Test restarting of finished transitions. r=birtles --- .../test_animation-finished.html | 61 +++++++++++++++++++ dom/animation/test/mochitest.ini | 1 + 2 files changed, 62 insertions(+) create mode 100644 dom/animation/test/css-transitions/test_animation-finished.html diff --git a/dom/animation/test/css-transitions/test_animation-finished.html b/dom/animation/test/css-transitions/test_animation-finished.html new file mode 100644 index 000000000000..198635d68f23 --- /dev/null +++ b/dom/animation/test/css-transitions/test_animation-finished.html @@ -0,0 +1,61 @@ + + + + + +
+ + diff --git a/dom/animation/test/mochitest.ini b/dom/animation/test/mochitest.ini index ffcec00d1622..06d3316ee868 100644 --- a/dom/animation/test/mochitest.ini +++ b/dom/animation/test/mochitest.ini @@ -15,6 +15,7 @@ support-files = [css-animations/test_element-get-animations.html] skip-if = buildapp == 'mulet' [css-transitions/test_animation-currenttime.html] +[css-transitions/test_animation-finished.html] [css-transitions/test_animation-pausing.html] [css-transitions/test_animation-ready.html] [css-transitions/test_animation-starttime.html] From 9b67d4237d6fb1220b5abfd2348d782ff5acf730 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Mon, 20 Apr 2015 14:22:29 +0100 Subject: [PATCH 096/241] Bug 1157074 - Fix Web Animations' Web Platform tests to make them use step_func when they should. r=birtles --- .../test/css-animations/test_animation-finished.html | 4 ++-- .../test/css-animations/test_animation-ready.html | 12 ++++++------ .../css-animations/test_animation-starttime.html | 4 ++-- .../css-transitions/test_animation-starttime.html | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dom/animation/test/css-animations/test_animation-finished.html b/dom/animation/test/css-animations/test_animation-finished.html index 95e5cea45053..0a5b834e7018 100644 --- a/dom/animation/test/css-animations/test_animation-finished.html +++ b/dom/animation/test/css-animations/test_animation-finished.html @@ -77,7 +77,7 @@ async_test(function(t) { animation.currentTime = ANIM_DURATION; - animation.finished.then(function() { + animation.finished.then(t.step_func(function() { previousFinishedPromise = animation.finished; animation.playbackRate = -1; assert_not_equals(animation.finished, previousFinishedPromise, @@ -85,7 +85,7 @@ async_test(function(t) { 'finished promise'); animation.currentTime = 0; return animation.finished; - }).then(t.step_func(function() { + })).then(t.step_func(function() { previousFinishedPromise = animation.finished; animation.play(); assert_not_equals(animation.finished, previousFinishedPromise, diff --git a/dom/animation/test/css-animations/test_animation-ready.html b/dom/animation/test/css-animations/test_animation-ready.html index 73264e6acff6..d7f421152201 100644 --- a/dom/animation/test/css-animations/test_animation-ready.html +++ b/dom/animation/test/css-animations/test_animation-ready.html @@ -44,13 +44,13 @@ async_test(function(t) { var animation = div.getAnimations()[0]; var originalReadyPromise = animation.ready; - animation.ready.then(function() { + animation.ready.then(t.step_func(function() { div.style.animationPlayState = 'running'; assert_not_equals(animation.ready, originalReadyPromise, 'After updating animation-play-state a new ready promise' + ' object is created'); t.done(); - }); + })); }, 'A new ready promise is created when setting animation-play-state: running'); async_test(function(t) { @@ -58,14 +58,14 @@ async_test(function(t) { div.style.animation = 'abc 100s'; var animation = div.getAnimations()[0]; - animation.ready.then(function() { + animation.ready.then(t.step_func(function() { var promiseBeforeCallingPlay = animation.ready; animation.play(); assert_equals(animation.ready, promiseBeforeCallingPlay, 'Ready promise has same object identity after redundant call' + ' to play()'); t.done(); - }); + })); }, 'Redundant calls to play() do not generate new ready promise objects'); async_test(function(t) { @@ -73,12 +73,12 @@ async_test(function(t) { div.style.animation = 'abc 100s'; var animation = div.getAnimations()[0]; - animation.ready.then(function(resolvedAnimation) { + animation.ready.then(t.step_func(function(resolvedAnimation) { assert_equals(resolvedAnimation, animation, 'Object identity of Animation passed to Promise callback' + ' matches the Animation object owning the Promise'); t.done(); - }); + })); }, 'The ready promise is fulfilled with its Animation'); async_test(function(t) { diff --git a/dom/animation/test/css-animations/test_animation-starttime.html b/dom/animation/test/css-animations/test_animation-starttime.html index 0dda2dc33721..f5ae80f6ceba 100644 --- a/dom/animation/test/css-animations/test_animation-starttime.html +++ b/dom/animation/test/css-animations/test_animation-starttime.html @@ -507,11 +507,11 @@ async_test(function(t) { return animation.ready; })).catch(t.step_func(function(reason) { assert_unreached(reason); - })).then(function() { + })).then(t.step_func(function() { assert_equals(animation.currentTime, storedCurrentTime, 'Test that hold time is correct'); t.done(); - }); + })); }, 'Setting startTime to null'); diff --git a/dom/animation/test/css-transitions/test_animation-starttime.html b/dom/animation/test/css-transitions/test_animation-starttime.html index db99d43b53df..1975d3542ad2 100644 --- a/dom/animation/test/css-transitions/test_animation-starttime.html +++ b/dom/animation/test/css-transitions/test_animation-starttime.html @@ -251,11 +251,11 @@ async_test(function(t) { return animation.ready; })).catch(t.step_func(function(reason) { assert_unreached(reason); - })).then(function() { + })).then(t.step_func(function() { assert_equals(animation.currentTime, storedCurrentTime, 'Test that hold time is correct'); t.done(); - }); + })); }, 'Setting startTime to null'); From be827bad4c5a3675dbd24db0c8d8b0e7727092f9 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 18:26:13 +0900 Subject: [PATCH 097/241] Bug 1155985 - Set FieldInto::mType just before storing to reserved slot. r=jonco, a=abillings --- js/src/ctypes/CTypes.cpp | 8 +++++++- js/src/jit-test/tests/ctypes/bug1155985.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 js/src/jit-test/tests/ctypes/bug1155985.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 640434db8d6a..2fe4187fbfb0 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -4963,7 +4963,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb // Add field name to the hash FieldInfo info; - info.mType = fieldType; + info.mType = nullptr; // Value of fields are not yet traceable here. info.mIndex = i; info.mOffset = fieldOffset; ASSERT_OK(fields->add(entryPtr, name, info)); @@ -4996,6 +4996,12 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb if (!SizeTojsval(cx, structSize, &sizeVal)) return false; + for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) { + FieldInfo& field = r.front().value(); + MOZ_ASSERT(field.mIndex < fieldRoots.length()); + field.mType = &fieldRoots[field.mIndex].toObject(); + } + JS_SetReservedSlot(typeObj, SLOT_FIELDINFO, PRIVATE_TO_JSVAL(fields.release())); JS_SetReservedSlot(typeObj, SLOT_SIZE, sizeVal); diff --git a/js/src/jit-test/tests/ctypes/bug1155985.js b/js/src/jit-test/tests/ctypes/bug1155985.js new file mode 100644 index 000000000000..54c24d4badfe --- /dev/null +++ b/js/src/jit-test/tests/ctypes/bug1155985.js @@ -0,0 +1,14 @@ +function test() { + for (let i = 0; i < 100; i++) { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }, + { "bar": ctypes.uint32_t }]); + + try { + new test_struct("foo", "x"); + } catch (e) { + } + } +} + +if (typeof ctypes === "object") + test(); From b032374d290fad6772d794955b298d45b873b87e Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 18:26:13 +0900 Subject: [PATCH 098/241] Bug 891107 - Part 1: Show information about value, type, function, and argument number in type conversion error messages in js-ctypes. r=jorendorff --- js/src/ctypes/CTypes.cpp | 802 +++++++++++++++--- js/src/ctypes/CTypes.h | 28 + js/src/ctypes/Library.cpp | 5 +- js/src/ctypes/ctypes.msg | 22 +- js/src/jit-test/lib/asserts.js | 20 + .../jit-test/tests/ctypes/conversion-array.js | 36 + .../jit-test/tests/ctypes/conversion-error.js | 14 + .../tests/ctypes/conversion-finalizer.js | 61 ++ .../tests/ctypes/conversion-function.js | 33 + .../jit-test/tests/ctypes/conversion-int64.js | 20 + .../ctypes/conversion-native-function.js | 37 + .../tests/ctypes/conversion-pointer.js | 29 + .../tests/ctypes/conversion-primitive.js | 44 + .../tests/ctypes/conversion-struct.js | 36 + .../tests/ctypes/conversion-to-primitive.js | 20 + js/src/jsexn.cpp | 40 + js/src/jsexn.h | 3 + .../ctypes/tests/unit/test_jsctypes.js | 36 +- 18 files changed, 1162 insertions(+), 124 deletions(-) create mode 100644 js/src/jit-test/tests/ctypes/conversion-array.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-error.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-finalizer.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-function.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-int64.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-native-function.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-pointer.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-primitive.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-struct.js create mode 100644 js/src/jit-test/tests/ctypes/conversion-to-primitive.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 2fe4187fbfb0..26099d919163 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -32,6 +32,7 @@ #endif #include "jscntxt.h" +#include "jsexn.h" #include "jsfun.h" #include "jsnum.h" #include "jsprf.h" @@ -40,6 +41,8 @@ #include "ctypes/Library.h" #include "gc/Zone.h" +#include "jsatominlines.h" + using namespace std; using mozilla::NumericLimits; @@ -876,21 +879,567 @@ GetErrorMessage(void* userRef, const unsigned errorNumber) return nullptr; } +static const char* +EncodeLatin1(JSContext* cx, AutoString& str, JSAutoByteString& bytes) +{ + return bytes.encodeLatin1(cx, NewUCString(cx, str)); +} + +static const char* +CTypesToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes) +{ + if (val.isObject() && + (CType::IsCType(&val.toObject()) || CData::IsCData(&val.toObject()))) { + RootedString str(cx, JS_ValueToSource(cx, val)); + return bytes.encodeLatin1(cx, str); + } + return ValueToSourceForError(cx, val, bytes); +} + +static void +BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj, + HandleString nameStr, unsigned ptrCount, + AutoString& source); + +static void +BuildCStyleTypeSource(JSContext* cx, JSObject* typeObj_, AutoString& source) +{ + RootedObject typeObj(cx, typeObj_); + + MOZ_ASSERT(CType::IsCType(typeObj)); + + switch (CType::GetTypeCode(typeObj)) { +#define BUILD_SOURCE(name, fromType, ffiType) \ + case TYPE_##name: \ + AppendString(source, #name); \ + break; + CTYPES_FOR_EACH_TYPE(BUILD_SOURCE) +#undef BUILD_SOURCE + case TYPE_void_t: + AppendString(source, "void"); + break; + case TYPE_pointer: { + unsigned ptrCount = 0; + TypeCode type; + RootedObject baseTypeObj(cx, typeObj); + do { + baseTypeObj = PointerType::GetBaseType(baseTypeObj); + ptrCount++; + type = CType::GetTypeCode(baseTypeObj); + } while (type == TYPE_pointer || type == TYPE_array); + if (type == TYPE_function) { + BuildCStyleFunctionTypeSource(cx, baseTypeObj, NullPtr(), ptrCount, + source); + break; + } + BuildCStyleTypeSource(cx, baseTypeObj, source); + AppendChars(source, '*', ptrCount); + break; + } + case TYPE_struct: { + RootedString name(cx, CType::GetName(cx, typeObj)); + AppendString(source, "struct "); + AppendString(source, name); + break; + } + case TYPE_function: + BuildCStyleFunctionTypeSource(cx, typeObj, NullPtr(), 0, source); + break; + case TYPE_array: + MOZ_CRASH("TYPE_array shouldn't appear in function type"); + } +} + +static void +BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj, + HandleString nameStr, unsigned ptrCount, + AutoString& source) +{ + MOZ_ASSERT(CType::IsCType(typeObj)); + + FunctionInfo* fninfo = FunctionType::GetFunctionInfo(typeObj); + BuildCStyleTypeSource(cx, fninfo->mReturnType, source); + AppendString(source, " "); + if (nameStr) { + MOZ_ASSERT(ptrCount == 0); + AppendString(source, nameStr); + } else if (ptrCount) { + AppendString(source, "("); + AppendChars(source, '*', ptrCount); + AppendString(source, ")"); + } + AppendString(source, "("); + if (fninfo->mArgTypes.length() > 0) { + for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) { + BuildCStyleTypeSource(cx, fninfo->mArgTypes[i], source); + if (i != fninfo->mArgTypes.length() - 1 || fninfo->mIsVariadic) { + AppendString(source, ", "); + } + } + if (fninfo->mIsVariadic) { + AppendString(source, "..."); + } + } + AppendString(source, ")"); +} + +static void +BuildFunctionTypeSource(JSContext* cx, HandleObject funObj, AutoString& source) +{ + MOZ_ASSERT(CData::IsCData(funObj) || CType::IsCType(funObj)); + + if (CData::IsCData(funObj)) { + jsval slot = JS_GetReservedSlot(funObj, SLOT_REFERENT); + if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) { + slot = JS_GetReservedSlot(funObj, SLOT_FUNNAME); + MOZ_ASSERT(!slot.isUndefined()); + RootedObject typeObj(cx, CData::GetCType(funObj)); + RootedObject baseTypeObj(cx, PointerType::GetBaseType(typeObj)); + RootedString nameStr(cx, slot.toString()); + BuildCStyleFunctionTypeSource(cx, baseTypeObj, nameStr, 0, source); + return; + } + } + + RootedValue funVal(cx, ObjectValue(*funObj)); + RootedString funcStr(cx, JS_ValueToSource(cx, funVal)); + if (!funcStr) { + JS_ClearPendingException(cx); + AppendString(source, "<>"); + return; + } + AppendString(source, funcStr); +} + +enum class ConversionType { + Argument = 0, + Construct, + Finalizer, + Return, + Setter +}; + +static void +BuildConversionPosition(JSContext* cx, ConversionType convType, + HandleObject funObj, unsigned argIndex, + AutoString& source) +{ + switch (convType) { + case ConversionType::Argument: { + MOZ_ASSERT(funObj); + + AppendString(source, " at argument "); + AppendUInt(source, argIndex + 1); + AppendString(source, " of "); + BuildFunctionTypeSource(cx, funObj, source); + break; + } + case ConversionType::Finalizer: + MOZ_ASSERT(funObj); + + AppendString(source, " at argument 1 of "); + BuildFunctionTypeSource(cx, funObj, source); + break; + case ConversionType::Return: + MOZ_ASSERT(funObj); + + AppendString(source, " at the return value of "); + BuildFunctionTypeSource(cx, funObj, source); + break; + default: + MOZ_ASSERT(!funObj); + break; + } +} + +static JSFlatString* +GetFieldName(HandleObject structObj, unsigned fieldIndex) +{ + const FieldInfoHash* fields = StructType::GetFieldInfo(structObj); + for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) { + if (r.front().value().mIndex == fieldIndex) { + return (&r.front())->key(); + } + } + return nullptr; +} + +static void +BuildTypeSource(JSContext* cx, JSObject* typeObj_, bool makeShort, + AutoString& result); + +static bool +ConvError(JSContext* cx, const char* expectedStr, HandleValue actual, + ConversionType convType, + HandleObject funObj = NullPtr(), unsigned argIndex = 0, + HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) +{ + JSAutoByteString valBytes; + const char* valStr = CTypesToSourceForError(cx, actual, valBytes); + if (!valStr) + return false; + + if (arrObj) { + MOZ_ASSERT(CType::IsCType(arrObj)); + + switch (CType::GetTypeCode(arrObj)) { + case TYPE_array: { + MOZ_ASSERT(!funObj); + + char indexStr[16]; + JS_snprintf(indexStr, 16, "%u", arrIndex); + + AutoString arrSource; + JSAutoByteString arrBytes; + BuildTypeSource(cx, arrObj, true, arrSource); + const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); + if (!arrStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_CONV_ERROR_ARRAY, + valStr, indexStr, arrStr); + break; + } + case TYPE_struct: { + JSFlatString* name = GetFieldName(arrObj, arrIndex); + MOZ_ASSERT(name); + JSAutoByteString nameBytes; + const char* nameStr = nameBytes.encodeLatin1(cx, name); + if (!nameStr) + return false; + + AutoString structSource; + JSAutoByteString structBytes; + BuildTypeSource(cx, arrObj, true, structSource); + const char* structStr = EncodeLatin1(cx, structSource, structBytes); + if (!structStr) + return false; + + JSAutoByteString posBytes; + const char* posStr; + if (funObj) { + AutoString posSource; + BuildConversionPosition(cx, convType, funObj, argIndex, posSource); + posStr = EncodeLatin1(cx, posSource, posBytes); + if (!posStr) + return false; + } else { + posStr = ""; + } + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_CONV_ERROR_STRUCT, + valStr, nameStr, expectedStr, structStr, posStr); + break; + } + default: + MOZ_CRASH("invalid arrObj value"); + } + return false; + } + + switch (convType) { + case ConversionType::Argument: { + MOZ_ASSERT(funObj); + + char indexStr[16]; + JS_snprintf(indexStr, 16, "%u", argIndex + 1); + + AutoString funSource; + JSAutoByteString funBytes; + BuildFunctionTypeSource(cx, funObj, funSource); + const char* funStr = EncodeLatin1(cx, funSource, funBytes); + if (!funStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_CONV_ERROR_ARG, + valStr, indexStr, funStr); + break; + } + case ConversionType::Finalizer: { + MOZ_ASSERT(funObj); + + AutoString funSource; + JSAutoByteString funBytes; + BuildFunctionTypeSource(cx, funObj, funSource); + const char* funStr = EncodeLatin1(cx, funSource, funBytes); + if (!funStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_CONV_ERROR_FIN, valStr, funStr); + break; + } + case ConversionType::Return: { + MOZ_ASSERT(funObj); + + AutoString funSource; + JSAutoByteString funBytes; + BuildFunctionTypeSource(cx, funObj, funSource); + const char* funStr = EncodeLatin1(cx, funSource, funBytes); + if (!funStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_CONV_ERROR_RET, valStr, funStr); + break; + } + case ConversionType::Setter: + case ConversionType::Construct: + MOZ_ASSERT(!funObj); + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_CONV_ERROR_SET, valStr, expectedStr); + break; + } + + return false; +} + +static bool +ConvError(JSContext* cx, HandleObject expectedType, HandleValue actual, + ConversionType convType, + HandleObject funObj = NullPtr(), unsigned argIndex = 0, + HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) +{ + MOZ_ASSERT(CType::IsCType(expectedType)); + + AutoString expectedSource; + JSAutoByteString expectedBytes; + BuildTypeSource(cx, expectedType, true, expectedSource); + const char* expectedStr = EncodeLatin1(cx, expectedSource, expectedBytes); + if (!expectedStr) + return false; + + return ConvError(cx, expectedStr, actual, convType, funObj, argIndex, + arrObj, arrIndex); +} + +static bool +ArgumentConvError(JSContext* cx, HandleValue actual, const char* funStr, + unsigned argIndex) +{ + JSAutoByteString valBytes; + const char* valStr = CTypesToSourceForError(cx, actual, valBytes); + if (!valStr) + return false; + + char indexStr[16]; + JS_snprintf(indexStr, 16, "%u", argIndex + 1); + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_CONV_ERROR_ARG, valStr, indexStr, funStr); + return false; +} + +static bool +ArrayLengthMismatch(JSContext* cx, unsigned expectedLength, HandleObject arrObj, + unsigned actualLength, HandleValue actual, + ConversionType convType) +{ + MOZ_ASSERT(arrObj && CType::IsCType(arrObj)); + + JSAutoByteString valBytes; + const char* valStr = CTypesToSourceForError(cx, actual, valBytes); + if (!valStr) + return false; + + char expectedLengthStr[16]; + JS_snprintf(expectedLengthStr, 16, "%u", expectedLength); + char actualLengthStr[16]; + JS_snprintf(actualLengthStr, 16, "%u", actualLength); + + AutoString arrSource; + JSAutoByteString arrBytes; + BuildTypeSource(cx, arrObj, true, arrSource); + const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); + if (!arrStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_ARRAY_MISMATCH, + valStr, arrStr, expectedLengthStr, actualLengthStr); + return false; +} + +static bool +ArrayLengthOverflow(JSContext* cx, unsigned expectedLength, HandleObject arrObj, + unsigned actualLength, HandleValue actual, + ConversionType convType) +{ + MOZ_ASSERT(arrObj && CType::IsCType(arrObj)); + + JSAutoByteString valBytes; + const char* valStr = CTypesToSourceForError(cx, actual, valBytes); + if (!valStr) + return false; + + char expectedLengthStr[16]; + JS_snprintf(expectedLengthStr, 16, "%u", expectedLength); + char actualLengthStr[16]; + JS_snprintf(actualLengthStr, 16, "%u", actualLength); + + AutoString arrSource; + JSAutoByteString arrBytes; + BuildTypeSource(cx, arrObj, true, arrSource); + const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); + if (!arrStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_ARRAY_OVERFLOW, + valStr, arrStr, expectedLengthStr, actualLengthStr); + return false; +} + +static bool +EmptyFinalizerError(JSContext* cx, ConversionType convType, + HandleObject funObj = NullPtr(), unsigned argIndex = 0) +{ + JSAutoByteString posBytes; + const char* posStr; + if (funObj) { + AutoString posSource; + BuildConversionPosition(cx, convType, funObj, argIndex, posSource); + posStr = EncodeLatin1(cx, posSource, posBytes); + if (!posStr) + return false; + } else { + posStr = ""; + } + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_EMPTY_FIN, posStr); + return false; +} + +static bool +FieldCountMismatch(JSContext* cx, + unsigned expectedCount, HandleObject structObj, + unsigned actualCount, HandleValue actual, + ConversionType convType, + HandleObject funObj = NullPtr(), unsigned argIndex = 0) +{ + MOZ_ASSERT(structObj && CType::IsCType(structObj)); + + JSAutoByteString valBytes; + const char* valStr = CTypesToSourceForError(cx, actual, valBytes); + if (!valStr) + return false; + + AutoString structSource; + JSAutoByteString structBytes; + BuildTypeSource(cx, structObj, true, structSource); + const char* structStr = EncodeLatin1(cx, structSource, structBytes); + if (!structStr) + return false; + + char expectedCountStr[16]; + JS_snprintf(expectedCountStr, 16, "%u", expectedCount); + char actualCountStr[16]; + JS_snprintf(actualCountStr, 16, "%u", actualCount); + + JSAutoByteString posBytes; + const char* posStr; + if (funObj) { + AutoString posSource; + BuildConversionPosition(cx, convType, funObj, argIndex, posSource); + posStr = EncodeLatin1(cx, posSource, posBytes); + if (!posStr) + return false; + } else { + posStr = ""; + } + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_FIELD_MISMATCH, + valStr, structStr, expectedCountStr, actualCountStr, + posStr); + return false; +} + +static bool +FinalizerSizeError(JSContext* cx, HandleObject funObj, HandleValue actual) +{ + MOZ_ASSERT(CType::IsCType(funObj)); + + JSAutoByteString valBytes; + const char* valStr = CTypesToSourceForError(cx, actual, valBytes); + if (!valStr) + return false; + + AutoString funSource; + JSAutoByteString funBytes; + BuildFunctionTypeSource(cx, funObj, funSource); + const char* funStr = EncodeLatin1(cx, funSource, funBytes); + if (!funStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_FIN_SIZE_ERROR, funStr, valStr); + return false; +} + +static bool +NonPrimitiveError(JSContext* cx, HandleObject typeObj) +{ + MOZ_ASSERT(CType::IsCType(typeObj)); + + AutoString typeSource; + JSAutoByteString typeBytes; + BuildTypeSource(cx, typeObj, true, typeSource); + const char* typeStr = EncodeLatin1(cx, typeSource, typeBytes); + if (!typeStr) + return false; + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_NON_PRIMITIVE, typeStr); + return false; +} + +static bool +PropNameNonStringError(JSContext* cx, HandleId id, HandleValue actual, + ConversionType convType, + HandleObject funObj = NullPtr(), unsigned argIndex = 0) +{ + JSAutoByteString valBytes; + const char* valStr = CTypesToSourceForError(cx, actual, valBytes); + if (!valStr) + return false; + + JSAutoByteString idBytes; + RootedValue idVal(cx, IdToValue(id)); + const char* propStr = CTypesToSourceForError(cx, idVal, idBytes); + if (!propStr) + return false; + + JSAutoByteString posBytes; + const char* posStr; + if (funObj) { + AutoString posSource; + BuildConversionPosition(cx, convType, funObj, argIndex, posSource); + posStr = EncodeLatin1(cx, posSource, posBytes); + if (!posStr) + return false; + } else { + posStr = ""; + } + + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_PROP_NONSTRING, propStr, valStr, posStr); + return false; +} + static bool TypeError(JSContext* cx, const char* expected, HandleValue actual) { - JSString* str = JS_ValueToSource(cx, actual); JSAutoByteString bytes; + const char* src = CTypesToSourceForError(cx, actual, bytes); + if (!src) + return false; - const char* src; - if (str) { - src = bytes.encodeLatin1(cx, str); - if (!src) - return false; - } else { - JS_ClearPendingException(cx); - src = "<>"; - } JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, CTYPESMSG_TYPE_ERROR, expected, src); return false; @@ -2210,8 +2759,7 @@ ConvertToJS(JSContext* cx, // We're about to create a new CData object to return. If the caller doesn't // want this, return early. if (wantPrimitive) { - JS_ReportError(cx, "cannot convert to primitive value"); - return false; + return NonPrimitiveError(cx, typeObj); } JSObject* obj = CData::Create(cx, typeObj, parentObj, data, ownResult); @@ -2276,18 +2824,20 @@ bool CanConvertTypedArrayItemTo(JSObject* baseType, JSObject* valObj, JSContext* // coercion between types. There are two cases in which this function is used: // 1) The target buffer is internal to a CData object; we simply write data // into it. -// 2) We are converting an argument for an ffi call, in which case 'isArgument' -// will be true. This allows us to handle a special case: if necessary, -// we can autoconvert a JS string primitive to a pointer-to-character type. -// In this case, ownership of the allocated string is handed off to the -// caller; 'freePointer' will be set to indicate this. +// 2) We are converting an argument for an ffi call, in which case 'convType' +// will be 'ConversionType::Argument'. This allows us to handle a special +// case: if necessary, we can autoconvert a JS string primitive to a +// pointer-to-character type. In this case, ownership of the allocated string +// is handed off to the caller; 'freePointer' will be set to indicate this. static bool ImplicitConvert(JSContext* cx, HandleValue val, JSObject* targetType_, void* buffer, - bool isArgument, - bool* freePointer) + ConversionType convType, + bool* freePointer, + HandleObject funObj = NullPtr(), unsigned argIndex = 0, + HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) { RootedObject targetType(cx, targetType_); MOZ_ASSERT(CType::IsSizeDefined(targetType)); @@ -2319,8 +2869,7 @@ ImplicitConvert(JSContext* cx, if (!p) { // We have called |dispose| or |forget| already. - JS_ReportError(cx, "Attempting to convert an empty CDataFinalizer"); - return false; + return EmptyFinalizerError(cx, convType, funObj, argIndex); } // If the types are equal, copy the buffer contained within the CData. @@ -2339,7 +2888,8 @@ ImplicitConvert(JSContext* cx, // Programs can convert explicitly, if needed, using `Boolean(v)` or `!!v`. bool result; if (!jsvalToBool(cx, val, &result)) - return TypeError(cx, "boolean", val); + return ConvError(cx, "boolean", val, convType, funObj, argIndex, + arrObj, arrIndex); *static_cast(buffer) = result; break; } @@ -2351,13 +2901,15 @@ ImplicitConvert(JSContext* cx, if (val.isString()) { \ JSString* str = val.toString(); \ if (str->length() != 1) \ - return TypeError(cx, #name, val); \ + return ConvError(cx, #name, val, convType, funObj, argIndex, \ + arrObj, arrIndex); \ JSLinearString* linear = str->ensureLinear(cx); \ if (!linear) \ return false; \ result = linear->latin1OrTwoByteChar(0); \ } else if (!jsvalToInteger(cx, val, &result)) { \ - return TypeError(cx, #name, val); \ + return ConvError(cx, #name, val, convType, funObj, argIndex, \ + arrObj, arrIndex); \ } \ *static_cast(buffer) = result; \ break; \ @@ -2369,7 +2921,8 @@ ImplicitConvert(JSContext* cx, /* Do not implicitly lose bits. */ \ type result; \ if (!jsvalToInteger(cx, val, &result)) \ - return TypeError(cx, #name, val); \ + return ConvError(cx, #name, val, convType, funObj, argIndex, \ + arrObj, arrIndex); \ *static_cast(buffer) = result; \ break; \ } @@ -2385,7 +2938,8 @@ ImplicitConvert(JSContext* cx, case TYPE_##name: { \ type result; \ if (!jsvalToFloat(cx, val, &result)) \ - return TypeError(cx, #name, val); \ + return ConvError(cx, #name, val, convType, funObj, argIndex, \ + arrObj, arrIndex); \ *static_cast(buffer) = result; \ break; \ } @@ -2420,7 +2974,7 @@ ImplicitConvert(JSContext* cx, } } - } else if (isArgument && val.isString()) { + } else if (convType == ConversionType::Argument && val.isString()) { // Convert the string for the ffi call. This requires allocating space // which the caller assumes ownership of. // TODO: Extend this so we can safely convert strings at other times also. @@ -2474,7 +3028,8 @@ ImplicitConvert(JSContext* cx, break; } default: - return TypeError(cx, "string pointer", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } break; } else if (val.isObject() && JS_IsArrayBufferObject(valObj)) { @@ -2482,8 +3037,9 @@ ImplicitConvert(JSContext* cx, // when converting an argument to a function call, as it is possible for // the pointer to be invalidated by anything that runs JS code. (It is // invalid to invoke JS code from a ctypes function call.) - if (!isArgument) { - return TypeError(cx, "arraybuffer pointer", val); + if (convType != ConversionType::Argument) { + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } void* ptr; { @@ -2491,7 +3047,8 @@ ImplicitConvert(JSContext* cx, ptr = JS_GetArrayBufferData(valObj, nogc); } if (!ptr) { - return TypeError(cx, "arraybuffer pointer", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } *static_cast(buffer) = ptr; break; @@ -2499,10 +3056,12 @@ ImplicitConvert(JSContext* cx, // Same as ArrayBuffer, above, though note that this will take the // offset of the view into account. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { - return TypeError(cx, "typed array with the appropriate type", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } - if (!isArgument) { - return TypeError(cx, "typed array pointer", val); + if (convType != ConversionType::Argument) { + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } void* ptr; { @@ -2510,14 +3069,18 @@ ImplicitConvert(JSContext* cx, ptr = JS_GetArrayBufferViewData(valObj, nogc); } if (!ptr) { - return TypeError(cx, "typed array pointer", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } *static_cast(buffer) = ptr; break; } - return TypeError(cx, "pointer", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } case TYPE_array: { + MOZ_ASSERT(!funObj); + RootedObject baseType(cx, ArrayType::GetBaseType(targetType)); size_t targetLength = ArrayType::GetLength(targetType); @@ -2539,8 +3102,9 @@ ImplicitConvert(JSContext* cx, return false; if (targetLength < nbytes) { - JS_ReportError(cx, "ArrayType has insufficient length"); - return false; + MOZ_ASSERT(!funObj); + return ArrayLengthOverflow(cx, targetLength, targetType, nbytes, val, + convType); } char* charBuffer = static_cast(buffer); @@ -2556,8 +3120,9 @@ ImplicitConvert(JSContext* cx, // Copy the string data, char16_t for char16_t, including the terminator // if there's space. if (targetLength < sourceLength) { - JS_ReportError(cx, "ArrayType has insufficient length"); - return false; + MOZ_ASSERT(!funObj); + return ArrayLengthOverflow(cx, targetLength, targetType, + sourceLength, val, convType); } char16_t* dest = static_cast(buffer); @@ -2575,7 +3140,8 @@ ImplicitConvert(JSContext* cx, break; } default: - return TypeError(cx, "array", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } } else if (val.isObject() && JS_IsArrayObject(cx, valObj)) { @@ -2583,8 +3149,9 @@ ImplicitConvert(JSContext* cx, uint32_t sourceLength; if (!JS_GetArrayLength(cx, valObj, &sourceLength) || targetLength != size_t(sourceLength)) { - JS_ReportError(cx, "ArrayType length does not match source array length"); - return false; + MOZ_ASSERT(!funObj); + return ArrayLengthMismatch(cx, targetLength, targetType, + size_t(sourceLength), val, convType); } // Convert into an intermediate, in case of failure. @@ -2602,7 +3169,8 @@ ImplicitConvert(JSContext* cx, return false; char* data = intermediate.get() + elementSize * i; - if (!ImplicitConvert(cx, item, baseType, data, false, nullptr)) + if (!ImplicitConvert(cx, item, baseType, data, convType, nullptr, + funObj, argIndex, targetType, i)) return false; } @@ -2615,8 +3183,9 @@ ImplicitConvert(JSContext* cx, size_t elementSize = CType::GetSize(baseType); size_t arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { - JS_ReportError(cx, "ArrayType length does not match source ArrayBuffer length"); - return false; + MOZ_ASSERT(!funObj); + return ArrayLengthMismatch(cx, arraySize, targetType, + size_t(sourceLength), val, convType); } JS::AutoCheckCannotGC nogc; memcpy(buffer, JS_GetArrayBufferData(valObj, nogc), sourceLength); @@ -2625,15 +3194,17 @@ ImplicitConvert(JSContext* cx, // Check that array is consistent with type, then // copy the array. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { - return TypeError(cx, "typed array with the appropriate type", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } uint32_t sourceLength = JS_GetTypedArrayByteLength(valObj); size_t elementSize = CType::GetSize(baseType); size_t arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { - JS_ReportError(cx, "typed array length does not match source TypedArray length"); - return false; + MOZ_ASSERT(!funObj); + return ArrayLengthMismatch(cx, arraySize, targetType, + size_t(sourceLength), val, convType); } JS::AutoCheckCannotGC nogc; memcpy(buffer, JS_GetArrayBufferViewData(valObj, nogc), sourceLength); @@ -2641,7 +3212,8 @@ ImplicitConvert(JSContext* cx, } else { // Don't implicitly convert to string. Users can implicitly convert // with `String(x)` or `""+x`. - return TypeError(cx, "array", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } break; } @@ -2663,8 +3235,9 @@ ImplicitConvert(JSContext* cx, const FieldInfoHash* fields = StructType::GetFieldInfo(targetType); if (props.length() != fields->count()) { - JS_ReportError(cx, "missing fields"); - return false; + return FieldCountMismatch(cx, fields->count(), targetType, + props.length(), val, convType, + funObj, argIndex); } RootedId id(cx); @@ -2672,8 +3245,8 @@ ImplicitConvert(JSContext* cx, id = props[i]; if (!JSID_IS_STRING(id)) { - JS_ReportError(cx, "property name is not a string"); - return false; + return PropNameNonStringError(cx, id, val, convType, + funObj, argIndex); } JSFlatString* name = JSID_TO_FLAT_STRING(id); @@ -2687,7 +3260,8 @@ ImplicitConvert(JSContext* cx, // Convert the field via ImplicitConvert(). char* fieldData = intermediate.get() + field->mOffset; - if (!ImplicitConvert(cx, prop, field->mType, fieldData, false, nullptr)) + if (!ImplicitConvert(cx, prop, field->mType, fieldData, convType, + nullptr, funObj, argIndex, targetType, i)) return false; } @@ -2695,7 +3269,8 @@ ImplicitConvert(JSContext* cx, break; } - return TypeError(cx, "struct", val); + return ConvError(cx, targetType, val, convType, funObj, argIndex, + arrObj, arrIndex); } case TYPE_void_t: case TYPE_function: @@ -2709,10 +3284,11 @@ ImplicitConvert(JSContext* cx, // storing the result in 'buffer'. This function is more forceful than // ImplicitConvert. static bool -ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, void* buffer) +ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, + void* buffer, ConversionType convType) { // If ImplicitConvert succeeds, use that result. - if (ImplicitConvert(cx, val, targetType, buffer, false, nullptr)) + if (ImplicitConvert(cx, val, targetType, buffer, convType, nullptr)) return true; // If ImplicitConvert failed, and there is no pending exception, then assume @@ -2741,7 +3317,7 @@ ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, void* b if (!jsvalToIntegerExplicit(val, &result) && \ (!val.isString() || \ !StringToInteger(cx, val.toString(), &result))) \ - return TypeError(cx, #name, val); \ + return ConvError(cx, #name, val, convType); \ *static_cast(buffer) = result; \ break; \ } @@ -2754,7 +3330,7 @@ ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, void* b // Convert a number, Int64 object, or UInt64 object to a pointer. uintptr_t result; if (!jsvalToPtrExplicit(cx, val, &result)) - return TypeError(cx, "pointer", val); + return ConvError(cx, targetType, val, convType); *static_cast(buffer) = result; break; } @@ -3268,7 +3844,8 @@ CType::ConstructBasic(JSContext* cx, return false; if (args.length() == 1) { - if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result))) + if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result), + ConversionType::Construct)) return false; } @@ -4069,7 +4646,8 @@ PointerType::ConstructData(JSContext* cx, JS_ReportError(cx, "first argument must be a function"); return false; } - return ExplicitConvert(cx, args[0], obj, CData::GetData(result)); + return ExplicitConvert(cx, args[0], obj, CData::GetData(result), + ConversionType::Construct); } // @@ -4253,7 +4831,8 @@ PointerType::ContentsSetter(JSContext* cx, JS::CallArgs args) } args.rval().setUndefined(); - return ImplicitConvert(cx, args.get(0), baseType, data, false, nullptr); + return ImplicitConvert(cx, args.get(0), baseType, data, + ConversionType::Setter, nullptr); } /******************************************************************************* @@ -4420,7 +4999,7 @@ ArrayType::ConstructData(JSContext* cx, length = sourceLength + 1; break; default: - return TypeError(cx, "array", args[0]); + return ConvError(cx, obj, args[0], ConversionType::Construct); } } else { @@ -4441,7 +5020,8 @@ ArrayType::ConstructData(JSContext* cx, args.rval().setObject(*result); if (convertObject) { - if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result))) + if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result), + ConversionType::Construct)) return false; } @@ -4611,7 +5191,8 @@ ArrayType::Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle size_t length = GetLength(typeObj); bool ok = jsidToSize(cx, idval, true, &index); int32_t dummy; - if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { + if (!ok && JSID_IS_STRING(idval) && + !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { // String either isn't a number, or doesn't fit in size_t. // Chances are it's a regular property lookup, so return. return true; @@ -4639,7 +5220,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle // Bail early if we're not an ArrayType. (This setter is present for all // CData, regardless of CType.) - JSObject* typeObj = CData::GetCType(obj); + RootedObject typeObj(cx, CData::GetCType(obj)); if (CType::GetTypeCode(typeObj) != TYPE_array) return result.succeed(); @@ -4648,7 +5229,8 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle size_t length = GetLength(typeObj); bool ok = jsidToSize(cx, idval, true, &index); int32_t dummy; - if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { + if (!ok && JSID_IS_STRING(idval) && + !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { // String either isn't a number, or doesn't fit in size_t. // Chances are it's a regular property lookup, so return. return result.succeed(); @@ -4658,10 +5240,11 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle return false; } - JSObject* baseType = GetBaseType(typeObj); + RootedObject baseType(cx, GetBaseType(typeObj)); size_t elementSize = CType::GetSize(baseType); char* data = static_cast(CData::GetData(obj)) + elementSize * index; - if (!ImplicitConvert(cx, vp, baseType, data, false, nullptr)) + if (!ImplicitConvert(cx, vp, baseType, data, ConversionType::Setter, + nullptr, NullPtr(), 0, typeObj, index)) return false; return result.succeed(); } @@ -5156,7 +5739,7 @@ StructType::ConstructData(JSContext* cx, // are mutually exclusive, so we can pick the right one. // Try option 1) first. - if (ExplicitConvert(cx, args[0], obj, buffer)) + if (ExplicitConvert(cx, args[0], obj, buffer, ConversionType::Construct)) return true; if (fields->count() != 1) @@ -5181,8 +5764,8 @@ StructType::ConstructData(JSContext* cx, const FieldInfo& field = r.front().value(); STATIC_ASSUME(field.mIndex < fields->count()); /* Quantified invariant */ if (!ImplicitConvert(cx, args[field.mIndex], field.mType, - buffer + field.mOffset, - false, nullptr)) + buffer + field.mOffset, ConversionType::Construct, + nullptr, NullPtr(), 0, obj, field.mIndex)) return false; } @@ -5346,7 +5929,7 @@ StructType::FieldSetter(JSContext* cx, unsigned argc, Value* vp) return false; } - JSObject* typeObj = CData::GetCType(obj); + RootedObject typeObj(cx, CData::GetCType(obj)); if (CType::GetTypeCode(typeObj) != TYPE_struct) { JS_ReportError(cx, "not a StructType"); return false; @@ -5364,7 +5947,8 @@ StructType::FieldSetter(JSContext* cx, unsigned argc, Value* vp) args.rval().setUndefined(); char* data = static_cast(CData::GetData(obj)) + field->mOffset; - return ImplicitConvert(cx, args.get(0), field->mType, data, false, nullptr); + return ImplicitConvert(cx, args.get(0), field->mType, data, ConversionType::Setter, nullptr, + NullPtr(), 0, typeObj, field->mIndex); } bool @@ -5850,6 +6434,8 @@ typedef Array AutoValueAutoArray; static bool ConvertArgument(JSContext* cx, + HandleObject funObj, + unsigned argIndex, HandleValue arg, JSObject* type, AutoValue* value, @@ -5861,7 +6447,9 @@ ConvertArgument(JSContext* cx, } bool freePointer = false; - if (!ImplicitConvert(cx, arg, type, value->mData, true, &freePointer)) + if (!ImplicitConvert(cx, arg, type, value->mData, + ConversionType::Argument, &freePointer, + funObj, argIndex)) return false; if (freePointer) { @@ -5930,7 +6518,8 @@ FunctionType::Call(JSContext* cx, } for (unsigned i = 0; i < argcFixed; ++i) - if (!ConvertArgument(cx, args[i], fninfo->mArgTypes[i], &values[i], &strings)) + if (!ConvertArgument(cx, obj, i, args[i], fninfo->mArgTypes[i], + &values[i], &strings)) return false; if (fninfo->mIsVariadic) { @@ -5955,7 +6544,7 @@ FunctionType::Call(JSContext* cx, !(type = PrepareType(cx, OBJECT_TO_JSVAL(type))) || // Relying on ImplicitConvert only for the limited purpose of // converting one CType to another (e.g., T[] to T*). - !ConvertArgument(cx, args[i], type, &values[i], &strings) || + !ConvertArgument(cx, obj, i, args[i], type, &values[i], &strings) || !(fninfo->mFFITypes[i] = CType::GetFFIType(cx, type))) { // These functions report their own errors. return false; @@ -6181,7 +6770,8 @@ CClosure::Create(JSContext* cx, return nullptr; // Do the value conversion. This might fail, in which case we throw. - if (!ImplicitConvert(cx, errVal, fninfo->mReturnType, errResult.get(), false, nullptr)) + if (!ImplicitConvert(cx, errVal, fninfo->mReturnType, errResult.get(), + ConversionType::Return, nullptr, typeObj)) return nullptr; } @@ -6328,14 +6918,14 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData) RootedValue rval(cx); bool success = JS_CallFunctionValue(cx, thisObj, jsfnVal, argv, &rval); - // Convert the result. Note that we pass 'isArgument = false', such that + // Convert the result. Note that we pass 'ConversionType::Return', such that // ImplicitConvert will *not* autoconvert a JS string into a pointer-to-char // type, which would require an allocation that we can't track. The JS // function must perform this conversion itself and return a PointerType // CData; thusly, the burden of freeing the data is left to the user. if (success && cif->rtype != &ffi_type_void) - success = ImplicitConvert(cx, rval, fninfo->mReturnType, result, false, - nullptr); + success = ImplicitConvert(cx, rval, fninfo->mReturnType, result, + ConversionType::Return, nullptr, typeObj); if (!success) { // Something failed. The callee may have thrown, or it may not have @@ -6562,7 +7152,8 @@ CData::ValueSetter(JSContext* cx, JS::CallArgs args) { RootedObject obj(cx, &args.thisv().toObject()); args.rval().setUndefined(); - return ImplicitConvert(cx, args.get(0), GetCType(obj), GetData(obj), false, nullptr); + return ImplicitConvert(cx, args.get(0), GetCType(obj), GetData(obj), + ConversionType::Setter, nullptr); } bool @@ -7050,7 +7641,7 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) TypeCode typCodePtr = CType::GetTypeCode(objCodePtrType); if (typCodePtr != TYPE_pointer) { return TypeError(cx, "a CData object of a function _pointer_ type", - valCodePtrType); + valCodePtr); } JSObject* objCodeType = PointerType::GetBaseType(objCodePtrType); @@ -7059,12 +7650,12 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) TypeCode typCode = CType::GetTypeCode(objCodeType); if (typCode != TYPE_function) { return TypeError(cx, "a CData object of a _function_ pointer type", - valCodePtrType); + valCodePtr); } uintptr_t code = *reinterpret_cast(CData::GetData(objCodePtr)); if (!code) { return TypeError(cx, "a CData object of a _non-NULL_ function pointer type", - valCodePtrType); + valCodePtr); } FunctionInfo* funInfoFinalizer = @@ -7090,16 +7681,17 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) size_t sizeArg; RootedValue valData(cx, args[0]); if (!CType::GetSafeSize(objArgType, &sizeArg)) { - return TypeError(cx, "(an object with known size)", valData); + RootedValue valCodeType(cx, ObjectValue(*objCodeType)); + return TypeError(cx, "a function with one known size argument", + valCodeType); } ScopedJSFreePtr cargs(malloc(sizeArg)); if (!ImplicitConvert(cx, valData, objArgType, cargs.get(), - false, &freePointer)) { - RootedValue valArgType(cx, ObjectValue(*objArgType)); - return TypeError(cx, "(an object that can be converted to the following type)", - valArgType); + ConversionType::Finalizer, &freePointer, + objCodePtrType, 0)) { + return false; } if (freePointer) { // Note: We could handle that case, if necessary. @@ -7135,7 +7727,7 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) MOZ_CRASH("object with unknown size"); } if (sizeBestArg != sizeArg) { - return TypeError(cx, "(an object with the same size as that expected by the C finalization function)", valData); + return FinalizerSizeError(cx, objCodePtrType, valData); } } } @@ -7246,8 +7838,8 @@ CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval* vp) if (!obj) return false; if (!CDataFinalizer::IsCDataFinalizer(obj)) { - RootedValue val(cx, ObjectValue(*obj)); - return TypeError(cx, "a CDataFinalizer", val); + JS_ReportError(cx, "not a CDataFinalizer"); + return false; } CDataFinalizer::Private* p = (CDataFinalizer::Private*) @@ -7294,8 +7886,8 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval* vp) if (!obj) return false; if (!CDataFinalizer::IsCDataFinalizer(obj)) { - RootedValue val(cx, ObjectValue(*obj)); - return TypeError(cx, "a CDataFinalizer", val); + JS_ReportError(cx, "not a CDataFinalizer"); + return false; } CDataFinalizer::Private* p = (CDataFinalizer::Private*) @@ -7534,8 +8126,9 @@ Int64::Construct(JSContext* cx, } int64_t i = 0; - if (!jsvalToBigInteger(cx, args[0], true, &i)) - return TypeError(cx, "int64", args[0]); + if (!jsvalToBigInteger(cx, args[0], true, &i)) { + return ArgumentConvError(cx, args[0], "Int64", 0); + } // Get ctypes.Int64.prototype from the 'prototype' property of the ctor. RootedValue slot(cx); @@ -7669,9 +8262,9 @@ Int64::Join(JSContext* cx, unsigned argc, jsval* vp) int32_t hi; uint32_t lo; if (!jsvalToInteger(cx, args[0], &hi)) - return TypeError(cx, "int32", args[0]); + return ArgumentConvError(cx, args[0], "Int64.join", 0); if (!jsvalToInteger(cx, args[1], &lo)) - return TypeError(cx, "uint32", args[1]); + return ArgumentConvError(cx, args[1], "Int64.join", 1); int64_t i = (int64_t(hi) << 32) + int64_t(lo); @@ -7704,8 +8297,9 @@ UInt64::Construct(JSContext* cx, } uint64_t u = 0; - if (!jsvalToBigInteger(cx, args[0], true, &u)) - return TypeError(cx, "uint64", args[0]); + if (!jsvalToBigInteger(cx, args[0], true, &u)) { + return ArgumentConvError(cx, args[0], "UInt64", 0); + } // Get ctypes.UInt64.prototype from the 'prototype' property of the ctor. RootedValue slot(cx); @@ -7835,9 +8429,9 @@ UInt64::Join(JSContext* cx, unsigned argc, jsval* vp) uint32_t hi; uint32_t lo; if (!jsvalToInteger(cx, args[0], &hi)) - return TypeError(cx, "uint32_t", args[0]); + return ArgumentConvError(cx, args[0], "UInt64.join", 0); if (!jsvalToInteger(cx, args[1], &lo)) - return TypeError(cx, "uint32_t", args[1]); + return ArgumentConvError(cx, args[1], "UInt64.join", 1); uint64_t u = (uint64_t(hi) << 32) + uint64_t(lo); diff --git a/js/src/ctypes/CTypes.h b/js/src/ctypes/CTypes.h index 40e9fb0bbf40..7c6c971e0765 100644 --- a/js/src/ctypes/CTypes.h +++ b/js/src/ctypes/CTypes.h @@ -10,6 +10,7 @@ #include "ffi.h" #include "jsalloc.h" +#include "jsprf.h" #include "prlink.h" #include "ctypes/typedefs.h" @@ -53,6 +54,32 @@ AppendString(Vector& v, const char (&array)[ArrayLength]) v[i + vlen] = array[i]; } +template +void +AppendChars(Vector& v, const char c, size_t count) +{ + size_t vlen = v.length(); + if (!v.resize(vlen + count)) + return; + + for (size_t i = 0; i < count; ++i) + v[i + vlen] = c; +} + +template +void +AppendUInt(Vector& v, unsigned n) +{ + char array[16]; + size_t alen = JS_snprintf(array, 16, "%u", n); + size_t vlen = v.length(); + if (!v.resize(vlen + alen)) + return; + + for (size_t i = 0; i < alen; ++i) + v[i + vlen] = array[i]; +} + template void AppendString(Vector& v, Vector& w) @@ -375,6 +402,7 @@ enum CDataSlot { SLOT_REFERENT = 1, // JSObject this object must keep alive, if any SLOT_DATA = 2, // pointer to a buffer containing the binary data SLOT_OWNS = 3, // JSVAL_TRUE if this CData owns its own buffer + SLOT_FUNNAME = 4, // JSString representing the function name CDATA_SLOTS }; diff --git a/js/src/ctypes/Library.cpp b/js/src/ctypes/Library.cpp index 80a2d2d7321f..688c8a03d836 100644 --- a/js/src/ctypes/Library.cpp +++ b/js/src/ctypes/Library.cpp @@ -321,7 +321,7 @@ Library::Declare(JSContext* cx, unsigned argc, jsval* vp) void* data; PRFuncPtr fnptr; - JSString* nameStr = args[0].toString(); + RootedString nameStr(cx, args[0].toString()); AutoCString symbol; if (isFunction) { // Build the symbol, with mangling if necessary. @@ -352,6 +352,9 @@ Library::Declare(JSContext* cx, unsigned argc, jsval* vp) if (!result) return false; + if (isFunction) + JS_SetReservedSlot(result, SLOT_FUNNAME, StringValue(nameStr)); + args.rval().setObject(*result); // Seal the CData object, to prevent modification of the function pointer. diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg index 7178fcb26b3b..aa1a709fe0f1 100644 --- a/js/src/ctypes/ctypes.msg +++ b/js/src/ctypes/ctypes.msg @@ -10,5 +10,25 @@ */ MSG_DEF(CTYPESMSG_PLACEHOLDER_0, 0, JSEXN_NONE, NULL) -MSG_DEF(CTYPESMSG_TYPE_ERROR, 2, JSEXN_TYPEERR, "expected type {0}, got {1}") +/* type conversion */ +MSG_DEF(CTYPESMSG_CONV_ERROR_ARG,3, JSEXN_TYPEERR, "can't pass {0} to argument {1} of {2}") +MSG_DEF(CTYPESMSG_CONV_ERROR_ARRAY,3, JSEXN_TYPEERR, "can't convert {0} to element {1} of the type {2}") +MSG_DEF(CTYPESMSG_CONV_ERROR_FIN,2, JSEXN_TYPEERR, "can't convert {0} to the type of argument 1 of {1}") +MSG_DEF(CTYPESMSG_CONV_ERROR_RET,2, JSEXN_TYPEERR, "can't convert {0} to the return type of {1}") +MSG_DEF(CTYPESMSG_CONV_ERROR_SET,2, JSEXN_TYPEERR, "can't convert {0} to the type {1}") +MSG_DEF(CTYPESMSG_CONV_ERROR_STRUCT,5, JSEXN_TYPEERR, "can't convert {0} to the '{1}' field ({2}) of {3}{4}") +MSG_DEF(CTYPESMSG_NON_PRIMITIVE, 1, JSEXN_TYPEERR, ".value only works on character and numeric types, not `{0}`") +MSG_DEF(CTYPESMSG_TYPE_ERROR, 2, JSEXN_TYPEERR, "expected {0}, got {1}") + +/* array */ +MSG_DEF(CTYPESMSG_ARRAY_MISMATCH,4, JSEXN_TYPEERR, "length of {0} does not match to the length of the type {1} (expected {2}, got {3})") +MSG_DEF(CTYPESMSG_ARRAY_OVERFLOW,4, JSEXN_TYPEERR, "length of {0} does not fit to the length of the type {1} (expected {2} or lower, got {3})") + +/* struct */ +MSG_DEF(CTYPESMSG_FIELD_MISMATCH,5, JSEXN_TYPEERR, "property count of {0} does not match to field count of the type {1} (expected {2}, got {3}){4}") +MSG_DEF(CTYPESMSG_PROP_NONSTRING,3, JSEXN_TYPEERR, "property name {0} of {1} is not a string{2}") + +/* data finalizer */ +MSG_DEF(CTYPESMSG_EMPTY_FIN, 1, JSEXN_TYPEERR, "attempting to convert an empty CDataFinalizer{0}") +MSG_DEF(CTYPESMSG_FIN_SIZE_ERROR,2, JSEXN_TYPEERR, "expected an object with the same size as argument 1 of {0}, got {1}") diff --git a/js/src/jit-test/lib/asserts.js b/js/src/jit-test/lib/asserts.js index a87364542211..c183a446fc08 100644 --- a/js/src/jit-test/lib/asserts.js +++ b/js/src/jit-test/lib/asserts.js @@ -65,3 +65,23 @@ if (typeof assertNoWarning === 'undefined') { } }; } + +if (typeof assertTypeErrorMessage === 'undefined') { + var assertTypeErrorMessage = function assertTypeErrorMessage(f, test) { + try { + f(); + } catch (e) { + if (!(e instanceof TypeError)) + throw new Error("Assertion failed: expected exception TypeError, got " + e); + if (typeof test == "string") { + if (test != e.message) + throw new Error("Assertion failed: expeceted " + test + ", got " + e.message); + } else { + if (!test.test(e.message)) + throw new Error("Assertion failed: expeceted " + test.toString() + ", got " + e.message); + } + return; + } + throw new Error("Assertion failed: expected exception TypeError, no exception thrown"); + }; +} diff --git a/js/src/jit-test/tests/ctypes/conversion-array.js b/js/src/jit-test/tests/ctypes/conversion-array.js new file mode 100644 index 000000000000..840c1a0feb43 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-array.js @@ -0,0 +1,36 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + // constructor + assertTypeErrorMessage(() => { ctypes.int32_t.array()("foo"); }, + "can't convert the string \"foo\" to the type ctypes.int32_t.array()"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)("foo"); }, + "can't convert the string \"foo\" to the type ctypes.int32_t.array(10)"); + assertTypeErrorMessage(() => { ctypes.char.array(2)("foo"); }, + "length of the string \"foo\" does not fit to the length of the type ctypes.char.array(2) (expected 2 or lower, got 3)"); + assertTypeErrorMessage(() => { ctypes.char16_t.array(2)("foo"); }, + "length of the string \"foo\" does not fit to the length of the type ctypes.char16_t.array(2) (expected 2 or lower, got 3)"); + assertTypeErrorMessage(() => { ctypes.int8_t.array(2)(new ArrayBuffer(8)); }, + "length of the array buffer ({}) does not match to the length of the type ctypes.int8_t.array(2) (expected 2, got 8)"); + assertTypeErrorMessage(() => { ctypes.int8_t.array(2)(new Int8Array(8)); }, + "length of the typed array ({0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0}) does not match to the length of the type ctypes.int8_t.array(2) (expected 2, got 8)"); + + // elem setter + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)()[0] = "foo"; }, + "can't convert the string \"foo\" to element 0 of the type ctypes.int32_t.array(10)"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)()[1] = "foo"; }, + "can't convert the string \"foo\" to element 1 of the type ctypes.int32_t.array(10)"); + + // value setter + assertTypeErrorMessage(() => { ctypes.int32_t.array(1)().value = ["foo"]; }, + "can't convert the string \"foo\" to element 0 of the type ctypes.int32_t.array(1)"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(1)().value = [2, "foo"]; }, + "length of the array [2, \"foo\"] does not match to the length of the type ctypes.int32_t.array(1) (expected 1, got 2)"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(2)().value = [2, "foo"]; }, + "can't convert the string \"foo\" to element 1 of the type ctypes.int32_t.array(2)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-error.js b/js/src/jit-test/tests/ctypes/conversion-error.js new file mode 100644 index 000000000000..a6823fe5ce8c --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-error.js @@ -0,0 +1,14 @@ +load(libdir + 'asserts.js'); + +function test() { + let obj = { + toSource() { + throw 1; + } + }; + assertTypeErrorMessage(() => { ctypes.double().value = obj; }, + "can't convert <> to the type double"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-finalizer.js b/js/src/jit-test/tests/ctypes/conversion-finalizer.js new file mode 100644 index 000000000000..a04a40cfa203 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-finalizer.js @@ -0,0 +1,61 @@ +load(libdir + 'asserts.js'); + +function test() { + // non object + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, "foo"); }, + "expected _a CData object_ of a function pointer type, got the string \"foo\""); + // non CData object + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ["foo"]); }, + "expected a _CData_ object of a function pointer type, got the array [\"foo\"]"); + + // a CData which is not a pointer + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ctypes.int32_t(0)); }, + "expected a CData object of a function _pointer_ type, got ctypes.int32_t(0)"); + // a pointer CData which is not a function + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ctypes.int32_t.ptr(0)); }, + "expected a CData object of a _function_ pointer type, got ctypes.int32_t.ptr(ctypes.UInt64(\"0x0\"))"); + + // null function + let func_type = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t, ctypes.int32_t]).ptr; + let f0 = func_type(0); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f0); }, + "expected a CData object of a _non-NULL_ function pointer type, got ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t, ctypes.int32_t]).ptr(ctypes.UInt64(\"0x0\"))"); + + // a function with 2 arguments + let f1 = func_type(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f1); }, + "expected a function accepting exactly one argument, got ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t, ctypes.int32_t])"); + + // non CData in argument 1 + let func_type2 = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t.ptr]).ptr; + let f2 = func_type2(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f2); }, + "can't convert the number 0 to the type of argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t.ptr]).ptr"); + + // wrong struct in argument 1 + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let func_type3 = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [test_struct]).ptr; + let f3 = func_type3(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer({ "x": "foo" }, f3); }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct at argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [test_struct]).ptr"); + + // different size in argument 1 + let func_type4 = ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, + [ctypes.int32_t]).ptr; + let f4 = func_type4(x => x); + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(ctypes.int16_t(0), f4); }, + "expected an object with the same size as argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.int32_t]).ptr, got ctypes.int16_t(0)"); + + let fin = ctypes.CDataFinalizer(ctypes.int32_t(0), f4); + fin.dispose(); + assertTypeErrorMessage(() => { ctypes.int32_t(0).value = fin; }, + "attempting to convert an empty CDataFinalizer"); + assertTypeErrorMessage(() => { f4(fin); }, + /attempting to convert an empty CDataFinalizer at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[ctypes\.int32_t\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-function.js b/js/src/jit-test/tests/ctypes/conversion-function.js new file mode 100644 index 000000000000..cd90f1b60682 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-function.js @@ -0,0 +1,33 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + // Note: js shell cannot handle the exception in return value. + + // primitive + let func_type = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t]).ptr; + let f1 = func_type(function() {}); + assertTypeErrorMessage(() => { f1("foo"); }, + /can't pass the string "foo" to argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.voidptr_t, \[ctypes\.int32_t\]\)\.ptr\(ctypes\.UInt64\("[x0-9A-Fa-f]+"\)\)/); + + // struct + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let func_type2 = ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, + [test_struct]).ptr; + let f2 = func_type2(function() {}); + assertTypeErrorMessage(() => { f2({ "x": "foo" }); }, + /can't convert the string \"foo\" to the 'x' field \(int32_t\) of test_struct at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); + assertTypeErrorMessage(() => { f2({ "x": "foo", "y": "bar" }); }, + /property count of the object \(\{x:\"foo\", y:\"bar\"\}\) does not match to field count of the type test_struct \(expected 1, got 2\) at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); + assertTypeErrorMessage(() => { f2({ 0: "foo" }); }, + /property name the number 0 of the object \(\{0:\"foo\"\}\) is not a string at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); + + // error sentinel + assertTypeErrorMessage(() => { func_type(function() {}, null, "foo"); }, + "can't convert the string \"foo\" to the return type of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t])"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-int64.js b/js/src/jit-test/tests/ctypes/conversion-int64.js new file mode 100644 index 000000000000..f1751bdc0547 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-int64.js @@ -0,0 +1,20 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.Int64("0xfffffffffffffffffffffff"); }, + "can't pass the string \"0xfffffffffffffffffffffff\" to argument 1 of Int64"); + assertTypeErrorMessage(() => { ctypes.Int64.join("foo", 0); }, + "can't pass the string \"foo\" to argument 1 of Int64.join"); + assertTypeErrorMessage(() => { ctypes.Int64.join(0, "foo"); }, + "can't pass the string \"foo\" to argument 2 of Int64.join"); + + assertTypeErrorMessage(() => { ctypes.UInt64("0xfffffffffffffffffffffff"); }, + "can't pass the string \"0xfffffffffffffffffffffff\" to argument 1 of UInt64"); + assertTypeErrorMessage(() => { ctypes.UInt64.join("foo", 0); }, + "can't pass the string \"foo\" to argument 1 of UInt64.join"); + assertTypeErrorMessage(() => { ctypes.UInt64.join(0, "foo"); }, + "can't pass the string \"foo\" to argument 2 of UInt64.join"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-native-function.js b/js/src/jit-test/tests/ctypes/conversion-native-function.js new file mode 100644 index 000000000000..d2196813e90d --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-native-function.js @@ -0,0 +1,37 @@ +// Type conversion error for native function should report its name and type +// in C style. + +load(libdir + 'asserts.js'); + +function test() { + let lib; + try { + lib = ctypes.open(ctypes.libraryName("c")); + } catch (e) { + } + if (!lib) + return; + + let func = lib.declare("hypot", + ctypes.default_abi, + ctypes.double, + ctypes.double, ctypes.double); + assertTypeErrorMessage(() => { func(1, "xyzzy"); }, + "can't pass the string \"xyzzy\" to argument 2 of double hypot(double, double)"); + + // test C style source for various types + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let test_func = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, + [ctypes.int32_t]).ptr; + func = lib.declare("hypot", + ctypes.default_abi, + ctypes.double, + ctypes.double, ctypes.int32_t.ptr.ptr.ptr.array(), + test_struct, test_struct.ptr.ptr, + test_func, test_func.ptr.ptr.ptr, "..."); + assertTypeErrorMessage(() => { func("xyzzy", 1, 2, 3, 4, 5); }, + "can't pass the string \"xyzzy\" to argument 1 of double hypot(double, int32_t****, struct test_struct, struct test_struct**, void* (*)(int32_t), void* (****)(int32_t), ...)"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-pointer.js b/js/src/jit-test/tests/ctypes/conversion-pointer.js new file mode 100644 index 000000000000..cfdcc8ed87af --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-pointer.js @@ -0,0 +1,29 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let struct_val = test_struct(); + + // constructor + assertTypeErrorMessage(() => { ctypes.int32_t.ptr("foo"); }, + "can't convert the string \"foo\" to the type ctypes.int32_t.ptr"); + + // value setter + assertTypeErrorMessage(() => { test_struct.ptr().value = "foo"; }, + "can't convert the string \"foo\" to the type test_struct.ptr"); + assertTypeErrorMessage(() => { test_struct.ptr().value = {}; }, + "can't convert the object ({}) to the type test_struct.ptr"); + assertTypeErrorMessage(() => { test_struct.ptr().value = [1, 2]; }, + "can't convert the array [1, 2] to the type test_struct.ptr"); + assertTypeErrorMessage(() => { test_struct.ptr().value = Int8Array([1, 2]); }, + "can't convert the typed array ({0:1, 1:2}) to the type test_struct.ptr"); + + // contents setter + assertTypeErrorMessage(() => { ctypes.int32_t().address().contents = {}; }, + "can't convert the object ({}) to the type int32_t"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-primitive.js b/js/src/jit-test/tests/ctypes/conversion-primitive.js new file mode 100644 index 000000000000..aaaa95e6b8bd --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-primitive.js @@ -0,0 +1,44 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + // constructor + assertTypeErrorMessage(() => { ctypes.int32_t("foo"); }, + "can't convert the string \"foo\" to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(null); }, + "can't convert null to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(undefined); }, + "can't convert undefined to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t({}); }, + "can't convert the object ({}) to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t([]); }, + "can't convert the array [] to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(new Int8Array([])); }, + "can't convert the typed array ({}) to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(ctypes.int32_t); }, + "can't convert ctypes.int32_t to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t("0xfffffffffffffffffffffff"); }, + "can't convert the string \"0xfffffffffffffffffffffff\" to the type int32_t"); + if (typeof Symbol === "function") { + assertTypeErrorMessage(() => { ctypes.int32_t(Symbol.iterator); }, + "can't convert Symbol.iterator to the type int32_t"); + assertTypeErrorMessage(() => { ctypes.int32_t(Symbol("foo")); }, + "can't convert Symbol(\"foo\") to the type int32_t"); + } + + // value setter + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); + let struct_val = test_struct(); + assertTypeErrorMessage(() => { ctypes.bool().value = struct_val; }, + "can't convert test_struct(0) to the type boolean"); + assertTypeErrorMessage(() => { ctypes.char16_t().value = struct_val; }, + "can't convert test_struct(0) to the type char16_t"); + assertTypeErrorMessage(() => { ctypes.int8_t().value = struct_val; }, + "can't convert test_struct(0) to the type int8_t"); + assertTypeErrorMessage(() => { ctypes.double().value = struct_val; }, + "can't convert test_struct(0) to the type double"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-struct.js b/js/src/jit-test/tests/ctypes/conversion-struct.js new file mode 100644 index 000000000000..f5e43ffa563b --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-struct.js @@ -0,0 +1,36 @@ +// Type conversion error should report its type. + +load(libdir + 'asserts.js'); + +function test() { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }, + { "bar": ctypes.int32_t }]); + + // constructor + assertTypeErrorMessage(() => { new test_struct("foo"); }, + "can't convert the string \"foo\" to the type test_struct"); + assertTypeErrorMessage(() => { new test_struct("foo", "x"); }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { new test_struct({ "x": "foo", "bar": 1 }); }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { new test_struct({ 0: 1, "bar": 1 }); }, + "property name the number 0 of the object ({0:1, bar:1}) is not a string"); + + // field setter + let struct_val = test_struct(); + assertTypeErrorMessage(() => { struct_val.x = "foo"; }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { struct_val.bar = "foo"; }, + "can't convert the string \"foo\" to the 'bar' field (int32_t) of test_struct"); + + // value setter + assertTypeErrorMessage(() => { struct_val.value = { "x": "foo" }; }, + "property count of the object ({x:\"foo\"}) does not match to field count of the type test_struct (expected 2, got 1)"); + assertTypeErrorMessage(() => { struct_val.value = { "x": "foo", "bar": 1 }; }, + "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); + assertTypeErrorMessage(() => { struct_val.value = "foo"; }, + "can't convert the string \"foo\" to the type test_struct"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-to-primitive.js b/js/src/jit-test/tests/ctypes/conversion-to-primitive.js new file mode 100644 index 000000000000..cdb9a4a051d5 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/conversion-to-primitive.js @@ -0,0 +1,20 @@ +// Accessing `value` property of non primitive type should report its type. + +load(libdir + 'asserts.js'); + +function test() { + let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.voidptr_t }]); + assertTypeErrorMessage(() => test_struct().value, + ".value only works on character and numeric types, not `test_struct`"); + + let test_array = ctypes.ArrayType(test_struct); + assertTypeErrorMessage(() => test_array(10).value, + ".value only works on character and numeric types, not `test_struct.array(10)`"); + + let test_pointer = ctypes.PointerType(test_struct); + assertTypeErrorMessage(() => test_pointer(10).value, + ".value only works on character and numeric types, not `test_struct.ptr`"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index a1fdab346a00..703ff7de5f34 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -930,3 +930,43 @@ JS::CreateError(JSContext* cx, JSExnType type, HandleObject stack, HandleString rval.setObject(*obj); return true; } + +const char* +js::ValueToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes) +{ + if (val.isUndefined()) { + return "undefined"; + } + if (val.isNull()) { + return "null"; + } + + RootedString str(cx, JS_ValueToSource(cx, val)); + if (!str) { + JS_ClearPendingException(cx); + return "<>"; + } + + StringBuffer sb(cx); + if (val.isObject()) { + RootedObject valObj(cx, val.toObjectOrNull()); + if (JS_IsArrayObject(cx, valObj)) { + sb.append("the array "); + } else if (JS_IsArrayBufferObject(valObj)) { + sb.append("the array buffer "); + } else if (JS_IsArrayBufferViewObject(valObj)) { + sb.append("the typed array "); + } else { + sb.append("the object "); + } + } else if (val.isNumber()) { + sb.append("the number "); + } else if (val.isString()) { + sb.append("the string "); + } else { + MOZ_ASSERT(val.isBoolean() || val.isSymbol()); + return bytes.encodeLatin1(cx, str); + } + sb.append(str); + return bytes.encodeLatin1(cx, sb.finishString()); +} diff --git a/js/src/jsexn.h b/js/src/jsexn.h index 1cdcac947e5d..3bcf29abd38a 100644 --- a/js/src/jsexn.h +++ b/js/src/jsexn.h @@ -129,6 +129,9 @@ class AutoClearPendingException } }; +extern const char* +ValueToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes); + } // namespace js #endif /* jsexn_h */ diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index 911e8e4b251b..5ddeab5297d5 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -1166,7 +1166,7 @@ function run_char_tests(library, t, name, size, signed, limits) { do_check_eq(s.constructor.length, literal.length + 1); s = t.array(50)(literal); do_check_eq(s.readString(), literal); - do_check_throws(function() { t.array(3)(literal); }, Error); + do_check_throws(function() { t.array(3)(literal); }, TypeError); do_check_throws(function() { t.ptr(literal); }, TypeError); let p = t.ptr(s); @@ -1258,7 +1258,7 @@ function run_char16_tests(library, t, name, limits) { do_check_eq(s.constructor.length, literal.length + 1); s = t.array(50)(literal); do_check_eq(s.readString(), literal); - do_check_throws(function() { t.array(3)(literal); }, Error); + do_check_throws(function() { t.array(3)(literal); }, TypeError); do_check_throws(function() { t.ptr(literal); }, TypeError); let p = t.ptr(s); @@ -1587,25 +1587,25 @@ function run_StructType_tests() { do_check_eq(s.b.b, s2.b.b); // Test that structs can be set from an object using 'value'. - do_check_throws(function() { s.value; }, Error); + do_check_throws(function() { s.value; }, TypeError); let s_init = { "a": 2, "b": { "a": 9, "b": 5 }, "c": 13 }; s.value = s_init; do_check_eq(s.b.a, 9); do_check_eq(s.c, 13); do_check_throws(function() { s.value = 5; }, TypeError); do_check_throws(function() { s.value = ctypes.int32_t(); }, TypeError); - do_check_throws(function() { s.value = {}; }, Error); - do_check_throws(function() { s.value = { "a": 2 }; }, Error); + do_check_throws(function() { s.value = {}; }, TypeError); + do_check_throws(function() { s.value = { "a": 2 }; }, TypeError); do_check_throws(function() { s.value = { "a": 2, "b": 5, "c": 10 }; }, TypeError); do_check_throws(function() { s.value = { "5": 2, "b": { "a": 9, "b": 5 }, "c": 13 }; - }, Error); + }, TypeError); do_check_throws(function() { s.value = { "a": 2, "b": { "a": 9, "b": 5 }, "c": 13, "d": 17 }; - }, Error); + }, TypeError); do_check_throws(function() { s.value = { "a": 2, "b": { "a": 9, "b": 5, "e": 9 }, "c": 13 }; - }, Error); + }, TypeError); // Test that structs can be constructed similarly through ExplicitConvert, // and that the single-field case is disambiguated correctly. @@ -1682,7 +1682,7 @@ function run_PointerType_tests() { // Test ExplicitConvert. let p = p_t(); - do_check_throws(function() { p.value; }, Error); + do_check_throws(function() { p.value; }, TypeError); do_check_eq(ptrValue(p), 0); do_check_throws(function() { p.contents; }, Error); do_check_throws(function() { p.contents = g; }, Error); @@ -1798,10 +1798,10 @@ function run_PointerType_tests() { let array_type_too_large = item_type.array(number_of_items + 1); let array_type_too_small = item_type.array(number_of_items - 1); - do_check_throws(function() { array_type_too_large(c_arraybuffer); }, Error); - do_check_throws(function() { array_type_too_small(c_arraybuffer); }, Error); - do_check_throws(function() { array_type_too_large(view); }, Error); - do_check_throws(function() { array_type_too_small(view); }, Error); + do_check_throws(function() { array_type_too_large(c_arraybuffer); }, TypeError); + do_check_throws(function() { array_type_too_small(c_arraybuffer); }, TypeError); + do_check_throws(function() { array_type_too_large(view); }, TypeError); + do_check_throws(function() { array_type_too_small(view); }, TypeError); // Convert subarray of typed array to array of right size and check contents c_array = array_type_too_small(view.subarray(1)); @@ -1884,7 +1884,7 @@ function run_FunctionType_tests() { // Test ExplicitConvert. let f = fp_t(); - do_check_throws(function() { f.value; }, Error); + do_check_throws(function() { f.value; }, TypeError); do_check_eq(ptrValue(f), 0); f = fp_t(5); do_check_eq(ptrValue(f), 5); @@ -2067,11 +2067,11 @@ function run_ArrayType_tests() { c.value = c; do_check_eq(c[3], 4); - do_check_throws(function() { c.value; }, Error); - do_check_throws(function() { c.value = [1, 2, 3, 4, 5]; }, Error); - do_check_throws(function() { c.value = [1, 2, 3, 4, 5, 6, 7]; }, Error); + do_check_throws(function() { c.value; }, TypeError); + do_check_throws(function() { c.value = [1, 2, 3, 4, 5]; }, TypeError); + do_check_throws(function() { c.value = [1, 2, 3, 4, 5, 6, 7]; }, TypeError); do_check_throws(function() { c.value = [1, 2, 7.4, 4, 5, 6]; }, TypeError); - do_check_throws(function() { c.value = []; }, Error); + do_check_throws(function() { c.value = []; }, TypeError); } function run_type_toString_tests() { From eac8d1b1f46d91661ff4ad1eee5e022fa0c22fc2 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 18:26:14 +0900 Subject: [PATCH 099/241] Bug 891107 - Part 2: Report argument length error as TypeError in js-ctypes. r=jorendorff --- js/src/ctypes/CTypes.cpp | 159 ++++++++++-------- js/src/ctypes/ctypes.msg | 3 + .../tests/ctypes/argument-length-abi.js | 9 + .../tests/ctypes/argument-length-array.js | 15 ++ .../tests/ctypes/argument-length-cdata.js | 15 ++ .../tests/ctypes/argument-length-ctypes.js | 11 ++ .../tests/ctypes/argument-length-finalizer.js | 16 ++ .../tests/ctypes/argument-length-function.js | 11 ++ .../tests/ctypes/argument-length-int64.js | 36 ++++ .../tests/ctypes/argument-length-pointer.js | 11 ++ .../tests/ctypes/argument-length-primitive.js | 11 ++ .../tests/ctypes/argument-length-struct.js | 17 ++ .../ctypes/tests/unit/test_jsctypes.js | 40 ++--- 13 files changed, 263 insertions(+), 91 deletions(-) create mode 100644 js/src/jit-test/tests/ctypes/argument-length-abi.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-array.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-cdata.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-ctypes.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-finalizer.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-function.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-int64.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-pointer.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-primitive.js create mode 100644 js/src/jit-test/tests/ctypes/argument-length-struct.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 26099d919163..86ed225c308f 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -1234,6 +1234,15 @@ ArgumentConvError(JSContext* cx, HandleValue actual, const char* funStr, return false; } +static bool +ArgumentLengthError(JSContext* cx, const char* fun, const char* count, + const char* s) +{ + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_WRONG_ARG_LENGTH, fun, count, s); + return false; +} + static bool ArrayLengthMismatch(JSContext* cx, unsigned expectedLength, HandleObject arrObj, unsigned actualLength, HandleValue actual, @@ -3834,8 +3843,7 @@ CType::ConstructBasic(JSContext* cx, const CallArgs& args) { if (args.length() > 1) { - JS_ReportError(cx, "CType constructor takes zero or one argument"); - return false; + return ArgumentLengthError(cx, "CType constructor", "at most one", ""); } // construct a CData object @@ -4357,8 +4365,7 @@ CType::CreateArray(JSContext* cx, unsigned argc, jsval* vp) // Construct and return a new ArrayType object. if (args.length() > 1) { - JS_ReportError(cx, "array takes zero or one argument"); - return false; + return ArgumentLengthError(cx, "CType.prototype.array", "at most one", ""); } // Convert the length argument to a size_t. @@ -4497,8 +4504,7 @@ ABI::ToSource(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - JS_ReportError(cx, "toSource takes zero arguments"); - return false; + return ArgumentLengthError(cx, "ABI.prototype.toSource", "no", "s"); } JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -4542,8 +4548,7 @@ PointerType::Create(JSContext* cx, unsigned argc, jsval* vp) CallArgs args = CallArgsFromVp(argc, vp); // Construct and return a new PointerType object. if (args.length() != 1) { - JS_ReportError(cx, "PointerType takes one argument"); - return false; + return ArgumentLengthError(cx, "PointerType", "one", ""); } jsval arg = args[0]; @@ -4608,8 +4613,8 @@ PointerType::ConstructData(JSContext* cx, } if (args.length() > 3) { - JS_ReportError(cx, "constructor takes 0, 1, 2, or 3 arguments"); - return false; + return ArgumentLengthError(cx, "PointerType constructor", "0, 1, 2, or 3", + "s"); } RootedObject result(cx, CData::Create(cx, obj, NullPtr(), nullptr, true)); @@ -4643,8 +4648,7 @@ PointerType::ConstructData(JSContext* cx, // if (!looksLikeClosure) { if (args.length() != 1) { - JS_ReportError(cx, "first argument must be a function"); - return false; + return ArgumentLengthError(cx, "FunctionType constructor", "one", ""); } return ExplicitConvert(cx, args[0], obj, CData::GetData(result), ConversionType::Construct); @@ -4845,8 +4849,7 @@ ArrayType::Create(JSContext* cx, unsigned argc, jsval* vp) CallArgs args = CallArgsFromVp(argc, vp); // Construct and return a new ArrayType object. if (args.length() < 1 || args.length() > 2) { - JS_ReportError(cx, "ArrayType takes one or two arguments"); - return false; + return ArgumentLengthError(cx, "ArrayType", "one or two", "s"); } if (args[0].isPrimitive() || @@ -4946,14 +4949,14 @@ ArrayType::ConstructData(JSContext* cx, // with a length argument, or with an actual JS array. if (CType::IsSizeDefined(obj)) { if (args.length() > 1) { - JS_ReportError(cx, "constructor takes zero or one argument"); - return false; + return ArgumentLengthError(cx, "size defined ArrayType constructor", + "at most one", ""); } } else { if (args.length() != 1) { - JS_ReportError(cx, "constructor takes one argument"); - return false; + return ArgumentLengthError(cx, "size undefined ArrayType constructor", + "one", ""); } RootedObject baseType(cx, GetBaseType(obj)); @@ -5268,8 +5271,8 @@ ArrayType::AddressOfElement(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 1) { - JS_ReportError(cx, "addressOfElement takes one argument"); - return false; + return ArgumentLengthError(cx, "ArrayType.prototype.addressOfElement", + "one", ""); } RootedObject baseType(cx, GetBaseType(typeObj)); @@ -5389,8 +5392,7 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp) // Construct and return a new StructType object. if (args.length() < 1 || args.length() > 2) { - JS_ReportError(cx, "StructType takes one or two arguments"); - return false; + return ArgumentLengthError(cx, "StructType", "one or two", "s"); } jsval name = args[0]; @@ -5684,8 +5686,7 @@ StructType::Define(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 1) { - JS_ReportError(cx, "define takes one argument"); - return false; + return ArgumentLengthError(cx, "StructType.prototype.define", "one", ""); } jsval arg = args[0]; @@ -5772,9 +5773,14 @@ StructType::ConstructData(JSContext* cx, return true; } - JS_ReportError(cx, "constructor takes 0, 1, or %u arguments", - fields->count()); - return false; + size_t count = fields->count(); + if (count >= 2) { + char fieldLengthStr[32]; + JS_snprintf(fieldLengthStr, 32, "0, 1, or %u", count); + return ArgumentLengthError(cx, "StructType constructor", fieldLengthStr, + "s"); + } + return ArgumentLengthError(cx, "StructType constructor", "at most one", ""); } const FieldInfoHash* @@ -5970,8 +5976,8 @@ StructType::AddressOfField(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 1) { - JS_ReportError(cx, "addressOfField takes one argument"); - return false; + return ArgumentLengthError(cx, "StructType.prototype.addressOfField", + "one", ""); } if (!args[0].isString()) { @@ -6315,8 +6321,7 @@ FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp) // Construct and return a new FunctionType object. CallArgs args = CallArgsFromVp(argc, vp); if (args.length() < 2 || args.length() > 3) { - JS_ReportError(cx, "FunctionType takes two or three arguments"); - return false; + return ArgumentLengthError(cx, "FunctionType", "two or three", "s"); } AutoValueVector argTypes(cx); @@ -7161,8 +7166,7 @@ CData::Address(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - JS_ReportError(cx, "address takes zero arguments"); - return false; + return ArgumentLengthError(cx, "CData.prototype.address", "no", "s"); } RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -7196,8 +7200,7 @@ CData::Cast(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { - JS_ReportError(cx, "cast takes two arguments"); - return false; + return ArgumentLengthError(cx, "ctypes.cast", "two", "s"); } if (args[0].isPrimitive() || !CData::IsCData(&args[0].toObject())) { @@ -7237,8 +7240,7 @@ CData::GetRuntime(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { - JS_ReportError(cx, "getRuntime takes one argument"); - return false; + return ArgumentLengthError(cx, "ctypes.getRuntime", "one", ""); } if (args[0].isPrimitive() || !CType::IsCType(&args[0].toObject())) { @@ -7270,8 +7272,11 @@ ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8, unsigned argc, js { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - JS_ReportError(cx, "readString takes zero arguments"); - return false; + if (inflateUTF8 == JS::UTF8CharsToNewTwoByteCharsZ) { + return ArgumentLengthError(cx, "CData.prototype.readString", "no", "s"); + } + return ArgumentLengthError(cx, "CData.prototype.readStringReplaceMalformed", + "no", "s"); } JSObject* obj = CDataFinalizer::GetCData(cx, JS_THIS_OBJECT(cx, vp)); @@ -7386,8 +7391,7 @@ CData::ToSource(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - JS_ReportError(cx, "toSource takes zero arguments"); - return false; + return ArgumentLengthError(cx, "CData.prototype.toSource", "no", "s"); } JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -7615,8 +7619,7 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 2) { - JS_ReportError(cx, "CDataFinalizer takes 2 arguments"); - return false; + return ArgumentLengthError(cx, "CDataFinalizer constructor", "two", "s"); } JS::HandleValue valCodePtr = args[1]; @@ -7830,8 +7833,8 @@ CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - JS_ReportError(cx, "CDataFinalizer.prototype.forget takes no arguments"); - return false; + return ArgumentLengthError(cx, "CDataFinalizer.prototype.forget", "no", + "s"); } JS::Rooted obj(cx, args.thisv().toObjectOrNull()); @@ -7878,8 +7881,8 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - JS_ReportError(cx, "CDataFinalizer.prototype.dispose takes no arguments"); - return false; + return ArgumentLengthError(cx, "CDataFinalizer.prototype.dispose", "no", + "s"); } RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -8052,8 +8055,12 @@ Int64Base::ToString(JSContext* cx, bool isUnsigned) { if (args.length() > 1) { - JS_ReportError(cx, "toString takes zero or one argument"); - return false; + if (isUnsigned) { + return ArgumentLengthError(cx, "UInt64.prototype.toString", + "at most one", ""); + } + return ArgumentLengthError(cx, "Int64.prototype.toString", + "at most one", ""); } int radix = 10; @@ -8089,8 +8096,10 @@ Int64Base::ToSource(JSContext* cx, bool isUnsigned) { if (args.length() != 0) { - JS_ReportError(cx, "toSource takes zero arguments"); - return false; + if (isUnsigned) { + return ArgumentLengthError(cx, "UInt64.prototype.toSource", "no", "s"); + } + return ArgumentLengthError(cx, "Int64.prototype.toSource", "no", "s"); } // Return a decimal string suitable for constructing the number. @@ -8121,8 +8130,7 @@ Int64::Construct(JSContext* cx, // Construct and return a new Int64 object. if (args.length() != 1) { - JS_ReportError(cx, "Int64 takes one argument"); - return false; + return ArgumentLengthError(cx, "Int64 constructor", "one", ""); } int64_t i = 0; @@ -8185,8 +8193,10 @@ bool Int64::Compare(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 2 || - args[0].isPrimitive() || + if (args.length() != 2) { + return ArgumentLengthError(cx, "Int64.compare", "two", "s"); + } + if (args[0].isPrimitive() || args[1].isPrimitive() || !Int64::IsInt64(&args[0].toObject()) || !Int64::IsInt64(&args[1].toObject())) { @@ -8218,8 +8228,10 @@ bool Int64::Lo(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1 || args[0].isPrimitive() || - !Int64::IsInt64(&args[0].toObject())) { + if (args.length() != 1) { + return ArgumentLengthError(cx, "Int64.lo", "one", ""); + } + if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { JS_ReportError(cx, "lo takes one Int64 argument"); return false; } @@ -8236,8 +8248,10 @@ bool Int64::Hi(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1 || args[0].isPrimitive() || - !Int64::IsInt64(&args[0].toObject())) { + if (args.length() != 1) { + return ArgumentLengthError(cx, "Int64.hi", "one", ""); + } + if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { JS_ReportError(cx, "hi takes one Int64 argument"); return false; } @@ -8255,8 +8269,7 @@ Int64::Join(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { - JS_ReportError(cx, "join takes two arguments"); - return false; + return ArgumentLengthError(cx, "Int64.join", "two", "s"); } int32_t hi; @@ -8292,8 +8305,7 @@ UInt64::Construct(JSContext* cx, // Construct and return a new UInt64 object. if (args.length() != 1) { - JS_ReportError(cx, "UInt64 takes one argument"); - return false; + return ArgumentLengthError(cx, "UInt64 constructor", "one", ""); } uint64_t u = 0; @@ -8356,8 +8368,10 @@ bool UInt64::Compare(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 2 || - args[0].isPrimitive() || + if (args.length() != 2) { + return ArgumentLengthError(cx, "UInt64.compare", "two", "s"); + } + if (args[0].isPrimitive() || args[1].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject()) || !UInt64::IsUInt64(&args[1].toObject())) { @@ -8385,8 +8399,10 @@ bool UInt64::Lo(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1 || args[0].isPrimitive() || - !UInt64::IsUInt64(&args[0].toObject())) { + if (args.length() != 1) { + return ArgumentLengthError(cx, "UInt64.lo", "one", ""); + } + if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { JS_ReportError(cx, "lo takes one UInt64 argument"); return false; } @@ -8403,8 +8419,10 @@ bool UInt64::Hi(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1 || args[0].isPrimitive() || - !UInt64::IsUInt64(&args[0].toObject())) { + if (args.length() != 1) { + return ArgumentLengthError(cx, "UInt64.hi", "one", ""); + } + if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { JS_ReportError(cx, "hi takes one UInt64 argument"); return false; } @@ -8422,8 +8440,7 @@ UInt64::Join(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { - JS_ReportError(cx, "join takes two arguments"); - return false; + return ArgumentLengthError(cx, "UInt64.join", "two", "s"); } uint32_t hi; diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg index aa1a709fe0f1..84a3884c649a 100644 --- a/js/src/ctypes/ctypes.msg +++ b/js/src/ctypes/ctypes.msg @@ -32,3 +32,6 @@ MSG_DEF(CTYPESMSG_PROP_NONSTRING,3, JSEXN_TYPEERR, "property name {0} of {1} is /* data finalizer */ MSG_DEF(CTYPESMSG_EMPTY_FIN, 1, JSEXN_TYPEERR, "attempting to convert an empty CDataFinalizer{0}") MSG_DEF(CTYPESMSG_FIN_SIZE_ERROR,2, JSEXN_TYPEERR, "expected an object with the same size as argument 1 of {0}, got {1}") + +/* native function */ +MSG_DEF(CTYPESMSG_WRONG_ARG_LENGTH,3, JSEXN_TYPEERR, "{0} takes {1} argument{2}") diff --git a/js/src/jit-test/tests/ctypes/argument-length-abi.js b/js/src/jit-test/tests/ctypes/argument-length-abi.js new file mode 100644 index 000000000000..a18a8059ed65 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-abi.js @@ -0,0 +1,9 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.default_abi.toSource(1); }, + "ABI.prototype.toSource takes no arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-array.js b/js/src/jit-test/tests/ctypes/argument-length-array.js new file mode 100644 index 000000000000..5afbcc46ebc2 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-array.js @@ -0,0 +1,15 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.ArrayType(); }, + "ArrayType takes one or two arguments"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)(1, 2); }, + "size defined ArrayType constructor takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.array()(1, 2); }, + "size undefined ArrayType constructor takes one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(10)().addressOfElement(); }, + "ArrayType.prototype.addressOfElement takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-cdata.js b/js/src/jit-test/tests/ctypes/argument-length-cdata.js new file mode 100644 index 000000000000..56a1497f4815 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-cdata.js @@ -0,0 +1,15 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t(0).address(1); }, + "CData.prototype.address takes no arguments"); + assertTypeErrorMessage(() => { ctypes.char.array(10)().readString(1); }, + "CData.prototype.readString takes no arguments"); + assertTypeErrorMessage(() => { ctypes.char.array(10)().readStringReplaceMalformed(1); }, + "CData.prototype.readStringReplaceMalformed takes no arguments"); + assertTypeErrorMessage(() => { ctypes.int32_t(0).toSource(1); }, + "CData.prototype.toSource takes no arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-ctypes.js b/js/src/jit-test/tests/ctypes/argument-length-ctypes.js new file mode 100644 index 000000000000..84b0b9ea54df --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-ctypes.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.cast(); }, + "ctypes.cast takes two arguments"); + assertTypeErrorMessage(() => { ctypes.getRuntime(); }, + "ctypes.getRuntime takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-finalizer.js b/js/src/jit-test/tests/ctypes/argument-length-finalizer.js new file mode 100644 index 000000000000..70e15bf8f089 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-finalizer.js @@ -0,0 +1,16 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.CDataFinalizer(1); }, + "CDataFinalizer constructor takes two arguments"); + + let fin = ctypes.CDataFinalizer(ctypes.int32_t(0), ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.int32_t]).ptr(x => x)); + assertTypeErrorMessage(() => { fin.forget(1); }, + "CDataFinalizer.prototype.forget takes no arguments"); + assertTypeErrorMessage(() => { fin.dispose(1); }, + "CDataFinalizer.prototype.dispose takes no arguments"); + fin.forget(); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-function.js b/js/src/jit-test/tests/ctypes/argument-length-function.js new file mode 100644 index 000000000000..2d26596620b2 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-function.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.FunctionType(); }, + "FunctionType takes two or three arguments"); + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, []).ptr({}, 1); }, + "FunctionType constructor takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-int64.js b/js/src/jit-test/tests/ctypes/argument-length-int64.js new file mode 100644 index 000000000000..888713accf6a --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-int64.js @@ -0,0 +1,36 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.Int64(1).toString(1, 2); }, + "Int64.prototype.toString takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.Int64(1).toSource(1); }, + "Int64.prototype.toSource takes no arguments"); + assertTypeErrorMessage(() => { ctypes.Int64(); }, + "Int64 constructor takes one argument"); + assertTypeErrorMessage(() => { ctypes.Int64.compare(); }, + "Int64.compare takes two arguments"); + assertTypeErrorMessage(() => { ctypes.Int64.lo(); }, + "Int64.lo takes one argument"); + assertTypeErrorMessage(() => { ctypes.Int64.hi(); }, + "Int64.hi takes one argument"); + assertTypeErrorMessage(() => { ctypes.Int64.join(); }, + "Int64.join takes two arguments"); + + assertTypeErrorMessage(() => { ctypes.UInt64(1).toString(1, 2); }, + "UInt64.prototype.toString takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64(1).toSource(1); }, + "UInt64.prototype.toSource takes no arguments"); + assertTypeErrorMessage(() => { ctypes.UInt64(); }, + "UInt64 constructor takes one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64.compare(); }, + "UInt64.compare takes two arguments"); + assertTypeErrorMessage(() => { ctypes.UInt64.lo(); }, + "UInt64.lo takes one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64.hi(); }, + "UInt64.hi takes one argument"); + assertTypeErrorMessage(() => { ctypes.UInt64.join(); }, + "UInt64.join takes two arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-pointer.js b/js/src/jit-test/tests/ctypes/argument-length-pointer.js new file mode 100644 index 000000000000..8ac404aaf751 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-pointer.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.PointerType(); }, + "PointerType takes one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.ptr(1, 2, 3, 4); }, + "PointerType constructor takes 0, 1, 2, or 3 arguments"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-primitive.js b/js/src/jit-test/tests/ctypes/argument-length-primitive.js new file mode 100644 index 000000000000..161ebd880c5f --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-primitive.js @@ -0,0 +1,11 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t(1, 2, 3); }, + "CType constructor takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.int32_t.array(1, 2); }, + "CType.prototype.array takes at most one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-struct.js b/js/src/jit-test/tests/ctypes/argument-length-struct.js new file mode 100644 index 000000000000..0e8efbb6ab4c --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-length-struct.js @@ -0,0 +1,17 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.StructType(); }, + "StructType takes one or two arguments"); + assertTypeErrorMessage(() => { ctypes.StructType("a").define(); }, + "StructType.prototype.define takes one argument"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [])(1, 2, 3); }, + "StructType constructor takes at most one argument"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ {"x": ctypes.int32_t }, {"y": ctypes.int32_t }, {"z": ctypes.int32_t }])(1, 2); }, + "StructType constructor takes 0, 1, or 3 arguments"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [ {"x": ctypes.int32_t } ])().addressOfField(); }, + "StructType.prototype.addressOfField takes one argument"); +} + +if (typeof ctypes === "object") + test(); diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index 5ddeab5297d5..d0323def0ac0 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -300,7 +300,7 @@ function run_abstract_class_tests() } function run_Int64_tests() { - do_check_throws(function() { ctypes.Int64(); }, Error); + do_check_throws(function() { ctypes.Int64(); }, TypeError); // Test that classes and prototypes are set up correctly. do_check_class(ctypes.Int64, "Function"); @@ -334,11 +334,11 @@ function run_Int64_tests() { do_check_throws(function() { i.toString(0); }, Error); do_check_throws(function() { i.toString(1); }, Error); do_check_throws(function() { i.toString(37); }, Error); - do_check_throws(function() { i.toString(10, 2); }, Error); + do_check_throws(function() { i.toString(10, 2); }, TypeError); // Test Int64.toSource(). do_check_eq(i.toSource(), "ctypes.Int64(\"0\")"); - do_check_throws(function() { i.toSource(10); }, Error); + do_check_throws(function() { i.toSource(10); }, TypeError); i = ctypes.Int64("0x28590a1c921def71"); do_check_eq(i.toString(), i.toString(10)); @@ -471,7 +471,7 @@ function run_Int64_tests() { } function run_UInt64_tests() { - do_check_throws(function() { ctypes.UInt64(); }, Error); + do_check_throws(function() { ctypes.UInt64(); }, TypeError); // Test that classes and prototypes are set up correctly. do_check_class(ctypes.UInt64, "Function"); @@ -505,11 +505,11 @@ function run_UInt64_tests() { do_check_throws(function() { i.toString(0); }, Error); do_check_throws(function() { i.toString(1); }, Error); do_check_throws(function() { i.toString(37); }, Error); - do_check_throws(function() { i.toString(10, 2); }, Error); + do_check_throws(function() { i.toString(10, 2); }, TypeError); // Test UInt64.toSource(). do_check_eq(i.toSource(), "ctypes.UInt64(\"0\")"); - do_check_throws(function() { i.toSource(10); }, Error); + do_check_throws(function() { i.toSource(10); }, TypeError); i = ctypes.UInt64("0x28590a1c921def71"); do_check_eq(i.toString(), i.toString(10)); @@ -1372,8 +1372,8 @@ function run_StructType_tests() { ctypes.StructType("t", [{"c": ctypes.int32_t}, {"d": ctypes.int64_t}]), [ "fields" ], [ "define" ], [], [ "addressOfField" ], [ "a", "b" ]); - do_check_throws(function() { ctypes.StructType(); }, Error); - do_check_throws(function() { ctypes.StructType("a", [], 5); }, Error); + do_check_throws(function() { ctypes.StructType(); }, TypeError); + do_check_throws(function() { ctypes.StructType("a", [], 5); }, TypeError); do_check_throws(function() { ctypes.StructType(null, []); }, Error); do_check_throws(function() { ctypes.StructType("a", null); }, Error); @@ -1424,8 +1424,8 @@ function run_StructType_tests() { }, TypeError); // Check that 'define' works. - do_check_throws(function() { opaque_t.define(); }, Error); - do_check_throws(function() { opaque_t.define([], 0); }, Error); + do_check_throws(function() { opaque_t.define(); }, TypeError); + do_check_throws(function() { opaque_t.define([], 0); }, TypeError); do_check_throws(function() { opaque_t.define([{}]); }, Error); do_check_throws(function() { opaque_t.define([{ a: 0 }]); }, Error); do_check_throws(function() { @@ -1551,7 +1551,7 @@ function run_StructType_tests() { do_check_eq(g.a, 1); do_check_eq(g.b, 2); do_check_throws(function() { g_t(1); }, TypeError); - do_check_throws(function() { g_t(1, 2, 3); }, Error); + do_check_throws(function() { g_t(1, 2, 3); }, TypeError); for (let field in g) do_check_true(field == "a" || field == "b"); @@ -1576,9 +1576,9 @@ function run_StructType_tests() { g_a = s.addressOfField("b"); do_check_true(g_a.constructor === g_t.ptr); do_check_eq(g_a.contents.a, s.b.a); - do_check_throws(function() { s.addressOfField(); }, Error); + do_check_throws(function() { s.addressOfField(); }, TypeError); do_check_throws(function() { s.addressOfField("d"); }, Error); - do_check_throws(function() { s.addressOfField("a", 2); }, Error); + do_check_throws(function() { s.addressOfField("a", 2); }, TypeError); do_check_eq(s.toSource(), "s_t(4, {\"a\": 7, \"b\": 2}, 10)"); do_check_eq(s.toSource(), s.toString()); @@ -1657,8 +1657,8 @@ function run_PointerType_tests() { ctypes.PointerType(ctypes.int32_t), ctypes.PointerType(ctypes.int64_t), [ "targetType" ], [], [ "contents" ], [ "isNull", "increment", "decrement" ], []); - do_check_throws(function() { ctypes.PointerType(); }, Error); - do_check_throws(function() { ctypes.PointerType(ctypes.int32_t, 5); }, Error); + do_check_throws(function() { ctypes.PointerType(); }, TypeError); + do_check_throws(function() { ctypes.PointerType(ctypes.int32_t, 5); }, TypeError); do_check_throws(function() { ctypes.PointerType(null); }, Error); do_check_throws(function() { ctypes.PointerType(ctypes.int32_t()); }, Error); do_check_throws(function() { ctypes.PointerType("void"); }, Error); @@ -1835,13 +1835,13 @@ function run_FunctionType_tests() { [ "abi", "returnType", "argTypes", "isVariadic" ], undefined, undefined, undefined, undefined); - do_check_throws(function() { ctypes.FunctionType(); }, Error); + do_check_throws(function() { ctypes.FunctionType(); }, TypeError); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, [ ctypes.void_t ]); }, Error); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, [ ctypes.void_t ], 5); - }, Error); + }, TypeError); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, ctypes.void_t); }, Error); @@ -1960,9 +1960,9 @@ function run_ArrayType_tests() { ctypes.ArrayType(ctypes.int32_t, 10), ctypes.ArrayType(ctypes.int64_t), [ "elementType", "length" ], [], [ "length" ], [ "addressOfElement" ]); - do_check_throws(function() { ctypes.ArrayType(); }, Error); + do_check_throws(function() { ctypes.ArrayType(); }, TypeError); do_check_throws(function() { ctypes.ArrayType(null); }, Error); - do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, 1, 5); }, Error); + do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, 1, 5); }, TypeError); do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, -1); }, Error); let name = "g_t"; @@ -2011,7 +2011,7 @@ function run_ArrayType_tests() { do_check_eq(a2.constructor.length, 5); do_check_eq(a2.length, 5); do_check_eq(a2.constructor.size, g_t.size * 5); - do_check_throws(function() { new a2_t(); }, Error); + do_check_throws(function() { new a2_t(); }, TypeError); do_check_throws(function() { ctypes.ArrayType(ctypes.ArrayType(g_t)); }, Error); do_check_throws(function() { ctypes.ArrayType(ctypes.ArrayType(g_t), 5); }, Error); From 84b9e85db2be23dbb2f249ce9ec51c212505988e Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 18:26:14 +0900 Subject: [PATCH 100/241] Bug 891107 - Part 3: Report argument type error as TypeError in js-ctypes. r=jorendorff --- js/src/ctypes/CTypes.cpp | 115 ++++++++++-------- js/src/ctypes/ctypes.msg | 2 + js/src/jit-test/lib/asserts.js | 22 +++- .../tests/ctypes/argument-type-array.js | 17 +++ .../tests/ctypes/argument-type-ctypes.js | 13 ++ .../tests/ctypes/argument-type-function.js | 9 ++ .../tests/ctypes/argument-type-int64.js | 28 +++++ .../tests/ctypes/argument-type-pointer.js | 9 ++ .../tests/ctypes/argument-type-struct.js | 17 +++ .../ctypes/tests/unit/test_jsctypes.js | 56 ++++----- 10 files changed, 201 insertions(+), 87 deletions(-) create mode 100644 js/src/jit-test/tests/ctypes/argument-type-array.js create mode 100644 js/src/jit-test/tests/ctypes/argument-type-ctypes.js create mode 100644 js/src/jit-test/tests/ctypes/argument-type-function.js create mode 100644 js/src/jit-test/tests/ctypes/argument-type-int64.js create mode 100644 js/src/jit-test/tests/ctypes/argument-type-pointer.js create mode 100644 js/src/jit-test/tests/ctypes/argument-type-struct.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 86ed225c308f..b2211f63ce33 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -1303,6 +1303,24 @@ ArrayLengthOverflow(JSContext* cx, unsigned expectedLength, HandleObject arrObj, return false; } +static bool +ArgumentRangeMismatch(JSContext* cx, const char* arg, const char* func, + const char* range) +{ + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_ARG_RANGE_MISMATCH, arg, func, range); + return false; +} + +static bool +ArgumentTypeMismatch(JSContext* cx, const char* arg, const char* func, + const char* type) +{ + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, + CTYPESMSG_ARG_TYPE_MISMATCH, arg, func, type); + return false; +} + static bool EmptyFinalizerError(JSContext* cx, ConversionType convType, HandleObject funObj = NullPtr(), unsigned argIndex = 0) @@ -4371,8 +4389,8 @@ CType::CreateArray(JSContext* cx, unsigned argc, jsval* vp) // Convert the length argument to a size_t. size_t length = 0; if (args.length() == 1 && !jsvalToSize(cx, args[0], false, &length)) { - JS_ReportError(cx, "argument must be a nonnegative integer"); - return false; + return ArgumentTypeMismatch(cx, "", "CType.prototype.array", + "a nonnegative integer"); } JSObject* result = ArrayType::CreateInternal(cx, baseType, length, args.length() == 1); @@ -4554,8 +4572,7 @@ PointerType::Create(JSContext* cx, unsigned argc, jsval* vp) jsval arg = args[0]; RootedObject obj(cx); if (arg.isPrimitive() || !CType::IsCType(obj = &arg.toObject())) { - JS_ReportError(cx, "first argument must be a CType"); - return false; + return ArgumentTypeMismatch(cx, "", "PointerType", "a CType"); } JSObject* result = CreateInternal(cx, obj); @@ -4852,17 +4869,15 @@ ArrayType::Create(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "ArrayType", "one or two", "s"); } - if (args[0].isPrimitive() || - !CType::IsCType(&args[0].toObject())) { - JS_ReportError(cx, "first argument must be a CType"); - return false; + if (args[0].isPrimitive() || !CType::IsCType(&args[0].toObject())) { + return ArgumentTypeMismatch(cx, "first ", "ArrayType", "a CType"); } // Convert the length argument to a size_t. size_t length = 0; if (args.length() == 2 && !jsvalToSize(cx, args[1], false, &length)) { - JS_ReportError(cx, "second argument must be a nonnegative integer"); - return false; + return ArgumentTypeMismatch(cx, "second ", "ArrayType", + "a nonnegative integer"); } RootedObject baseType(cx, &args[0].toObject()); @@ -4973,8 +4988,9 @@ ArrayType::ConstructData(JSContext* cx, RootedValue lengthVal(cx); if (!JS_GetProperty(cx, arg, "length", &lengthVal) || !jsvalToSize(cx, lengthVal, false, &length)) { - JS_ReportError(cx, "argument must be an array object or length"); - return false; + return ArgumentTypeMismatch(cx, "", + "size undefined ArrayType constructor", + "an array object or integer"); } } else if (args[0].isString()) { @@ -5006,8 +5022,9 @@ ArrayType::ConstructData(JSContext* cx, } } else { - JS_ReportError(cx, "argument must be an array object or length"); - return false; + return ArgumentTypeMismatch(cx, "", + "size undefined ArrayType constructor", + "an array object or integer"); } // Construct a new ArrayType of defined length, for the new CData object. @@ -5397,8 +5414,7 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp) jsval name = args[0]; if (!name.isString()) { - JS_ReportError(cx, "first argument must be a string"); - return false; + return ArgumentTypeMismatch(cx, "first ", "StructType", "a string"); } // Get ctypes.StructType.prototype from the ctypes.StructType constructor. @@ -5415,8 +5431,7 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp) if (args.length() == 2) { RootedObject arr(cx, args[1].isPrimitive() ? nullptr : &args[1].toObject()); if (!arr || !JS_IsArrayObject(cx, arr)) { - JS_ReportError(cx, "second argument must be an array"); - return false; + return ArgumentTypeMismatch(cx, "second ", "StructType", "an array"); } // Define the struct fields. @@ -5691,13 +5706,13 @@ StructType::Define(JSContext* cx, unsigned argc, jsval* vp) jsval arg = args[0]; if (arg.isPrimitive()) { - JS_ReportError(cx, "argument must be an array"); - return false; + return ArgumentTypeMismatch(cx, "", "StructType.prototype.define", + "an array"); } RootedObject arr(cx, arg.toObjectOrNull()); if (!JS_IsArrayObject(cx, arr)) { - JS_ReportError(cx, "argument must be an array"); - return false; + return ArgumentTypeMismatch(cx, "", "StructType.prototype.define", + "an array"); } return DefineInternal(cx, obj, arr); @@ -5981,8 +5996,8 @@ StructType::AddressOfField(JSContext* cx, unsigned argc, jsval* vp) } if (!args[0].isString()) { - JS_ReportError(cx, "argument must be a string"); - return false; + return ArgumentTypeMismatch(cx, "", "StructType.prototype.addressOfField", + "a string"); } JSFlatString* str = JS_FlattenString(cx, args[0].toString()); @@ -6332,8 +6347,7 @@ FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp) if (args[2].isObject()) arrayObj = &args[2].toObject(); if (!arrayObj || !JS_IsArrayObject(cx, arrayObj)) { - JS_ReportError(cx, "third argument must be an array"); - return false; + return ArgumentTypeMismatch(cx, "third ", "FunctionType", "an array"); } uint32_t len; @@ -7204,15 +7218,13 @@ CData::Cast(JSContext* cx, unsigned argc, jsval* vp) } if (args[0].isPrimitive() || !CData::IsCData(&args[0].toObject())) { - JS_ReportError(cx, "first argument must be a CData"); - return false; + return ArgumentTypeMismatch(cx, "first ", "ctypes.cast", "a CData"); } RootedObject sourceData(cx, &args[0].toObject()); JSObject* sourceType = CData::GetCType(sourceData); if (args[1].isPrimitive() || !CType::IsCType(&args[1].toObject())) { - JS_ReportError(cx, "second argument must be a CType"); - return false; + return ArgumentTypeMismatch(cx, "second ", "ctypes.cast", "a CType"); } RootedObject targetType(cx, &args[1].toObject()); @@ -7244,8 +7256,7 @@ CData::GetRuntime(JSContext* cx, unsigned argc, jsval* vp) } if (args[0].isPrimitive() || !CType::IsCType(&args[0].toObject())) { - JS_ReportError(cx, "first argument must be a CType"); - return false; + return ArgumentTypeMismatch(cx, "", "ctypes.getRuntime", "a CType"); } RootedObject targetType(cx, &args[0].toObject()); @@ -8069,8 +8080,10 @@ Int64Base::ToString(JSContext* cx, if (arg.isInt32()) radix = arg.toInt32(); if (!arg.isInt32() || radix < 2 || radix > 36) { - JS_ReportError(cx, "radix argument must be an integer between 2 and 36"); - return false; + if (isUnsigned) { + return ArgumentRangeMismatch(cx, "", "UInt64.prototype.toString", "an integer at least 2 and no greater than 36"); + } + return ArgumentRangeMismatch(cx, "", "Int64.prototype.toString", "an integer at least 2 and no greater than 36"); } } @@ -8196,12 +8209,11 @@ Int64::Compare(JSContext* cx, unsigned argc, jsval* vp) if (args.length() != 2) { return ArgumentLengthError(cx, "Int64.compare", "two", "s"); } - if (args[0].isPrimitive() || - args[1].isPrimitive() || - !Int64::IsInt64(&args[0].toObject()) || - !Int64::IsInt64(&args[1].toObject())) { - JS_ReportError(cx, "compare takes two Int64 arguments"); - return false; + if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { + return ArgumentTypeMismatch(cx, "first ", "Int64.compare", "a Int64"); + } + if (args[1].isPrimitive() ||!Int64::IsInt64(&args[1].toObject())) { + return ArgumentTypeMismatch(cx, "second ", "Int64.compare", "a Int64"); } JSObject* obj1 = &args[0].toObject(); @@ -8232,8 +8244,7 @@ Int64::Lo(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "Int64.lo", "one", ""); } if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { - JS_ReportError(cx, "lo takes one Int64 argument"); - return false; + return ArgumentTypeMismatch(cx, "", "Int64.lo", "a Int64"); } JSObject* obj = &args[0].toObject(); @@ -8252,8 +8263,7 @@ Int64::Hi(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "Int64.hi", "one", ""); } if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { - JS_ReportError(cx, "hi takes one Int64 argument"); - return false; + return ArgumentTypeMismatch(cx, "", "Int64.hi", "a Int64"); } JSObject* obj = &args[0].toObject(); @@ -8371,12 +8381,11 @@ UInt64::Compare(JSContext* cx, unsigned argc, jsval* vp) if (args.length() != 2) { return ArgumentLengthError(cx, "UInt64.compare", "two", "s"); } - if (args[0].isPrimitive() || - args[1].isPrimitive() || - !UInt64::IsUInt64(&args[0].toObject()) || - !UInt64::IsUInt64(&args[1].toObject())) { - JS_ReportError(cx, "compare takes two UInt64 arguments"); - return false; + if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { + return ArgumentTypeMismatch(cx, "first ", "UInt64.compare", "a UInt64"); + } + if (args[1].isPrimitive() || !UInt64::IsUInt64(&args[1].toObject())) { + return ArgumentTypeMismatch(cx, "second ", "UInt64.compare", "a UInt64"); } JSObject* obj1 = &args[0].toObject(); @@ -8403,8 +8412,7 @@ UInt64::Lo(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "UInt64.lo", "one", ""); } if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { - JS_ReportError(cx, "lo takes one UInt64 argument"); - return false; + return ArgumentTypeMismatch(cx, "", "UInt64.lo", "a UInt64"); } JSObject* obj = &args[0].toObject(); @@ -8423,8 +8431,7 @@ UInt64::Hi(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "UInt64.hi", "one", ""); } if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { - JS_ReportError(cx, "hi takes one UInt64 argument"); - return false; + return ArgumentTypeMismatch(cx, "", "UInt64.hi", "a UInt64"); } JSObject* obj = &args[0].toObject(); diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg index 84a3884c649a..49bf3f0daa4f 100644 --- a/js/src/ctypes/ctypes.msg +++ b/js/src/ctypes/ctypes.msg @@ -34,4 +34,6 @@ MSG_DEF(CTYPESMSG_EMPTY_FIN, 1, JSEXN_TYPEERR, "attempting to convert an emp MSG_DEF(CTYPESMSG_FIN_SIZE_ERROR,2, JSEXN_TYPEERR, "expected an object with the same size as argument 1 of {0}, got {1}") /* native function */ +MSG_DEF(CTYPESMSG_ARG_RANGE_MISMATCH,3, JSEXN_RANGEERR, "{0}argument of {1} must be {2}") +MSG_DEF(CTYPESMSG_ARG_TYPE_MISMATCH,3, JSEXN_TYPEERR, "{0}argument of {1} must be {2}") MSG_DEF(CTYPESMSG_WRONG_ARG_LENGTH,3, JSEXN_TYPEERR, "{0} takes {1} argument{2}") diff --git a/js/src/jit-test/lib/asserts.js b/js/src/jit-test/lib/asserts.js index c183a446fc08..1443168f79c3 100644 --- a/js/src/jit-test/lib/asserts.js +++ b/js/src/jit-test/lib/asserts.js @@ -66,13 +66,13 @@ if (typeof assertNoWarning === 'undefined') { }; } -if (typeof assertTypeErrorMessage === 'undefined') { - var assertTypeErrorMessage = function assertTypeErrorMessage(f, test) { +if (typeof assertErrorMessage === 'undefined') { + var assertErrorMessage = function assertErrorMessage(f, ctor, test) { try { f(); } catch (e) { - if (!(e instanceof TypeError)) - throw new Error("Assertion failed: expected exception TypeError, got " + e); + if (!(e instanceof ctor)) + throw new Error("Assertion failed: expected exception " + ctor.name + ", got " + e); if (typeof test == "string") { if (test != e.message) throw new Error("Assertion failed: expeceted " + test + ", got " + e.message); @@ -82,6 +82,18 @@ if (typeof assertTypeErrorMessage === 'undefined') { } return; } - throw new Error("Assertion failed: expected exception TypeError, no exception thrown"); + throw new Error("Assertion failed: expected exception " + ctor.name + ", no exception thrown"); + }; +} + +if (typeof assertTypeErrorMessage === 'undefined') { + var assertTypeErrorMessage = function assertTypeErrorMessage(f, test) { + assertErrorMessage(f, TypeError, test); + }; +} + +if (typeof assertRangeErrorMessage === 'undefined') { + var assertRangeErrorMessage = function assertRangeErrorMessage(f, test) { + assertErrorMessage(f, RangeError, test); }; } diff --git a/js/src/jit-test/tests/ctypes/argument-type-array.js b/js/src/jit-test/tests/ctypes/argument-type-array.js new file mode 100644 index 000000000000..e78578d86bd9 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-array.js @@ -0,0 +1,17 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.int32_t.array({}); }, + "argument of CType.prototype.array must be a nonnegative integer"); + assertTypeErrorMessage(() => { ctypes.ArrayType(1); }, + "first argument of ArrayType must be a CType"); + assertTypeErrorMessage(() => { ctypes.ArrayType(ctypes.int32_t, {}); }, + "second argument of ArrayType must be a nonnegative integer"); + assertTypeErrorMessage(() => { ctypes.char.array()({}); }, + "argument of size undefined ArrayType constructor must be an array object or integer"); + assertTypeErrorMessage(() => { ctypes.char.array()(false); }, + "argument of size undefined ArrayType constructor must be an array object or integer"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-ctypes.js b/js/src/jit-test/tests/ctypes/argument-type-ctypes.js new file mode 100644 index 000000000000..168c8fb746b4 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-ctypes.js @@ -0,0 +1,13 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.cast(1, 2); }, + "first argument of ctypes.cast must be a CData"); + assertTypeErrorMessage(() => { ctypes.cast(ctypes.int32_t(0), 2); }, + "second argument of ctypes.cast must be a CType"); + assertTypeErrorMessage(() => { ctypes.getRuntime(1); }, + "argument of ctypes.getRuntime must be a CType"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-function.js b/js/src/jit-test/tests/ctypes/argument-type-function.js new file mode 100644 index 000000000000..a341415f1d7e --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-function.js @@ -0,0 +1,9 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, 1); }, + "third argument of FunctionType must be an array"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-int64.js b/js/src/jit-test/tests/ctypes/argument-type-int64.js new file mode 100644 index 000000000000..e147b98a4824 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-int64.js @@ -0,0 +1,28 @@ +load(libdir + 'asserts.js'); + +function test() { + assertRangeErrorMessage(() => { ctypes.Int64(0).toString("a"); }, + "argument of Int64.prototype.toString must be an integer at least 2 and no greater than 36"); + assertTypeErrorMessage(() => { ctypes.Int64.compare(1, 2); }, + "first argument of Int64.compare must be a Int64"); + assertTypeErrorMessage(() => { ctypes.Int64.compare(ctypes.Int64(0), 2); }, + "second argument of Int64.compare must be a Int64"); + assertTypeErrorMessage(() => { ctypes.Int64.lo(1); }, + "argument of Int64.lo must be a Int64"); + assertTypeErrorMessage(() => { ctypes.Int64.hi(1); }, + "argument of Int64.hi must be a Int64"); + + assertRangeErrorMessage(() => { ctypes.UInt64(0).toString("a"); }, + "argument of UInt64.prototype.toString must be an integer at least 2 and no greater than 36"); + assertTypeErrorMessage(() => { ctypes.UInt64.compare(1, 2); }, + "first argument of UInt64.compare must be a UInt64"); + assertTypeErrorMessage(() => { ctypes.UInt64.compare(ctypes.UInt64(0), 2); }, + "second argument of UInt64.compare must be a UInt64"); + assertTypeErrorMessage(() => { ctypes.UInt64.lo(1); }, + "argument of UInt64.lo must be a UInt64"); + assertTypeErrorMessage(() => { ctypes.UInt64.hi(1); }, + "argument of UInt64.hi must be a UInt64"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-pointer.js b/js/src/jit-test/tests/ctypes/argument-type-pointer.js new file mode 100644 index 000000000000..80f96ad90532 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-pointer.js @@ -0,0 +1,9 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.PointerType({}); }, + "argument of PointerType must be a CType"); +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-struct.js b/js/src/jit-test/tests/ctypes/argument-type-struct.js new file mode 100644 index 000000000000..703c0f059f33 --- /dev/null +++ b/js/src/jit-test/tests/ctypes/argument-type-struct.js @@ -0,0 +1,17 @@ +load(libdir + 'asserts.js'); + +function test() { + assertTypeErrorMessage(() => { ctypes.StructType(1); }, + "first argument of StructType must be a string"); + assertTypeErrorMessage(() => { ctypes.StructType("a", 1); }, + "second argument of StructType must be an array"); + assertTypeErrorMessage(() => { ctypes.StructType("a").define(1); }, + "argument of StructType.prototype.define must be an array"); + assertTypeErrorMessage(() => { ctypes.StructType("a").define({}); }, + "argument of StructType.prototype.define must be an array"); + assertTypeErrorMessage(() => { ctypes.StructType("a", [{x:ctypes.int32_t}])().addressOfField(1); }, + "argument of StructType.prototype.addressOfField must be a string"); +} + +if (typeof ctypes === "object") + test(); diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index d0323def0ac0..9920931706d0 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -331,9 +331,9 @@ function run_Int64_tests() { do_check_eq(i.toString(), "0"); for (let radix = 2; radix <= 36; ++radix) do_check_eq(i.toString(radix), "0"); - do_check_throws(function() { i.toString(0); }, Error); - do_check_throws(function() { i.toString(1); }, Error); - do_check_throws(function() { i.toString(37); }, Error); + do_check_throws(function() { i.toString(0); }, RangeError); + do_check_throws(function() { i.toString(1); }, RangeError); + do_check_throws(function() { i.toString(37); }, RangeError); do_check_throws(function() { i.toString(10, 2); }, TypeError); // Test Int64.toSource(). @@ -445,18 +445,18 @@ function run_Int64_tests() { do_check_eq(ctypes.Int64.compare(ctypes.Int64(-5), ctypes.Int64(-5)), 0); do_check_eq(ctypes.Int64.compare(ctypes.Int64(-5), ctypes.Int64(-4)), -1); do_check_eq(ctypes.Int64.compare(ctypes.Int64(-4), ctypes.Int64(-5)), 1); - do_check_throws(function() { ctypes.Int64.compare(ctypes.Int64(4), ctypes.UInt64(4)); }, Error); - do_check_throws(function() { ctypes.Int64.compare(4, 5); }, Error); + do_check_throws(function() { ctypes.Int64.compare(ctypes.Int64(4), ctypes.UInt64(4)); }, TypeError); + do_check_throws(function() { ctypes.Int64.compare(4, 5); }, TypeError); // Test ctypes.Int64.{lo,hi}. do_check_eq(ctypes.Int64.lo(ctypes.Int64(0x28590a1c921de000)), 0x921de000); do_check_eq(ctypes.Int64.hi(ctypes.Int64(0x28590a1c921de000)), 0x28590a1c); do_check_eq(ctypes.Int64.lo(ctypes.Int64(-0x28590a1c921de000)), 0x6de22000); do_check_eq(ctypes.Int64.hi(ctypes.Int64(-0x28590a1c921de000)), -0x28590a1d); - do_check_throws(function() { ctypes.Int64.lo(ctypes.UInt64(0)); }, Error); - do_check_throws(function() { ctypes.Int64.hi(ctypes.UInt64(0)); }, Error); - do_check_throws(function() { ctypes.Int64.lo(0); }, Error); - do_check_throws(function() { ctypes.Int64.hi(0); }, Error); + do_check_throws(function() { ctypes.Int64.lo(ctypes.UInt64(0)); }, TypeError); + do_check_throws(function() { ctypes.Int64.hi(ctypes.UInt64(0)); }, TypeError); + do_check_throws(function() { ctypes.Int64.lo(0); }, TypeError); + do_check_throws(function() { ctypes.Int64.hi(0); }, TypeError); // Test ctypes.Int64.join. do_check_eq(ctypes.Int64.join(0, 0).toString(), "0"); @@ -502,9 +502,9 @@ function run_UInt64_tests() { do_check_eq(i.toString(), "0"); for (let radix = 2; radix <= 36; ++radix) do_check_eq(i.toString(radix), "0"); - do_check_throws(function() { i.toString(0); }, Error); - do_check_throws(function() { i.toString(1); }, Error); - do_check_throws(function() { i.toString(37); }, Error); + do_check_throws(function() { i.toString(0); }, RangeError); + do_check_throws(function() { i.toString(1); }, RangeError); + do_check_throws(function() { i.toString(37); }, RangeError); do_check_throws(function() { i.toString(10, 2); }, TypeError); // Test UInt64.toSource(). @@ -592,18 +592,18 @@ function run_UInt64_tests() { do_check_eq(ctypes.UInt64.compare(ctypes.UInt64(5), ctypes.UInt64(5)), 0); do_check_eq(ctypes.UInt64.compare(ctypes.UInt64(5), ctypes.UInt64(4)), 1); do_check_eq(ctypes.UInt64.compare(ctypes.UInt64(4), ctypes.UInt64(5)), -1); - do_check_throws(function() { ctypes.UInt64.compare(ctypes.UInt64(4), ctypes.Int64(4)); }, Error); - do_check_throws(function() { ctypes.UInt64.compare(4, 5); }, Error); + do_check_throws(function() { ctypes.UInt64.compare(ctypes.UInt64(4), ctypes.Int64(4)); }, TypeError); + do_check_throws(function() { ctypes.UInt64.compare(4, 5); }, TypeError); // Test ctypes.UInt64.{lo,hi}. do_check_eq(ctypes.UInt64.lo(ctypes.UInt64(0x28590a1c921de000)), 0x921de000); do_check_eq(ctypes.UInt64.hi(ctypes.UInt64(0x28590a1c921de000)), 0x28590a1c); do_check_eq(ctypes.UInt64.lo(ctypes.UInt64(0xa8590a1c921de000)), 0x921de000); do_check_eq(ctypes.UInt64.hi(ctypes.UInt64(0xa8590a1c921de000)), 0xa8590a1c); - do_check_throws(function() { ctypes.UInt64.lo(ctypes.Int64(0)); }, Error); - do_check_throws(function() { ctypes.UInt64.hi(ctypes.Int64(0)); }, Error); - do_check_throws(function() { ctypes.UInt64.lo(0); }, Error); - do_check_throws(function() { ctypes.UInt64.hi(0); }, Error); + do_check_throws(function() { ctypes.UInt64.lo(ctypes.Int64(0)); }, TypeError); + do_check_throws(function() { ctypes.UInt64.hi(ctypes.Int64(0)); }, TypeError); + do_check_throws(function() { ctypes.UInt64.lo(0); }, TypeError); + do_check_throws(function() { ctypes.UInt64.hi(0); }, TypeError); // Test ctypes.UInt64.join. do_check_eq(ctypes.UInt64.join(0, 0).toString(), "0"); @@ -1374,8 +1374,8 @@ function run_StructType_tests() { do_check_throws(function() { ctypes.StructType(); }, TypeError); do_check_throws(function() { ctypes.StructType("a", [], 5); }, TypeError); - do_check_throws(function() { ctypes.StructType(null, []); }, Error); - do_check_throws(function() { ctypes.StructType("a", null); }, Error); + do_check_throws(function() { ctypes.StructType(null, []); }, TypeError); + do_check_throws(function() { ctypes.StructType("a", null); }, TypeError); // Check that malformed descriptors are an error. do_check_throws(function() { @@ -1659,9 +1659,9 @@ function run_PointerType_tests() { do_check_throws(function() { ctypes.PointerType(); }, TypeError); do_check_throws(function() { ctypes.PointerType(ctypes.int32_t, 5); }, TypeError); - do_check_throws(function() { ctypes.PointerType(null); }, Error); - do_check_throws(function() { ctypes.PointerType(ctypes.int32_t()); }, Error); - do_check_throws(function() { ctypes.PointerType("void"); }, Error); + do_check_throws(function() { ctypes.PointerType(null); }, TypeError); + do_check_throws(function() { ctypes.PointerType(ctypes.int32_t()); }, TypeError); + do_check_throws(function() { ctypes.PointerType("void"); }, TypeError); let name = "g_t"; let g_t = ctypes.StructType(name, [{ a: ctypes.int32_t }, { b: ctypes.double }]); @@ -1844,10 +1844,10 @@ function run_FunctionType_tests() { }, TypeError); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, ctypes.void_t); - }, Error); + }, TypeError); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, null); - }, Error); + }, TypeError); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t()); }, Error); @@ -1961,9 +1961,9 @@ function run_ArrayType_tests() { [ "elementType", "length" ], [], [ "length" ], [ "addressOfElement" ]); do_check_throws(function() { ctypes.ArrayType(); }, TypeError); - do_check_throws(function() { ctypes.ArrayType(null); }, Error); + do_check_throws(function() { ctypes.ArrayType(null); }, TypeError); do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, 1, 5); }, TypeError); - do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, -1); }, Error); + do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, -1); }, TypeError); let name = "g_t"; let g_t = ctypes.StructType(name, [{ a: ctypes.int32_t }, { b: ctypes.double }]); @@ -2036,7 +2036,7 @@ function run_ArrayType_tests() { } else { do_check_throws(function() { ctypes.ArrayType(ctypes.int8_t, ctypes.UInt64("0xffffffffffffffff")); - }, Error); + }, TypeError); do_check_throws(function() { ctypes.ArrayType(ctypes.int16_t, ctypes.UInt64("0x8000000000000000")); }, Error); From b385723d9d231228a83f928766a1bfafea46bf36 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Wed, 22 Apr 2015 11:30:47 +0200 Subject: [PATCH 101/241] Bug 1156886 - Optimize toLowerCase and toUpperCase on ASCII characters. r=luke --HG-- extra : rebase_source : 6e715d90e59540dd36e30414a77ab2d7c303b7e5 --- js/src/jsstr.cpp | 4 ++-- js/src/vm/Unicode.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 1cd2be6b8e70..7752217af047 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -603,7 +603,7 @@ ToLowerCase(JSContext* cx, JSLinearString* str) size_t i = 0; for (; i < length; i++) { char16_t c = chars[i]; - if (unicode::ToLowerCase(c) != c) + if (unicode::CanLowerCase(c)) break; } @@ -722,7 +722,7 @@ ToUpperCase(JSContext* cx, JSLinearString* str) size_t i = 0; for (; i < length; i++) { char16_t c = chars[i]; - if (unicode::ToUpperCase(c) != c) + if (unicode::CanUpperCase(c)) break; } diff --git a/js/src/vm/Unicode.h b/js/src/vm/Unicode.h index 591e46f56e25..ea853442c7f9 100644 --- a/js/src/vm/Unicode.h +++ b/js/src/vm/Unicode.h @@ -191,6 +191,12 @@ IsSpaceOrBOM2(char16_t ch) inline char16_t ToUpperCase(char16_t ch) { + if (ch < 128) { + if (ch >= 'a' && ch <= 'z') + return ch - ('a' - 'A'); + return ch; + } + const CharacterInfo& info = CharInfo(ch); return uint16_t(ch) + info.upperCase; @@ -199,11 +205,35 @@ ToUpperCase(char16_t ch) inline char16_t ToLowerCase(char16_t ch) { + if (ch < 128) { + if (ch >= 'A' && ch <= 'Z') + return ch + ('a' - 'A'); + return ch; + } + const CharacterInfo& info = CharInfo(ch); return uint16_t(ch) + info.lowerCase; } +// Returns true iff ToUpperCase(ch) != ch. +inline bool +CanUpperCase(char16_t ch) +{ + if (ch < 128) + return ch >= 'a' && ch <= 'z'; + return CharInfo(ch).upperCase != 0; +} + +// Returns true iff ToLowerCase(ch) != ch. +inline bool +CanLowerCase(char16_t ch) +{ + if (ch < 128) + return ch >= 'A' && ch <= 'Z'; + return CharInfo(ch).lowerCase != 0; +} + } /* namespace unicode */ } /* namespace js */ From 6a32ce3434fa08d7378ea5cd58cca8a9ad400f60 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 22 Apr 2015 12:02:01 +0200 Subject: [PATCH 102/241] Bug 1155626 - Don't assume that Factory::GetD2D1Device returns a non-null device and add some gfxCriticalLog. r=Bas --- gfx/2d/DrawTargetD2D1.cpp | 14 ++++++++++++-- gfx/2d/Factory.cpp | 5 ++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index a2c9b291a1b9..81399b7ce39a 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -739,7 +739,12 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat) { HRESULT hr; - hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC)); + ID2D1Device* device = Factory::GetD2D1Device(); + if (!device) { + return false; + } + + hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC)); if (FAILED(hr)) { gfxCriticalError() <<"[D2D1.1] 1Failed to create a DeviceContext, code: " << hexa(hr); @@ -794,7 +799,12 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat) { HRESULT hr; - hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC)); + ID2D1Device* device = Factory::GetD2D1Device(); + if (!device) { + return false; + } + + hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC)); if (FAILED(hr)) { gfxCriticalError() <<"[D2D1.1] 2Failed to create a DeviceContext, code: " << hexa(hr); diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index 948d3c3bbda7..c7d6aaf2f566 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -681,7 +681,10 @@ Factory::SetDirect3D11Device(ID3D11Device *aDevice) RefPtr device; aDevice->QueryInterface((IDXGIDevice**)byRef(device)); - factory->CreateDevice(device, &mD2D1Device); + HRESULT hr = factory->CreateDevice(device, &mD2D1Device); + if (FAILED(hr)) { + gfxCriticalError() << "[D2D1] Failed to create gfx factory's D2D1 device, code: " << hexa(hr); + } } ID3D11Device* From 38812b566179e24646bfce897349562d2e7745b6 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 22 Apr 2015 12:06:53 +0200 Subject: [PATCH 103/241] Bug 1155252 - Add a pref to control the maximum canvas 2d size and set it to 0x7ff. r=jrmuizel --- dom/canvas/CanvasRenderingContext2D.cpp | 3 ++- gfx/thebes/gfxPrefs.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index fd7d6c17d2f1..92501f038217 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -1334,7 +1334,8 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode) // Check that the dimensions are sane IntSize size(mWidth, mHeight); - if (size.width <= 0xFFFF && size.height <= 0xFFFF && + if (size.width <= gfxPrefs::MaxCanvasSize() && + size.height <= gfxPrefs::MaxCanvasSize() && size.width >= 0 && size.height >= 0) { SurfaceFormat format = GetSurfaceFormat(); nsIDocument* ownerDoc = nullptr; diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 3f48d0a1488c..b3544914070c 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -205,6 +205,8 @@ private: DECL_GFX_PREF(Live, "gfx.canvas.auto_accelerate.min_frames", CanvasAutoAccelerateMinFrames, int32_t, 30); DECL_GFX_PREF(Live, "gfx.canvas.auto_accelerate.min_seconds", CanvasAutoAccelerateMinSeconds, float, 5.0f); DECL_GFX_PREF(Live, "gfx.canvas.azure.accelerated", CanvasAzureAccelerated, bool, false); + // 0x7fff is the maximum supported xlib surface size and is more than enough for canvases. + DECL_GFX_PREF(Live, "gfx.canvas.max-size", MaxCanvasSize, uint32_t, 0x7fff); DECL_GFX_PREF(Once, "gfx.canvas.skiagl.cache-items", CanvasSkiaGLCacheItems, int32_t, 256); DECL_GFX_PREF(Once, "gfx.canvas.skiagl.cache-size", CanvasSkiaGLCacheSize, int32_t, 96); DECL_GFX_PREF(Once, "gfx.canvas.skiagl.dynamic-cache", CanvasSkiaGLDynamicCache, bool, false); From c883352e91d581641445359d694197b8da2b3bac Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 22 Apr 2015 12:37:56 +0200 Subject: [PATCH 104/241] Bug 1155252 * -WError fix --- gfx/thebes/gfxPrefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index b3544914070c..2319074128e7 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -206,7 +206,7 @@ private: DECL_GFX_PREF(Live, "gfx.canvas.auto_accelerate.min_seconds", CanvasAutoAccelerateMinSeconds, float, 5.0f); DECL_GFX_PREF(Live, "gfx.canvas.azure.accelerated", CanvasAzureAccelerated, bool, false); // 0x7fff is the maximum supported xlib surface size and is more than enough for canvases. - DECL_GFX_PREF(Live, "gfx.canvas.max-size", MaxCanvasSize, uint32_t, 0x7fff); + DECL_GFX_PREF(Live, "gfx.canvas.max-size", MaxCanvasSize, int32_t, 0x7fff); DECL_GFX_PREF(Once, "gfx.canvas.skiagl.cache-items", CanvasSkiaGLCacheItems, int32_t, 256); DECL_GFX_PREF(Once, "gfx.canvas.skiagl.cache-size", CanvasSkiaGLCacheSize, int32_t, 96); DECL_GFX_PREF(Once, "gfx.canvas.skiagl.dynamic-cache", CanvasSkiaGLDynamicCache, bool, false); From a74592cf8ff087a1d84369b8d5f6f23b1f17aba4 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 20:08:19 +0900 Subject: [PATCH 105/241] Backed out changeset 467559ddc08f (bug 891107) for xpcshell-test failure --- js/src/ctypes/CTypes.cpp | 115 ++++++++---------- js/src/ctypes/ctypes.msg | 2 - js/src/jit-test/lib/asserts.js | 22 +--- .../tests/ctypes/argument-type-array.js | 17 --- .../tests/ctypes/argument-type-ctypes.js | 13 -- .../tests/ctypes/argument-type-function.js | 9 -- .../tests/ctypes/argument-type-int64.js | 28 ----- .../tests/ctypes/argument-type-pointer.js | 9 -- .../tests/ctypes/argument-type-struct.js | 17 --- .../ctypes/tests/unit/test_jsctypes.js | 56 ++++----- 10 files changed, 87 insertions(+), 201 deletions(-) delete mode 100644 js/src/jit-test/tests/ctypes/argument-type-array.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-type-ctypes.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-type-function.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-type-int64.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-type-pointer.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-type-struct.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index b2211f63ce33..86ed225c308f 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -1303,24 +1303,6 @@ ArrayLengthOverflow(JSContext* cx, unsigned expectedLength, HandleObject arrObj, return false; } -static bool -ArgumentRangeMismatch(JSContext* cx, const char* arg, const char* func, - const char* range) -{ - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_ARG_RANGE_MISMATCH, arg, func, range); - return false; -} - -static bool -ArgumentTypeMismatch(JSContext* cx, const char* arg, const char* func, - const char* type) -{ - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_ARG_TYPE_MISMATCH, arg, func, type); - return false; -} - static bool EmptyFinalizerError(JSContext* cx, ConversionType convType, HandleObject funObj = NullPtr(), unsigned argIndex = 0) @@ -4389,8 +4371,8 @@ CType::CreateArray(JSContext* cx, unsigned argc, jsval* vp) // Convert the length argument to a size_t. size_t length = 0; if (args.length() == 1 && !jsvalToSize(cx, args[0], false, &length)) { - return ArgumentTypeMismatch(cx, "", "CType.prototype.array", - "a nonnegative integer"); + JS_ReportError(cx, "argument must be a nonnegative integer"); + return false; } JSObject* result = ArrayType::CreateInternal(cx, baseType, length, args.length() == 1); @@ -4572,7 +4554,8 @@ PointerType::Create(JSContext* cx, unsigned argc, jsval* vp) jsval arg = args[0]; RootedObject obj(cx); if (arg.isPrimitive() || !CType::IsCType(obj = &arg.toObject())) { - return ArgumentTypeMismatch(cx, "", "PointerType", "a CType"); + JS_ReportError(cx, "first argument must be a CType"); + return false; } JSObject* result = CreateInternal(cx, obj); @@ -4869,15 +4852,17 @@ ArrayType::Create(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "ArrayType", "one or two", "s"); } - if (args[0].isPrimitive() || !CType::IsCType(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "first ", "ArrayType", "a CType"); + if (args[0].isPrimitive() || + !CType::IsCType(&args[0].toObject())) { + JS_ReportError(cx, "first argument must be a CType"); + return false; } // Convert the length argument to a size_t. size_t length = 0; if (args.length() == 2 && !jsvalToSize(cx, args[1], false, &length)) { - return ArgumentTypeMismatch(cx, "second ", "ArrayType", - "a nonnegative integer"); + JS_ReportError(cx, "second argument must be a nonnegative integer"); + return false; } RootedObject baseType(cx, &args[0].toObject()); @@ -4988,9 +4973,8 @@ ArrayType::ConstructData(JSContext* cx, RootedValue lengthVal(cx); if (!JS_GetProperty(cx, arg, "length", &lengthVal) || !jsvalToSize(cx, lengthVal, false, &length)) { - return ArgumentTypeMismatch(cx, "", - "size undefined ArrayType constructor", - "an array object or integer"); + JS_ReportError(cx, "argument must be an array object or length"); + return false; } } else if (args[0].isString()) { @@ -5022,9 +5006,8 @@ ArrayType::ConstructData(JSContext* cx, } } else { - return ArgumentTypeMismatch(cx, "", - "size undefined ArrayType constructor", - "an array object or integer"); + JS_ReportError(cx, "argument must be an array object or length"); + return false; } // Construct a new ArrayType of defined length, for the new CData object. @@ -5414,7 +5397,8 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp) jsval name = args[0]; if (!name.isString()) { - return ArgumentTypeMismatch(cx, "first ", "StructType", "a string"); + JS_ReportError(cx, "first argument must be a string"); + return false; } // Get ctypes.StructType.prototype from the ctypes.StructType constructor. @@ -5431,7 +5415,8 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp) if (args.length() == 2) { RootedObject arr(cx, args[1].isPrimitive() ? nullptr : &args[1].toObject()); if (!arr || !JS_IsArrayObject(cx, arr)) { - return ArgumentTypeMismatch(cx, "second ", "StructType", "an array"); + JS_ReportError(cx, "second argument must be an array"); + return false; } // Define the struct fields. @@ -5706,13 +5691,13 @@ StructType::Define(JSContext* cx, unsigned argc, jsval* vp) jsval arg = args[0]; if (arg.isPrimitive()) { - return ArgumentTypeMismatch(cx, "", "StructType.prototype.define", - "an array"); + JS_ReportError(cx, "argument must be an array"); + return false; } RootedObject arr(cx, arg.toObjectOrNull()); if (!JS_IsArrayObject(cx, arr)) { - return ArgumentTypeMismatch(cx, "", "StructType.prototype.define", - "an array"); + JS_ReportError(cx, "argument must be an array"); + return false; } return DefineInternal(cx, obj, arr); @@ -5996,8 +5981,8 @@ StructType::AddressOfField(JSContext* cx, unsigned argc, jsval* vp) } if (!args[0].isString()) { - return ArgumentTypeMismatch(cx, "", "StructType.prototype.addressOfField", - "a string"); + JS_ReportError(cx, "argument must be a string"); + return false; } JSFlatString* str = JS_FlattenString(cx, args[0].toString()); @@ -6347,7 +6332,8 @@ FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp) if (args[2].isObject()) arrayObj = &args[2].toObject(); if (!arrayObj || !JS_IsArrayObject(cx, arrayObj)) { - return ArgumentTypeMismatch(cx, "third ", "FunctionType", "an array"); + JS_ReportError(cx, "third argument must be an array"); + return false; } uint32_t len; @@ -7218,13 +7204,15 @@ CData::Cast(JSContext* cx, unsigned argc, jsval* vp) } if (args[0].isPrimitive() || !CData::IsCData(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "first ", "ctypes.cast", "a CData"); + JS_ReportError(cx, "first argument must be a CData"); + return false; } RootedObject sourceData(cx, &args[0].toObject()); JSObject* sourceType = CData::GetCType(sourceData); if (args[1].isPrimitive() || !CType::IsCType(&args[1].toObject())) { - return ArgumentTypeMismatch(cx, "second ", "ctypes.cast", "a CType"); + JS_ReportError(cx, "second argument must be a CType"); + return false; } RootedObject targetType(cx, &args[1].toObject()); @@ -7256,7 +7244,8 @@ CData::GetRuntime(JSContext* cx, unsigned argc, jsval* vp) } if (args[0].isPrimitive() || !CType::IsCType(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "", "ctypes.getRuntime", "a CType"); + JS_ReportError(cx, "first argument must be a CType"); + return false; } RootedObject targetType(cx, &args[0].toObject()); @@ -8080,10 +8069,8 @@ Int64Base::ToString(JSContext* cx, if (arg.isInt32()) radix = arg.toInt32(); if (!arg.isInt32() || radix < 2 || radix > 36) { - if (isUnsigned) { - return ArgumentRangeMismatch(cx, "", "UInt64.prototype.toString", "an integer at least 2 and no greater than 36"); - } - return ArgumentRangeMismatch(cx, "", "Int64.prototype.toString", "an integer at least 2 and no greater than 36"); + JS_ReportError(cx, "radix argument must be an integer between 2 and 36"); + return false; } } @@ -8209,11 +8196,12 @@ Int64::Compare(JSContext* cx, unsigned argc, jsval* vp) if (args.length() != 2) { return ArgumentLengthError(cx, "Int64.compare", "two", "s"); } - if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "first ", "Int64.compare", "a Int64"); - } - if (args[1].isPrimitive() ||!Int64::IsInt64(&args[1].toObject())) { - return ArgumentTypeMismatch(cx, "second ", "Int64.compare", "a Int64"); + if (args[0].isPrimitive() || + args[1].isPrimitive() || + !Int64::IsInt64(&args[0].toObject()) || + !Int64::IsInt64(&args[1].toObject())) { + JS_ReportError(cx, "compare takes two Int64 arguments"); + return false; } JSObject* obj1 = &args[0].toObject(); @@ -8244,7 +8232,8 @@ Int64::Lo(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "Int64.lo", "one", ""); } if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "", "Int64.lo", "a Int64"); + JS_ReportError(cx, "lo takes one Int64 argument"); + return false; } JSObject* obj = &args[0].toObject(); @@ -8263,7 +8252,8 @@ Int64::Hi(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "Int64.hi", "one", ""); } if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "", "Int64.hi", "a Int64"); + JS_ReportError(cx, "hi takes one Int64 argument"); + return false; } JSObject* obj = &args[0].toObject(); @@ -8381,11 +8371,12 @@ UInt64::Compare(JSContext* cx, unsigned argc, jsval* vp) if (args.length() != 2) { return ArgumentLengthError(cx, "UInt64.compare", "two", "s"); } - if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "first ", "UInt64.compare", "a UInt64"); - } - if (args[1].isPrimitive() || !UInt64::IsUInt64(&args[1].toObject())) { - return ArgumentTypeMismatch(cx, "second ", "UInt64.compare", "a UInt64"); + if (args[0].isPrimitive() || + args[1].isPrimitive() || + !UInt64::IsUInt64(&args[0].toObject()) || + !UInt64::IsUInt64(&args[1].toObject())) { + JS_ReportError(cx, "compare takes two UInt64 arguments"); + return false; } JSObject* obj1 = &args[0].toObject(); @@ -8412,7 +8403,8 @@ UInt64::Lo(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "UInt64.lo", "one", ""); } if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "", "UInt64.lo", "a UInt64"); + JS_ReportError(cx, "lo takes one UInt64 argument"); + return false; } JSObject* obj = &args[0].toObject(); @@ -8431,7 +8423,8 @@ UInt64::Hi(JSContext* cx, unsigned argc, jsval* vp) return ArgumentLengthError(cx, "UInt64.hi", "one", ""); } if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { - return ArgumentTypeMismatch(cx, "", "UInt64.hi", "a UInt64"); + JS_ReportError(cx, "hi takes one UInt64 argument"); + return false; } JSObject* obj = &args[0].toObject(); diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg index 49bf3f0daa4f..84a3884c649a 100644 --- a/js/src/ctypes/ctypes.msg +++ b/js/src/ctypes/ctypes.msg @@ -34,6 +34,4 @@ MSG_DEF(CTYPESMSG_EMPTY_FIN, 1, JSEXN_TYPEERR, "attempting to convert an emp MSG_DEF(CTYPESMSG_FIN_SIZE_ERROR,2, JSEXN_TYPEERR, "expected an object with the same size as argument 1 of {0}, got {1}") /* native function */ -MSG_DEF(CTYPESMSG_ARG_RANGE_MISMATCH,3, JSEXN_RANGEERR, "{0}argument of {1} must be {2}") -MSG_DEF(CTYPESMSG_ARG_TYPE_MISMATCH,3, JSEXN_TYPEERR, "{0}argument of {1} must be {2}") MSG_DEF(CTYPESMSG_WRONG_ARG_LENGTH,3, JSEXN_TYPEERR, "{0} takes {1} argument{2}") diff --git a/js/src/jit-test/lib/asserts.js b/js/src/jit-test/lib/asserts.js index 1443168f79c3..c183a446fc08 100644 --- a/js/src/jit-test/lib/asserts.js +++ b/js/src/jit-test/lib/asserts.js @@ -66,13 +66,13 @@ if (typeof assertNoWarning === 'undefined') { }; } -if (typeof assertErrorMessage === 'undefined') { - var assertErrorMessage = function assertErrorMessage(f, ctor, test) { +if (typeof assertTypeErrorMessage === 'undefined') { + var assertTypeErrorMessage = function assertTypeErrorMessage(f, test) { try { f(); } catch (e) { - if (!(e instanceof ctor)) - throw new Error("Assertion failed: expected exception " + ctor.name + ", got " + e); + if (!(e instanceof TypeError)) + throw new Error("Assertion failed: expected exception TypeError, got " + e); if (typeof test == "string") { if (test != e.message) throw new Error("Assertion failed: expeceted " + test + ", got " + e.message); @@ -82,18 +82,6 @@ if (typeof assertErrorMessage === 'undefined') { } return; } - throw new Error("Assertion failed: expected exception " + ctor.name + ", no exception thrown"); - }; -} - -if (typeof assertTypeErrorMessage === 'undefined') { - var assertTypeErrorMessage = function assertTypeErrorMessage(f, test) { - assertErrorMessage(f, TypeError, test); - }; -} - -if (typeof assertRangeErrorMessage === 'undefined') { - var assertRangeErrorMessage = function assertRangeErrorMessage(f, test) { - assertErrorMessage(f, RangeError, test); + throw new Error("Assertion failed: expected exception TypeError, no exception thrown"); }; } diff --git a/js/src/jit-test/tests/ctypes/argument-type-array.js b/js/src/jit-test/tests/ctypes/argument-type-array.js deleted file mode 100644 index e78578d86bd9..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-type-array.js +++ /dev/null @@ -1,17 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.int32_t.array({}); }, - "argument of CType.prototype.array must be a nonnegative integer"); - assertTypeErrorMessage(() => { ctypes.ArrayType(1); }, - "first argument of ArrayType must be a CType"); - assertTypeErrorMessage(() => { ctypes.ArrayType(ctypes.int32_t, {}); }, - "second argument of ArrayType must be a nonnegative integer"); - assertTypeErrorMessage(() => { ctypes.char.array()({}); }, - "argument of size undefined ArrayType constructor must be an array object or integer"); - assertTypeErrorMessage(() => { ctypes.char.array()(false); }, - "argument of size undefined ArrayType constructor must be an array object or integer"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-ctypes.js b/js/src/jit-test/tests/ctypes/argument-type-ctypes.js deleted file mode 100644 index 168c8fb746b4..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-type-ctypes.js +++ /dev/null @@ -1,13 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.cast(1, 2); }, - "first argument of ctypes.cast must be a CData"); - assertTypeErrorMessage(() => { ctypes.cast(ctypes.int32_t(0), 2); }, - "second argument of ctypes.cast must be a CType"); - assertTypeErrorMessage(() => { ctypes.getRuntime(1); }, - "argument of ctypes.getRuntime must be a CType"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-function.js b/js/src/jit-test/tests/ctypes/argument-type-function.js deleted file mode 100644 index a341415f1d7e..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-type-function.js +++ /dev/null @@ -1,9 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, 1); }, - "third argument of FunctionType must be an array"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-int64.js b/js/src/jit-test/tests/ctypes/argument-type-int64.js deleted file mode 100644 index e147b98a4824..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-type-int64.js +++ /dev/null @@ -1,28 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertRangeErrorMessage(() => { ctypes.Int64(0).toString("a"); }, - "argument of Int64.prototype.toString must be an integer at least 2 and no greater than 36"); - assertTypeErrorMessage(() => { ctypes.Int64.compare(1, 2); }, - "first argument of Int64.compare must be a Int64"); - assertTypeErrorMessage(() => { ctypes.Int64.compare(ctypes.Int64(0), 2); }, - "second argument of Int64.compare must be a Int64"); - assertTypeErrorMessage(() => { ctypes.Int64.lo(1); }, - "argument of Int64.lo must be a Int64"); - assertTypeErrorMessage(() => { ctypes.Int64.hi(1); }, - "argument of Int64.hi must be a Int64"); - - assertRangeErrorMessage(() => { ctypes.UInt64(0).toString("a"); }, - "argument of UInt64.prototype.toString must be an integer at least 2 and no greater than 36"); - assertTypeErrorMessage(() => { ctypes.UInt64.compare(1, 2); }, - "first argument of UInt64.compare must be a UInt64"); - assertTypeErrorMessage(() => { ctypes.UInt64.compare(ctypes.UInt64(0), 2); }, - "second argument of UInt64.compare must be a UInt64"); - assertTypeErrorMessage(() => { ctypes.UInt64.lo(1); }, - "argument of UInt64.lo must be a UInt64"); - assertTypeErrorMessage(() => { ctypes.UInt64.hi(1); }, - "argument of UInt64.hi must be a UInt64"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-pointer.js b/js/src/jit-test/tests/ctypes/argument-type-pointer.js deleted file mode 100644 index 80f96ad90532..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-type-pointer.js +++ /dev/null @@ -1,9 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.PointerType({}); }, - "argument of PointerType must be a CType"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-type-struct.js b/js/src/jit-test/tests/ctypes/argument-type-struct.js deleted file mode 100644 index 703c0f059f33..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-type-struct.js +++ /dev/null @@ -1,17 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.StructType(1); }, - "first argument of StructType must be a string"); - assertTypeErrorMessage(() => { ctypes.StructType("a", 1); }, - "second argument of StructType must be an array"); - assertTypeErrorMessage(() => { ctypes.StructType("a").define(1); }, - "argument of StructType.prototype.define must be an array"); - assertTypeErrorMessage(() => { ctypes.StructType("a").define({}); }, - "argument of StructType.prototype.define must be an array"); - assertTypeErrorMessage(() => { ctypes.StructType("a", [{x:ctypes.int32_t}])().addressOfField(1); }, - "argument of StructType.prototype.addressOfField must be a string"); -} - -if (typeof ctypes === "object") - test(); diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index 9920931706d0..d0323def0ac0 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -331,9 +331,9 @@ function run_Int64_tests() { do_check_eq(i.toString(), "0"); for (let radix = 2; radix <= 36; ++radix) do_check_eq(i.toString(radix), "0"); - do_check_throws(function() { i.toString(0); }, RangeError); - do_check_throws(function() { i.toString(1); }, RangeError); - do_check_throws(function() { i.toString(37); }, RangeError); + do_check_throws(function() { i.toString(0); }, Error); + do_check_throws(function() { i.toString(1); }, Error); + do_check_throws(function() { i.toString(37); }, Error); do_check_throws(function() { i.toString(10, 2); }, TypeError); // Test Int64.toSource(). @@ -445,18 +445,18 @@ function run_Int64_tests() { do_check_eq(ctypes.Int64.compare(ctypes.Int64(-5), ctypes.Int64(-5)), 0); do_check_eq(ctypes.Int64.compare(ctypes.Int64(-5), ctypes.Int64(-4)), -1); do_check_eq(ctypes.Int64.compare(ctypes.Int64(-4), ctypes.Int64(-5)), 1); - do_check_throws(function() { ctypes.Int64.compare(ctypes.Int64(4), ctypes.UInt64(4)); }, TypeError); - do_check_throws(function() { ctypes.Int64.compare(4, 5); }, TypeError); + do_check_throws(function() { ctypes.Int64.compare(ctypes.Int64(4), ctypes.UInt64(4)); }, Error); + do_check_throws(function() { ctypes.Int64.compare(4, 5); }, Error); // Test ctypes.Int64.{lo,hi}. do_check_eq(ctypes.Int64.lo(ctypes.Int64(0x28590a1c921de000)), 0x921de000); do_check_eq(ctypes.Int64.hi(ctypes.Int64(0x28590a1c921de000)), 0x28590a1c); do_check_eq(ctypes.Int64.lo(ctypes.Int64(-0x28590a1c921de000)), 0x6de22000); do_check_eq(ctypes.Int64.hi(ctypes.Int64(-0x28590a1c921de000)), -0x28590a1d); - do_check_throws(function() { ctypes.Int64.lo(ctypes.UInt64(0)); }, TypeError); - do_check_throws(function() { ctypes.Int64.hi(ctypes.UInt64(0)); }, TypeError); - do_check_throws(function() { ctypes.Int64.lo(0); }, TypeError); - do_check_throws(function() { ctypes.Int64.hi(0); }, TypeError); + do_check_throws(function() { ctypes.Int64.lo(ctypes.UInt64(0)); }, Error); + do_check_throws(function() { ctypes.Int64.hi(ctypes.UInt64(0)); }, Error); + do_check_throws(function() { ctypes.Int64.lo(0); }, Error); + do_check_throws(function() { ctypes.Int64.hi(0); }, Error); // Test ctypes.Int64.join. do_check_eq(ctypes.Int64.join(0, 0).toString(), "0"); @@ -502,9 +502,9 @@ function run_UInt64_tests() { do_check_eq(i.toString(), "0"); for (let radix = 2; radix <= 36; ++radix) do_check_eq(i.toString(radix), "0"); - do_check_throws(function() { i.toString(0); }, RangeError); - do_check_throws(function() { i.toString(1); }, RangeError); - do_check_throws(function() { i.toString(37); }, RangeError); + do_check_throws(function() { i.toString(0); }, Error); + do_check_throws(function() { i.toString(1); }, Error); + do_check_throws(function() { i.toString(37); }, Error); do_check_throws(function() { i.toString(10, 2); }, TypeError); // Test UInt64.toSource(). @@ -592,18 +592,18 @@ function run_UInt64_tests() { do_check_eq(ctypes.UInt64.compare(ctypes.UInt64(5), ctypes.UInt64(5)), 0); do_check_eq(ctypes.UInt64.compare(ctypes.UInt64(5), ctypes.UInt64(4)), 1); do_check_eq(ctypes.UInt64.compare(ctypes.UInt64(4), ctypes.UInt64(5)), -1); - do_check_throws(function() { ctypes.UInt64.compare(ctypes.UInt64(4), ctypes.Int64(4)); }, TypeError); - do_check_throws(function() { ctypes.UInt64.compare(4, 5); }, TypeError); + do_check_throws(function() { ctypes.UInt64.compare(ctypes.UInt64(4), ctypes.Int64(4)); }, Error); + do_check_throws(function() { ctypes.UInt64.compare(4, 5); }, Error); // Test ctypes.UInt64.{lo,hi}. do_check_eq(ctypes.UInt64.lo(ctypes.UInt64(0x28590a1c921de000)), 0x921de000); do_check_eq(ctypes.UInt64.hi(ctypes.UInt64(0x28590a1c921de000)), 0x28590a1c); do_check_eq(ctypes.UInt64.lo(ctypes.UInt64(0xa8590a1c921de000)), 0x921de000); do_check_eq(ctypes.UInt64.hi(ctypes.UInt64(0xa8590a1c921de000)), 0xa8590a1c); - do_check_throws(function() { ctypes.UInt64.lo(ctypes.Int64(0)); }, TypeError); - do_check_throws(function() { ctypes.UInt64.hi(ctypes.Int64(0)); }, TypeError); - do_check_throws(function() { ctypes.UInt64.lo(0); }, TypeError); - do_check_throws(function() { ctypes.UInt64.hi(0); }, TypeError); + do_check_throws(function() { ctypes.UInt64.lo(ctypes.Int64(0)); }, Error); + do_check_throws(function() { ctypes.UInt64.hi(ctypes.Int64(0)); }, Error); + do_check_throws(function() { ctypes.UInt64.lo(0); }, Error); + do_check_throws(function() { ctypes.UInt64.hi(0); }, Error); // Test ctypes.UInt64.join. do_check_eq(ctypes.UInt64.join(0, 0).toString(), "0"); @@ -1374,8 +1374,8 @@ function run_StructType_tests() { do_check_throws(function() { ctypes.StructType(); }, TypeError); do_check_throws(function() { ctypes.StructType("a", [], 5); }, TypeError); - do_check_throws(function() { ctypes.StructType(null, []); }, TypeError); - do_check_throws(function() { ctypes.StructType("a", null); }, TypeError); + do_check_throws(function() { ctypes.StructType(null, []); }, Error); + do_check_throws(function() { ctypes.StructType("a", null); }, Error); // Check that malformed descriptors are an error. do_check_throws(function() { @@ -1659,9 +1659,9 @@ function run_PointerType_tests() { do_check_throws(function() { ctypes.PointerType(); }, TypeError); do_check_throws(function() { ctypes.PointerType(ctypes.int32_t, 5); }, TypeError); - do_check_throws(function() { ctypes.PointerType(null); }, TypeError); - do_check_throws(function() { ctypes.PointerType(ctypes.int32_t()); }, TypeError); - do_check_throws(function() { ctypes.PointerType("void"); }, TypeError); + do_check_throws(function() { ctypes.PointerType(null); }, Error); + do_check_throws(function() { ctypes.PointerType(ctypes.int32_t()); }, Error); + do_check_throws(function() { ctypes.PointerType("void"); }, Error); let name = "g_t"; let g_t = ctypes.StructType(name, [{ a: ctypes.int32_t }, { b: ctypes.double }]); @@ -1844,10 +1844,10 @@ function run_FunctionType_tests() { }, TypeError); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, ctypes.void_t); - }, TypeError); + }, Error); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, null); - }, TypeError); + }, Error); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t()); }, Error); @@ -1961,9 +1961,9 @@ function run_ArrayType_tests() { [ "elementType", "length" ], [], [ "length" ], [ "addressOfElement" ]); do_check_throws(function() { ctypes.ArrayType(); }, TypeError); - do_check_throws(function() { ctypes.ArrayType(null); }, TypeError); + do_check_throws(function() { ctypes.ArrayType(null); }, Error); do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, 1, 5); }, TypeError); - do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, -1); }, TypeError); + do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, -1); }, Error); let name = "g_t"; let g_t = ctypes.StructType(name, [{ a: ctypes.int32_t }, { b: ctypes.double }]); @@ -2036,7 +2036,7 @@ function run_ArrayType_tests() { } else { do_check_throws(function() { ctypes.ArrayType(ctypes.int8_t, ctypes.UInt64("0xffffffffffffffff")); - }, TypeError); + }, Error); do_check_throws(function() { ctypes.ArrayType(ctypes.int16_t, ctypes.UInt64("0x8000000000000000")); }, Error); From 1c0a8e43350f89db36b94ed1b6a60766d99df01e Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 20:08:21 +0900 Subject: [PATCH 106/241] Backed out changeset 951ec7d134c2 (bug 891107) for xpcshell-test failure --- js/src/ctypes/CTypes.cpp | 159 ++++++++---------- js/src/ctypes/ctypes.msg | 3 - .../tests/ctypes/argument-length-abi.js | 9 - .../tests/ctypes/argument-length-array.js | 15 -- .../tests/ctypes/argument-length-cdata.js | 15 -- .../tests/ctypes/argument-length-ctypes.js | 11 -- .../tests/ctypes/argument-length-finalizer.js | 16 -- .../tests/ctypes/argument-length-function.js | 11 -- .../tests/ctypes/argument-length-int64.js | 36 ---- .../tests/ctypes/argument-length-pointer.js | 11 -- .../tests/ctypes/argument-length-primitive.js | 11 -- .../tests/ctypes/argument-length-struct.js | 17 -- .../ctypes/tests/unit/test_jsctypes.js | 40 ++--- 13 files changed, 91 insertions(+), 263 deletions(-) delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-abi.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-array.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-cdata.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-ctypes.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-finalizer.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-function.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-int64.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-pointer.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-primitive.js delete mode 100644 js/src/jit-test/tests/ctypes/argument-length-struct.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 86ed225c308f..26099d919163 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -1234,15 +1234,6 @@ ArgumentConvError(JSContext* cx, HandleValue actual, const char* funStr, return false; } -static bool -ArgumentLengthError(JSContext* cx, const char* fun, const char* count, - const char* s) -{ - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_WRONG_ARG_LENGTH, fun, count, s); - return false; -} - static bool ArrayLengthMismatch(JSContext* cx, unsigned expectedLength, HandleObject arrObj, unsigned actualLength, HandleValue actual, @@ -3843,7 +3834,8 @@ CType::ConstructBasic(JSContext* cx, const CallArgs& args) { if (args.length() > 1) { - return ArgumentLengthError(cx, "CType constructor", "at most one", ""); + JS_ReportError(cx, "CType constructor takes zero or one argument"); + return false; } // construct a CData object @@ -4365,7 +4357,8 @@ CType::CreateArray(JSContext* cx, unsigned argc, jsval* vp) // Construct and return a new ArrayType object. if (args.length() > 1) { - return ArgumentLengthError(cx, "CType.prototype.array", "at most one", ""); + JS_ReportError(cx, "array takes zero or one argument"); + return false; } // Convert the length argument to a size_t. @@ -4504,7 +4497,8 @@ ABI::ToSource(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - return ArgumentLengthError(cx, "ABI.prototype.toSource", "no", "s"); + JS_ReportError(cx, "toSource takes zero arguments"); + return false; } JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -4548,7 +4542,8 @@ PointerType::Create(JSContext* cx, unsigned argc, jsval* vp) CallArgs args = CallArgsFromVp(argc, vp); // Construct and return a new PointerType object. if (args.length() != 1) { - return ArgumentLengthError(cx, "PointerType", "one", ""); + JS_ReportError(cx, "PointerType takes one argument"); + return false; } jsval arg = args[0]; @@ -4613,8 +4608,8 @@ PointerType::ConstructData(JSContext* cx, } if (args.length() > 3) { - return ArgumentLengthError(cx, "PointerType constructor", "0, 1, 2, or 3", - "s"); + JS_ReportError(cx, "constructor takes 0, 1, 2, or 3 arguments"); + return false; } RootedObject result(cx, CData::Create(cx, obj, NullPtr(), nullptr, true)); @@ -4648,7 +4643,8 @@ PointerType::ConstructData(JSContext* cx, // if (!looksLikeClosure) { if (args.length() != 1) { - return ArgumentLengthError(cx, "FunctionType constructor", "one", ""); + JS_ReportError(cx, "first argument must be a function"); + return false; } return ExplicitConvert(cx, args[0], obj, CData::GetData(result), ConversionType::Construct); @@ -4849,7 +4845,8 @@ ArrayType::Create(JSContext* cx, unsigned argc, jsval* vp) CallArgs args = CallArgsFromVp(argc, vp); // Construct and return a new ArrayType object. if (args.length() < 1 || args.length() > 2) { - return ArgumentLengthError(cx, "ArrayType", "one or two", "s"); + JS_ReportError(cx, "ArrayType takes one or two arguments"); + return false; } if (args[0].isPrimitive() || @@ -4949,14 +4946,14 @@ ArrayType::ConstructData(JSContext* cx, // with a length argument, or with an actual JS array. if (CType::IsSizeDefined(obj)) { if (args.length() > 1) { - return ArgumentLengthError(cx, "size defined ArrayType constructor", - "at most one", ""); + JS_ReportError(cx, "constructor takes zero or one argument"); + return false; } } else { if (args.length() != 1) { - return ArgumentLengthError(cx, "size undefined ArrayType constructor", - "one", ""); + JS_ReportError(cx, "constructor takes one argument"); + return false; } RootedObject baseType(cx, GetBaseType(obj)); @@ -5271,8 +5268,8 @@ ArrayType::AddressOfElement(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 1) { - return ArgumentLengthError(cx, "ArrayType.prototype.addressOfElement", - "one", ""); + JS_ReportError(cx, "addressOfElement takes one argument"); + return false; } RootedObject baseType(cx, GetBaseType(typeObj)); @@ -5392,7 +5389,8 @@ StructType::Create(JSContext* cx, unsigned argc, jsval* vp) // Construct and return a new StructType object. if (args.length() < 1 || args.length() > 2) { - return ArgumentLengthError(cx, "StructType", "one or two", "s"); + JS_ReportError(cx, "StructType takes one or two arguments"); + return false; } jsval name = args[0]; @@ -5686,7 +5684,8 @@ StructType::Define(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 1) { - return ArgumentLengthError(cx, "StructType.prototype.define", "one", ""); + JS_ReportError(cx, "define takes one argument"); + return false; } jsval arg = args[0]; @@ -5773,14 +5772,9 @@ StructType::ConstructData(JSContext* cx, return true; } - size_t count = fields->count(); - if (count >= 2) { - char fieldLengthStr[32]; - JS_snprintf(fieldLengthStr, 32, "0, 1, or %u", count); - return ArgumentLengthError(cx, "StructType constructor", fieldLengthStr, - "s"); - } - return ArgumentLengthError(cx, "StructType constructor", "at most one", ""); + JS_ReportError(cx, "constructor takes 0, 1, or %u arguments", + fields->count()); + return false; } const FieldInfoHash* @@ -5976,8 +5970,8 @@ StructType::AddressOfField(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 1) { - return ArgumentLengthError(cx, "StructType.prototype.addressOfField", - "one", ""); + JS_ReportError(cx, "addressOfField takes one argument"); + return false; } if (!args[0].isString()) { @@ -6321,7 +6315,8 @@ FunctionType::Create(JSContext* cx, unsigned argc, jsval* vp) // Construct and return a new FunctionType object. CallArgs args = CallArgsFromVp(argc, vp); if (args.length() < 2 || args.length() > 3) { - return ArgumentLengthError(cx, "FunctionType", "two or three", "s"); + JS_ReportError(cx, "FunctionType takes two or three arguments"); + return false; } AutoValueVector argTypes(cx); @@ -7166,7 +7161,8 @@ CData::Address(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - return ArgumentLengthError(cx, "CData.prototype.address", "no", "s"); + JS_ReportError(cx, "address takes zero arguments"); + return false; } RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -7200,7 +7196,8 @@ CData::Cast(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { - return ArgumentLengthError(cx, "ctypes.cast", "two", "s"); + JS_ReportError(cx, "cast takes two arguments"); + return false; } if (args[0].isPrimitive() || !CData::IsCData(&args[0].toObject())) { @@ -7240,7 +7237,8 @@ CData::GetRuntime(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { - return ArgumentLengthError(cx, "ctypes.getRuntime", "one", ""); + JS_ReportError(cx, "getRuntime takes one argument"); + return false; } if (args[0].isPrimitive() || !CType::IsCType(&args[0].toObject())) { @@ -7272,11 +7270,8 @@ ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8, unsigned argc, js { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - if (inflateUTF8 == JS::UTF8CharsToNewTwoByteCharsZ) { - return ArgumentLengthError(cx, "CData.prototype.readString", "no", "s"); - } - return ArgumentLengthError(cx, "CData.prototype.readStringReplaceMalformed", - "no", "s"); + JS_ReportError(cx, "readString takes zero arguments"); + return false; } JSObject* obj = CDataFinalizer::GetCData(cx, JS_THIS_OBJECT(cx, vp)); @@ -7391,7 +7386,8 @@ CData::ToSource(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - return ArgumentLengthError(cx, "CData.prototype.toSource", "no", "s"); + JS_ReportError(cx, "toSource takes zero arguments"); + return false; } JSObject* obj = JS_THIS_OBJECT(cx, vp); @@ -7619,7 +7615,8 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) } if (args.length() != 2) { - return ArgumentLengthError(cx, "CDataFinalizer constructor", "two", "s"); + JS_ReportError(cx, "CDataFinalizer takes 2 arguments"); + return false; } JS::HandleValue valCodePtr = args[1]; @@ -7833,8 +7830,8 @@ CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - return ArgumentLengthError(cx, "CDataFinalizer.prototype.forget", "no", - "s"); + JS_ReportError(cx, "CDataFinalizer.prototype.forget takes no arguments"); + return false; } JS::Rooted obj(cx, args.thisv().toObjectOrNull()); @@ -7881,8 +7878,8 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 0) { - return ArgumentLengthError(cx, "CDataFinalizer.prototype.dispose", "no", - "s"); + JS_ReportError(cx, "CDataFinalizer.prototype.dispose takes no arguments"); + return false; } RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); @@ -8055,12 +8052,8 @@ Int64Base::ToString(JSContext* cx, bool isUnsigned) { if (args.length() > 1) { - if (isUnsigned) { - return ArgumentLengthError(cx, "UInt64.prototype.toString", - "at most one", ""); - } - return ArgumentLengthError(cx, "Int64.prototype.toString", - "at most one", ""); + JS_ReportError(cx, "toString takes zero or one argument"); + return false; } int radix = 10; @@ -8096,10 +8089,8 @@ Int64Base::ToSource(JSContext* cx, bool isUnsigned) { if (args.length() != 0) { - if (isUnsigned) { - return ArgumentLengthError(cx, "UInt64.prototype.toSource", "no", "s"); - } - return ArgumentLengthError(cx, "Int64.prototype.toSource", "no", "s"); + JS_ReportError(cx, "toSource takes zero arguments"); + return false; } // Return a decimal string suitable for constructing the number. @@ -8130,7 +8121,8 @@ Int64::Construct(JSContext* cx, // Construct and return a new Int64 object. if (args.length() != 1) { - return ArgumentLengthError(cx, "Int64 constructor", "one", ""); + JS_ReportError(cx, "Int64 takes one argument"); + return false; } int64_t i = 0; @@ -8193,10 +8185,8 @@ bool Int64::Compare(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 2) { - return ArgumentLengthError(cx, "Int64.compare", "two", "s"); - } - if (args[0].isPrimitive() || + if (args.length() != 2 || + args[0].isPrimitive() || args[1].isPrimitive() || !Int64::IsInt64(&args[0].toObject()) || !Int64::IsInt64(&args[1].toObject())) { @@ -8228,10 +8218,8 @@ bool Int64::Lo(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1) { - return ArgumentLengthError(cx, "Int64.lo", "one", ""); - } - if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { + if (args.length() != 1 || args[0].isPrimitive() || + !Int64::IsInt64(&args[0].toObject())) { JS_ReportError(cx, "lo takes one Int64 argument"); return false; } @@ -8248,10 +8236,8 @@ bool Int64::Hi(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1) { - return ArgumentLengthError(cx, "Int64.hi", "one", ""); - } - if (args[0].isPrimitive() || !Int64::IsInt64(&args[0].toObject())) { + if (args.length() != 1 || args[0].isPrimitive() || + !Int64::IsInt64(&args[0].toObject())) { JS_ReportError(cx, "hi takes one Int64 argument"); return false; } @@ -8269,7 +8255,8 @@ Int64::Join(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { - return ArgumentLengthError(cx, "Int64.join", "two", "s"); + JS_ReportError(cx, "join takes two arguments"); + return false; } int32_t hi; @@ -8305,7 +8292,8 @@ UInt64::Construct(JSContext* cx, // Construct and return a new UInt64 object. if (args.length() != 1) { - return ArgumentLengthError(cx, "UInt64 constructor", "one", ""); + JS_ReportError(cx, "UInt64 takes one argument"); + return false; } uint64_t u = 0; @@ -8368,10 +8356,8 @@ bool UInt64::Compare(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 2) { - return ArgumentLengthError(cx, "UInt64.compare", "two", "s"); - } - if (args[0].isPrimitive() || + if (args.length() != 2 || + args[0].isPrimitive() || args[1].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject()) || !UInt64::IsUInt64(&args[1].toObject())) { @@ -8399,10 +8385,8 @@ bool UInt64::Lo(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1) { - return ArgumentLengthError(cx, "UInt64.lo", "one", ""); - } - if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { + if (args.length() != 1 || args[0].isPrimitive() || + !UInt64::IsUInt64(&args[0].toObject())) { JS_ReportError(cx, "lo takes one UInt64 argument"); return false; } @@ -8419,10 +8403,8 @@ bool UInt64::Hi(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1) { - return ArgumentLengthError(cx, "UInt64.hi", "one", ""); - } - if (args[0].isPrimitive() || !UInt64::IsUInt64(&args[0].toObject())) { + if (args.length() != 1 || args[0].isPrimitive() || + !UInt64::IsUInt64(&args[0].toObject())) { JS_ReportError(cx, "hi takes one UInt64 argument"); return false; } @@ -8440,7 +8422,8 @@ UInt64::Join(JSContext* cx, unsigned argc, jsval* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 2) { - return ArgumentLengthError(cx, "UInt64.join", "two", "s"); + JS_ReportError(cx, "join takes two arguments"); + return false; } uint32_t hi; diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg index 84a3884c649a..aa1a709fe0f1 100644 --- a/js/src/ctypes/ctypes.msg +++ b/js/src/ctypes/ctypes.msg @@ -32,6 +32,3 @@ MSG_DEF(CTYPESMSG_PROP_NONSTRING,3, JSEXN_TYPEERR, "property name {0} of {1} is /* data finalizer */ MSG_DEF(CTYPESMSG_EMPTY_FIN, 1, JSEXN_TYPEERR, "attempting to convert an empty CDataFinalizer{0}") MSG_DEF(CTYPESMSG_FIN_SIZE_ERROR,2, JSEXN_TYPEERR, "expected an object with the same size as argument 1 of {0}, got {1}") - -/* native function */ -MSG_DEF(CTYPESMSG_WRONG_ARG_LENGTH,3, JSEXN_TYPEERR, "{0} takes {1} argument{2}") diff --git a/js/src/jit-test/tests/ctypes/argument-length-abi.js b/js/src/jit-test/tests/ctypes/argument-length-abi.js deleted file mode 100644 index a18a8059ed65..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-abi.js +++ /dev/null @@ -1,9 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.default_abi.toSource(1); }, - "ABI.prototype.toSource takes no arguments"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-array.js b/js/src/jit-test/tests/ctypes/argument-length-array.js deleted file mode 100644 index 5afbcc46ebc2..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-array.js +++ /dev/null @@ -1,15 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.ArrayType(); }, - "ArrayType takes one or two arguments"); - assertTypeErrorMessage(() => { ctypes.int32_t.array(10)(1, 2); }, - "size defined ArrayType constructor takes at most one argument"); - assertTypeErrorMessage(() => { ctypes.int32_t.array()(1, 2); }, - "size undefined ArrayType constructor takes one argument"); - assertTypeErrorMessage(() => { ctypes.int32_t.array(10)().addressOfElement(); }, - "ArrayType.prototype.addressOfElement takes one argument"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-cdata.js b/js/src/jit-test/tests/ctypes/argument-length-cdata.js deleted file mode 100644 index 56a1497f4815..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-cdata.js +++ /dev/null @@ -1,15 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.int32_t(0).address(1); }, - "CData.prototype.address takes no arguments"); - assertTypeErrorMessage(() => { ctypes.char.array(10)().readString(1); }, - "CData.prototype.readString takes no arguments"); - assertTypeErrorMessage(() => { ctypes.char.array(10)().readStringReplaceMalformed(1); }, - "CData.prototype.readStringReplaceMalformed takes no arguments"); - assertTypeErrorMessage(() => { ctypes.int32_t(0).toSource(1); }, - "CData.prototype.toSource takes no arguments"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-ctypes.js b/js/src/jit-test/tests/ctypes/argument-length-ctypes.js deleted file mode 100644 index 84b0b9ea54df..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-ctypes.js +++ /dev/null @@ -1,11 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.cast(); }, - "ctypes.cast takes two arguments"); - assertTypeErrorMessage(() => { ctypes.getRuntime(); }, - "ctypes.getRuntime takes one argument"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-finalizer.js b/js/src/jit-test/tests/ctypes/argument-length-finalizer.js deleted file mode 100644 index 70e15bf8f089..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-finalizer.js +++ /dev/null @@ -1,16 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(1); }, - "CDataFinalizer constructor takes two arguments"); - - let fin = ctypes.CDataFinalizer(ctypes.int32_t(0), ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.int32_t]).ptr(x => x)); - assertTypeErrorMessage(() => { fin.forget(1); }, - "CDataFinalizer.prototype.forget takes no arguments"); - assertTypeErrorMessage(() => { fin.dispose(1); }, - "CDataFinalizer.prototype.dispose takes no arguments"); - fin.forget(); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-function.js b/js/src/jit-test/tests/ctypes/argument-length-function.js deleted file mode 100644 index 2d26596620b2..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-function.js +++ /dev/null @@ -1,11 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.FunctionType(); }, - "FunctionType takes two or three arguments"); - assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, []).ptr({}, 1); }, - "FunctionType constructor takes one argument"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-int64.js b/js/src/jit-test/tests/ctypes/argument-length-int64.js deleted file mode 100644 index 888713accf6a..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-int64.js +++ /dev/null @@ -1,36 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.Int64(1).toString(1, 2); }, - "Int64.prototype.toString takes at most one argument"); - assertTypeErrorMessage(() => { ctypes.Int64(1).toSource(1); }, - "Int64.prototype.toSource takes no arguments"); - assertTypeErrorMessage(() => { ctypes.Int64(); }, - "Int64 constructor takes one argument"); - assertTypeErrorMessage(() => { ctypes.Int64.compare(); }, - "Int64.compare takes two arguments"); - assertTypeErrorMessage(() => { ctypes.Int64.lo(); }, - "Int64.lo takes one argument"); - assertTypeErrorMessage(() => { ctypes.Int64.hi(); }, - "Int64.hi takes one argument"); - assertTypeErrorMessage(() => { ctypes.Int64.join(); }, - "Int64.join takes two arguments"); - - assertTypeErrorMessage(() => { ctypes.UInt64(1).toString(1, 2); }, - "UInt64.prototype.toString takes at most one argument"); - assertTypeErrorMessage(() => { ctypes.UInt64(1).toSource(1); }, - "UInt64.prototype.toSource takes no arguments"); - assertTypeErrorMessage(() => { ctypes.UInt64(); }, - "UInt64 constructor takes one argument"); - assertTypeErrorMessage(() => { ctypes.UInt64.compare(); }, - "UInt64.compare takes two arguments"); - assertTypeErrorMessage(() => { ctypes.UInt64.lo(); }, - "UInt64.lo takes one argument"); - assertTypeErrorMessage(() => { ctypes.UInt64.hi(); }, - "UInt64.hi takes one argument"); - assertTypeErrorMessage(() => { ctypes.UInt64.join(); }, - "UInt64.join takes two arguments"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-pointer.js b/js/src/jit-test/tests/ctypes/argument-length-pointer.js deleted file mode 100644 index 8ac404aaf751..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-pointer.js +++ /dev/null @@ -1,11 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.PointerType(); }, - "PointerType takes one argument"); - assertTypeErrorMessage(() => { ctypes.int32_t.ptr(1, 2, 3, 4); }, - "PointerType constructor takes 0, 1, 2, or 3 arguments"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-primitive.js b/js/src/jit-test/tests/ctypes/argument-length-primitive.js deleted file mode 100644 index 161ebd880c5f..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-primitive.js +++ /dev/null @@ -1,11 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.int32_t(1, 2, 3); }, - "CType constructor takes at most one argument"); - assertTypeErrorMessage(() => { ctypes.int32_t.array(1, 2); }, - "CType.prototype.array takes at most one argument"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/argument-length-struct.js b/js/src/jit-test/tests/ctypes/argument-length-struct.js deleted file mode 100644 index 0e8efbb6ab4c..000000000000 --- a/js/src/jit-test/tests/ctypes/argument-length-struct.js +++ /dev/null @@ -1,17 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.StructType(); }, - "StructType takes one or two arguments"); - assertTypeErrorMessage(() => { ctypes.StructType("a").define(); }, - "StructType.prototype.define takes one argument"); - assertTypeErrorMessage(() => { ctypes.StructType("a", [])(1, 2, 3); }, - "StructType constructor takes at most one argument"); - assertTypeErrorMessage(() => { ctypes.StructType("a", [ {"x": ctypes.int32_t }, {"y": ctypes.int32_t }, {"z": ctypes.int32_t }])(1, 2); }, - "StructType constructor takes 0, 1, or 3 arguments"); - assertTypeErrorMessage(() => { ctypes.StructType("a", [ {"x": ctypes.int32_t } ])().addressOfField(); }, - "StructType.prototype.addressOfField takes one argument"); -} - -if (typeof ctypes === "object") - test(); diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index d0323def0ac0..5ddeab5297d5 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -300,7 +300,7 @@ function run_abstract_class_tests() } function run_Int64_tests() { - do_check_throws(function() { ctypes.Int64(); }, TypeError); + do_check_throws(function() { ctypes.Int64(); }, Error); // Test that classes and prototypes are set up correctly. do_check_class(ctypes.Int64, "Function"); @@ -334,11 +334,11 @@ function run_Int64_tests() { do_check_throws(function() { i.toString(0); }, Error); do_check_throws(function() { i.toString(1); }, Error); do_check_throws(function() { i.toString(37); }, Error); - do_check_throws(function() { i.toString(10, 2); }, TypeError); + do_check_throws(function() { i.toString(10, 2); }, Error); // Test Int64.toSource(). do_check_eq(i.toSource(), "ctypes.Int64(\"0\")"); - do_check_throws(function() { i.toSource(10); }, TypeError); + do_check_throws(function() { i.toSource(10); }, Error); i = ctypes.Int64("0x28590a1c921def71"); do_check_eq(i.toString(), i.toString(10)); @@ -471,7 +471,7 @@ function run_Int64_tests() { } function run_UInt64_tests() { - do_check_throws(function() { ctypes.UInt64(); }, TypeError); + do_check_throws(function() { ctypes.UInt64(); }, Error); // Test that classes and prototypes are set up correctly. do_check_class(ctypes.UInt64, "Function"); @@ -505,11 +505,11 @@ function run_UInt64_tests() { do_check_throws(function() { i.toString(0); }, Error); do_check_throws(function() { i.toString(1); }, Error); do_check_throws(function() { i.toString(37); }, Error); - do_check_throws(function() { i.toString(10, 2); }, TypeError); + do_check_throws(function() { i.toString(10, 2); }, Error); // Test UInt64.toSource(). do_check_eq(i.toSource(), "ctypes.UInt64(\"0\")"); - do_check_throws(function() { i.toSource(10); }, TypeError); + do_check_throws(function() { i.toSource(10); }, Error); i = ctypes.UInt64("0x28590a1c921def71"); do_check_eq(i.toString(), i.toString(10)); @@ -1372,8 +1372,8 @@ function run_StructType_tests() { ctypes.StructType("t", [{"c": ctypes.int32_t}, {"d": ctypes.int64_t}]), [ "fields" ], [ "define" ], [], [ "addressOfField" ], [ "a", "b" ]); - do_check_throws(function() { ctypes.StructType(); }, TypeError); - do_check_throws(function() { ctypes.StructType("a", [], 5); }, TypeError); + do_check_throws(function() { ctypes.StructType(); }, Error); + do_check_throws(function() { ctypes.StructType("a", [], 5); }, Error); do_check_throws(function() { ctypes.StructType(null, []); }, Error); do_check_throws(function() { ctypes.StructType("a", null); }, Error); @@ -1424,8 +1424,8 @@ function run_StructType_tests() { }, TypeError); // Check that 'define' works. - do_check_throws(function() { opaque_t.define(); }, TypeError); - do_check_throws(function() { opaque_t.define([], 0); }, TypeError); + do_check_throws(function() { opaque_t.define(); }, Error); + do_check_throws(function() { opaque_t.define([], 0); }, Error); do_check_throws(function() { opaque_t.define([{}]); }, Error); do_check_throws(function() { opaque_t.define([{ a: 0 }]); }, Error); do_check_throws(function() { @@ -1551,7 +1551,7 @@ function run_StructType_tests() { do_check_eq(g.a, 1); do_check_eq(g.b, 2); do_check_throws(function() { g_t(1); }, TypeError); - do_check_throws(function() { g_t(1, 2, 3); }, TypeError); + do_check_throws(function() { g_t(1, 2, 3); }, Error); for (let field in g) do_check_true(field == "a" || field == "b"); @@ -1576,9 +1576,9 @@ function run_StructType_tests() { g_a = s.addressOfField("b"); do_check_true(g_a.constructor === g_t.ptr); do_check_eq(g_a.contents.a, s.b.a); - do_check_throws(function() { s.addressOfField(); }, TypeError); + do_check_throws(function() { s.addressOfField(); }, Error); do_check_throws(function() { s.addressOfField("d"); }, Error); - do_check_throws(function() { s.addressOfField("a", 2); }, TypeError); + do_check_throws(function() { s.addressOfField("a", 2); }, Error); do_check_eq(s.toSource(), "s_t(4, {\"a\": 7, \"b\": 2}, 10)"); do_check_eq(s.toSource(), s.toString()); @@ -1657,8 +1657,8 @@ function run_PointerType_tests() { ctypes.PointerType(ctypes.int32_t), ctypes.PointerType(ctypes.int64_t), [ "targetType" ], [], [ "contents" ], [ "isNull", "increment", "decrement" ], []); - do_check_throws(function() { ctypes.PointerType(); }, TypeError); - do_check_throws(function() { ctypes.PointerType(ctypes.int32_t, 5); }, TypeError); + do_check_throws(function() { ctypes.PointerType(); }, Error); + do_check_throws(function() { ctypes.PointerType(ctypes.int32_t, 5); }, Error); do_check_throws(function() { ctypes.PointerType(null); }, Error); do_check_throws(function() { ctypes.PointerType(ctypes.int32_t()); }, Error); do_check_throws(function() { ctypes.PointerType("void"); }, Error); @@ -1835,13 +1835,13 @@ function run_FunctionType_tests() { [ "abi", "returnType", "argTypes", "isVariadic" ], undefined, undefined, undefined, undefined); - do_check_throws(function() { ctypes.FunctionType(); }, TypeError); + do_check_throws(function() { ctypes.FunctionType(); }, Error); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, [ ctypes.void_t ]); }, Error); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, [ ctypes.void_t ], 5); - }, TypeError); + }, Error); do_check_throws(function() { ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, ctypes.void_t); }, Error); @@ -1960,9 +1960,9 @@ function run_ArrayType_tests() { ctypes.ArrayType(ctypes.int32_t, 10), ctypes.ArrayType(ctypes.int64_t), [ "elementType", "length" ], [], [ "length" ], [ "addressOfElement" ]); - do_check_throws(function() { ctypes.ArrayType(); }, TypeError); + do_check_throws(function() { ctypes.ArrayType(); }, Error); do_check_throws(function() { ctypes.ArrayType(null); }, Error); - do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, 1, 5); }, TypeError); + do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, 1, 5); }, Error); do_check_throws(function() { ctypes.ArrayType(ctypes.int32_t, -1); }, Error); let name = "g_t"; @@ -2011,7 +2011,7 @@ function run_ArrayType_tests() { do_check_eq(a2.constructor.length, 5); do_check_eq(a2.length, 5); do_check_eq(a2.constructor.size, g_t.size * 5); - do_check_throws(function() { new a2_t(); }, TypeError); + do_check_throws(function() { new a2_t(); }, Error); do_check_throws(function() { ctypes.ArrayType(ctypes.ArrayType(g_t)); }, Error); do_check_throws(function() { ctypes.ArrayType(ctypes.ArrayType(g_t), 5); }, Error); From 592070ffda8e7c2cfdcb617c041cb824a4196dc9 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 20:08:23 +0900 Subject: [PATCH 107/241] Backed out changeset b2b956ba0acd (bug 891107) for xpcshell-test failure --- js/src/ctypes/CTypes.cpp | 802 +++--------------- js/src/ctypes/CTypes.h | 28 - js/src/ctypes/Library.cpp | 5 +- js/src/ctypes/ctypes.msg | 22 +- js/src/jit-test/lib/asserts.js | 20 - .../jit-test/tests/ctypes/conversion-array.js | 36 - .../jit-test/tests/ctypes/conversion-error.js | 14 - .../tests/ctypes/conversion-finalizer.js | 61 -- .../tests/ctypes/conversion-function.js | 33 - .../jit-test/tests/ctypes/conversion-int64.js | 20 - .../ctypes/conversion-native-function.js | 37 - .../tests/ctypes/conversion-pointer.js | 29 - .../tests/ctypes/conversion-primitive.js | 44 - .../tests/ctypes/conversion-struct.js | 36 - .../tests/ctypes/conversion-to-primitive.js | 20 - js/src/jsexn.cpp | 40 - js/src/jsexn.h | 3 - .../ctypes/tests/unit/test_jsctypes.js | 36 +- 18 files changed, 124 insertions(+), 1162 deletions(-) delete mode 100644 js/src/jit-test/tests/ctypes/conversion-array.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-error.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-finalizer.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-function.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-int64.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-native-function.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-pointer.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-primitive.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-struct.js delete mode 100644 js/src/jit-test/tests/ctypes/conversion-to-primitive.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 26099d919163..2fe4187fbfb0 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -32,7 +32,6 @@ #endif #include "jscntxt.h" -#include "jsexn.h" #include "jsfun.h" #include "jsnum.h" #include "jsprf.h" @@ -41,8 +40,6 @@ #include "ctypes/Library.h" #include "gc/Zone.h" -#include "jsatominlines.h" - using namespace std; using mozilla::NumericLimits; @@ -879,567 +876,21 @@ GetErrorMessage(void* userRef, const unsigned errorNumber) return nullptr; } -static const char* -EncodeLatin1(JSContext* cx, AutoString& str, JSAutoByteString& bytes) -{ - return bytes.encodeLatin1(cx, NewUCString(cx, str)); -} - -static const char* -CTypesToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes) -{ - if (val.isObject() && - (CType::IsCType(&val.toObject()) || CData::IsCData(&val.toObject()))) { - RootedString str(cx, JS_ValueToSource(cx, val)); - return bytes.encodeLatin1(cx, str); - } - return ValueToSourceForError(cx, val, bytes); -} - -static void -BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj, - HandleString nameStr, unsigned ptrCount, - AutoString& source); - -static void -BuildCStyleTypeSource(JSContext* cx, JSObject* typeObj_, AutoString& source) -{ - RootedObject typeObj(cx, typeObj_); - - MOZ_ASSERT(CType::IsCType(typeObj)); - - switch (CType::GetTypeCode(typeObj)) { -#define BUILD_SOURCE(name, fromType, ffiType) \ - case TYPE_##name: \ - AppendString(source, #name); \ - break; - CTYPES_FOR_EACH_TYPE(BUILD_SOURCE) -#undef BUILD_SOURCE - case TYPE_void_t: - AppendString(source, "void"); - break; - case TYPE_pointer: { - unsigned ptrCount = 0; - TypeCode type; - RootedObject baseTypeObj(cx, typeObj); - do { - baseTypeObj = PointerType::GetBaseType(baseTypeObj); - ptrCount++; - type = CType::GetTypeCode(baseTypeObj); - } while (type == TYPE_pointer || type == TYPE_array); - if (type == TYPE_function) { - BuildCStyleFunctionTypeSource(cx, baseTypeObj, NullPtr(), ptrCount, - source); - break; - } - BuildCStyleTypeSource(cx, baseTypeObj, source); - AppendChars(source, '*', ptrCount); - break; - } - case TYPE_struct: { - RootedString name(cx, CType::GetName(cx, typeObj)); - AppendString(source, "struct "); - AppendString(source, name); - break; - } - case TYPE_function: - BuildCStyleFunctionTypeSource(cx, typeObj, NullPtr(), 0, source); - break; - case TYPE_array: - MOZ_CRASH("TYPE_array shouldn't appear in function type"); - } -} - -static void -BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj, - HandleString nameStr, unsigned ptrCount, - AutoString& source) -{ - MOZ_ASSERT(CType::IsCType(typeObj)); - - FunctionInfo* fninfo = FunctionType::GetFunctionInfo(typeObj); - BuildCStyleTypeSource(cx, fninfo->mReturnType, source); - AppendString(source, " "); - if (nameStr) { - MOZ_ASSERT(ptrCount == 0); - AppendString(source, nameStr); - } else if (ptrCount) { - AppendString(source, "("); - AppendChars(source, '*', ptrCount); - AppendString(source, ")"); - } - AppendString(source, "("); - if (fninfo->mArgTypes.length() > 0) { - for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) { - BuildCStyleTypeSource(cx, fninfo->mArgTypes[i], source); - if (i != fninfo->mArgTypes.length() - 1 || fninfo->mIsVariadic) { - AppendString(source, ", "); - } - } - if (fninfo->mIsVariadic) { - AppendString(source, "..."); - } - } - AppendString(source, ")"); -} - -static void -BuildFunctionTypeSource(JSContext* cx, HandleObject funObj, AutoString& source) -{ - MOZ_ASSERT(CData::IsCData(funObj) || CType::IsCType(funObj)); - - if (CData::IsCData(funObj)) { - jsval slot = JS_GetReservedSlot(funObj, SLOT_REFERENT); - if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) { - slot = JS_GetReservedSlot(funObj, SLOT_FUNNAME); - MOZ_ASSERT(!slot.isUndefined()); - RootedObject typeObj(cx, CData::GetCType(funObj)); - RootedObject baseTypeObj(cx, PointerType::GetBaseType(typeObj)); - RootedString nameStr(cx, slot.toString()); - BuildCStyleFunctionTypeSource(cx, baseTypeObj, nameStr, 0, source); - return; - } - } - - RootedValue funVal(cx, ObjectValue(*funObj)); - RootedString funcStr(cx, JS_ValueToSource(cx, funVal)); - if (!funcStr) { - JS_ClearPendingException(cx); - AppendString(source, "<>"); - return; - } - AppendString(source, funcStr); -} - -enum class ConversionType { - Argument = 0, - Construct, - Finalizer, - Return, - Setter -}; - -static void -BuildConversionPosition(JSContext* cx, ConversionType convType, - HandleObject funObj, unsigned argIndex, - AutoString& source) -{ - switch (convType) { - case ConversionType::Argument: { - MOZ_ASSERT(funObj); - - AppendString(source, " at argument "); - AppendUInt(source, argIndex + 1); - AppendString(source, " of "); - BuildFunctionTypeSource(cx, funObj, source); - break; - } - case ConversionType::Finalizer: - MOZ_ASSERT(funObj); - - AppendString(source, " at argument 1 of "); - BuildFunctionTypeSource(cx, funObj, source); - break; - case ConversionType::Return: - MOZ_ASSERT(funObj); - - AppendString(source, " at the return value of "); - BuildFunctionTypeSource(cx, funObj, source); - break; - default: - MOZ_ASSERT(!funObj); - break; - } -} - -static JSFlatString* -GetFieldName(HandleObject structObj, unsigned fieldIndex) -{ - const FieldInfoHash* fields = StructType::GetFieldInfo(structObj); - for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) { - if (r.front().value().mIndex == fieldIndex) { - return (&r.front())->key(); - } - } - return nullptr; -} - -static void -BuildTypeSource(JSContext* cx, JSObject* typeObj_, bool makeShort, - AutoString& result); - -static bool -ConvError(JSContext* cx, const char* expectedStr, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0, - HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) -{ - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - if (arrObj) { - MOZ_ASSERT(CType::IsCType(arrObj)); - - switch (CType::GetTypeCode(arrObj)) { - case TYPE_array: { - MOZ_ASSERT(!funObj); - - char indexStr[16]; - JS_snprintf(indexStr, 16, "%u", arrIndex); - - AutoString arrSource; - JSAutoByteString arrBytes; - BuildTypeSource(cx, arrObj, true, arrSource); - const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); - if (!arrStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_ARRAY, - valStr, indexStr, arrStr); - break; - } - case TYPE_struct: { - JSFlatString* name = GetFieldName(arrObj, arrIndex); - MOZ_ASSERT(name); - JSAutoByteString nameBytes; - const char* nameStr = nameBytes.encodeLatin1(cx, name); - if (!nameStr) - return false; - - AutoString structSource; - JSAutoByteString structBytes; - BuildTypeSource(cx, arrObj, true, structSource); - const char* structStr = EncodeLatin1(cx, structSource, structBytes); - if (!structStr) - return false; - - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_STRUCT, - valStr, nameStr, expectedStr, structStr, posStr); - break; - } - default: - MOZ_CRASH("invalid arrObj value"); - } - return false; - } - - switch (convType) { - case ConversionType::Argument: { - MOZ_ASSERT(funObj); - - char indexStr[16]; - JS_snprintf(indexStr, 16, "%u", argIndex + 1); - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_ARG, - valStr, indexStr, funStr); - break; - } - case ConversionType::Finalizer: { - MOZ_ASSERT(funObj); - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_FIN, valStr, funStr); - break; - } - case ConversionType::Return: { - MOZ_ASSERT(funObj); - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_RET, valStr, funStr); - break; - } - case ConversionType::Setter: - case ConversionType::Construct: - MOZ_ASSERT(!funObj); - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_SET, valStr, expectedStr); - break; - } - - return false; -} - -static bool -ConvError(JSContext* cx, HandleObject expectedType, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0, - HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) -{ - MOZ_ASSERT(CType::IsCType(expectedType)); - - AutoString expectedSource; - JSAutoByteString expectedBytes; - BuildTypeSource(cx, expectedType, true, expectedSource); - const char* expectedStr = EncodeLatin1(cx, expectedSource, expectedBytes); - if (!expectedStr) - return false; - - return ConvError(cx, expectedStr, actual, convType, funObj, argIndex, - arrObj, arrIndex); -} - -static bool -ArgumentConvError(JSContext* cx, HandleValue actual, const char* funStr, - unsigned argIndex) -{ - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - char indexStr[16]; - JS_snprintf(indexStr, 16, "%u", argIndex + 1); - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_CONV_ERROR_ARG, valStr, indexStr, funStr); - return false; -} - -static bool -ArrayLengthMismatch(JSContext* cx, unsigned expectedLength, HandleObject arrObj, - unsigned actualLength, HandleValue actual, - ConversionType convType) -{ - MOZ_ASSERT(arrObj && CType::IsCType(arrObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - char expectedLengthStr[16]; - JS_snprintf(expectedLengthStr, 16, "%u", expectedLength); - char actualLengthStr[16]; - JS_snprintf(actualLengthStr, 16, "%u", actualLength); - - AutoString arrSource; - JSAutoByteString arrBytes; - BuildTypeSource(cx, arrObj, true, arrSource); - const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); - if (!arrStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_ARRAY_MISMATCH, - valStr, arrStr, expectedLengthStr, actualLengthStr); - return false; -} - -static bool -ArrayLengthOverflow(JSContext* cx, unsigned expectedLength, HandleObject arrObj, - unsigned actualLength, HandleValue actual, - ConversionType convType) -{ - MOZ_ASSERT(arrObj && CType::IsCType(arrObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - char expectedLengthStr[16]; - JS_snprintf(expectedLengthStr, 16, "%u", expectedLength); - char actualLengthStr[16]; - JS_snprintf(actualLengthStr, 16, "%u", actualLength); - - AutoString arrSource; - JSAutoByteString arrBytes; - BuildTypeSource(cx, arrObj, true, arrSource); - const char* arrStr = EncodeLatin1(cx, arrSource, arrBytes); - if (!arrStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_ARRAY_OVERFLOW, - valStr, arrStr, expectedLengthStr, actualLengthStr); - return false; -} - -static bool -EmptyFinalizerError(JSContext* cx, ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0) -{ - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_EMPTY_FIN, posStr); - return false; -} - -static bool -FieldCountMismatch(JSContext* cx, - unsigned expectedCount, HandleObject structObj, - unsigned actualCount, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0) -{ - MOZ_ASSERT(structObj && CType::IsCType(structObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - AutoString structSource; - JSAutoByteString structBytes; - BuildTypeSource(cx, structObj, true, structSource); - const char* structStr = EncodeLatin1(cx, structSource, structBytes); - if (!structStr) - return false; - - char expectedCountStr[16]; - JS_snprintf(expectedCountStr, 16, "%u", expectedCount); - char actualCountStr[16]; - JS_snprintf(actualCountStr, 16, "%u", actualCount); - - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_FIELD_MISMATCH, - valStr, structStr, expectedCountStr, actualCountStr, - posStr); - return false; -} - -static bool -FinalizerSizeError(JSContext* cx, HandleObject funObj, HandleValue actual) -{ - MOZ_ASSERT(CType::IsCType(funObj)); - - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - AutoString funSource; - JSAutoByteString funBytes; - BuildFunctionTypeSource(cx, funObj, funSource); - const char* funStr = EncodeLatin1(cx, funSource, funBytes); - if (!funStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_FIN_SIZE_ERROR, funStr, valStr); - return false; -} - -static bool -NonPrimitiveError(JSContext* cx, HandleObject typeObj) -{ - MOZ_ASSERT(CType::IsCType(typeObj)); - - AutoString typeSource; - JSAutoByteString typeBytes; - BuildTypeSource(cx, typeObj, true, typeSource); - const char* typeStr = EncodeLatin1(cx, typeSource, typeBytes); - if (!typeStr) - return false; - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_NON_PRIMITIVE, typeStr); - return false; -} - -static bool -PropNameNonStringError(JSContext* cx, HandleId id, HandleValue actual, - ConversionType convType, - HandleObject funObj = NullPtr(), unsigned argIndex = 0) -{ - JSAutoByteString valBytes; - const char* valStr = CTypesToSourceForError(cx, actual, valBytes); - if (!valStr) - return false; - - JSAutoByteString idBytes; - RootedValue idVal(cx, IdToValue(id)); - const char* propStr = CTypesToSourceForError(cx, idVal, idBytes); - if (!propStr) - return false; - - JSAutoByteString posBytes; - const char* posStr; - if (funObj) { - AutoString posSource; - BuildConversionPosition(cx, convType, funObj, argIndex, posSource); - posStr = EncodeLatin1(cx, posSource, posBytes); - if (!posStr) - return false; - } else { - posStr = ""; - } - - JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, - CTYPESMSG_PROP_NONSTRING, propStr, valStr, posStr); - return false; -} - static bool TypeError(JSContext* cx, const char* expected, HandleValue actual) { + JSString* str = JS_ValueToSource(cx, actual); JSAutoByteString bytes; - const char* src = CTypesToSourceForError(cx, actual, bytes); - if (!src) - return false; + const char* src; + if (str) { + src = bytes.encodeLatin1(cx, str); + if (!src) + return false; + } else { + JS_ClearPendingException(cx); + src = "<>"; + } JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, CTYPESMSG_TYPE_ERROR, expected, src); return false; @@ -2759,7 +2210,8 @@ ConvertToJS(JSContext* cx, // We're about to create a new CData object to return. If the caller doesn't // want this, return early. if (wantPrimitive) { - return NonPrimitiveError(cx, typeObj); + JS_ReportError(cx, "cannot convert to primitive value"); + return false; } JSObject* obj = CData::Create(cx, typeObj, parentObj, data, ownResult); @@ -2824,20 +2276,18 @@ bool CanConvertTypedArrayItemTo(JSObject* baseType, JSObject* valObj, JSContext* // coercion between types. There are two cases in which this function is used: // 1) The target buffer is internal to a CData object; we simply write data // into it. -// 2) We are converting an argument for an ffi call, in which case 'convType' -// will be 'ConversionType::Argument'. This allows us to handle a special -// case: if necessary, we can autoconvert a JS string primitive to a -// pointer-to-character type. In this case, ownership of the allocated string -// is handed off to the caller; 'freePointer' will be set to indicate this. +// 2) We are converting an argument for an ffi call, in which case 'isArgument' +// will be true. This allows us to handle a special case: if necessary, +// we can autoconvert a JS string primitive to a pointer-to-character type. +// In this case, ownership of the allocated string is handed off to the +// caller; 'freePointer' will be set to indicate this. static bool ImplicitConvert(JSContext* cx, HandleValue val, JSObject* targetType_, void* buffer, - ConversionType convType, - bool* freePointer, - HandleObject funObj = NullPtr(), unsigned argIndex = 0, - HandleObject arrObj = NullPtr(), unsigned arrIndex = 0) + bool isArgument, + bool* freePointer) { RootedObject targetType(cx, targetType_); MOZ_ASSERT(CType::IsSizeDefined(targetType)); @@ -2869,7 +2319,8 @@ ImplicitConvert(JSContext* cx, if (!p) { // We have called |dispose| or |forget| already. - return EmptyFinalizerError(cx, convType, funObj, argIndex); + JS_ReportError(cx, "Attempting to convert an empty CDataFinalizer"); + return false; } // If the types are equal, copy the buffer contained within the CData. @@ -2888,8 +2339,7 @@ ImplicitConvert(JSContext* cx, // Programs can convert explicitly, if needed, using `Boolean(v)` or `!!v`. bool result; if (!jsvalToBool(cx, val, &result)) - return ConvError(cx, "boolean", val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "boolean", val); *static_cast(buffer) = result; break; } @@ -2901,15 +2351,13 @@ ImplicitConvert(JSContext* cx, if (val.isString()) { \ JSString* str = val.toString(); \ if (str->length() != 1) \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ JSLinearString* linear = str->ensureLinear(cx); \ if (!linear) \ return false; \ result = linear->latin1OrTwoByteChar(0); \ } else if (!jsvalToInteger(cx, val, &result)) { \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ } \ *static_cast(buffer) = result; \ break; \ @@ -2921,8 +2369,7 @@ ImplicitConvert(JSContext* cx, /* Do not implicitly lose bits. */ \ type result; \ if (!jsvalToInteger(cx, val, &result)) \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ *static_cast(buffer) = result; \ break; \ } @@ -2938,8 +2385,7 @@ ImplicitConvert(JSContext* cx, case TYPE_##name: { \ type result; \ if (!jsvalToFloat(cx, val, &result)) \ - return ConvError(cx, #name, val, convType, funObj, argIndex, \ - arrObj, arrIndex); \ + return TypeError(cx, #name, val); \ *static_cast(buffer) = result; \ break; \ } @@ -2974,7 +2420,7 @@ ImplicitConvert(JSContext* cx, } } - } else if (convType == ConversionType::Argument && val.isString()) { + } else if (isArgument && val.isString()) { // Convert the string for the ffi call. This requires allocating space // which the caller assumes ownership of. // TODO: Extend this so we can safely convert strings at other times also. @@ -3028,8 +2474,7 @@ ImplicitConvert(JSContext* cx, break; } default: - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "string pointer", val); } break; } else if (val.isObject() && JS_IsArrayBufferObject(valObj)) { @@ -3037,9 +2482,8 @@ ImplicitConvert(JSContext* cx, // when converting an argument to a function call, as it is possible for // the pointer to be invalidated by anything that runs JS code. (It is // invalid to invoke JS code from a ctypes function call.) - if (convType != ConversionType::Argument) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + if (!isArgument) { + return TypeError(cx, "arraybuffer pointer", val); } void* ptr; { @@ -3047,8 +2491,7 @@ ImplicitConvert(JSContext* cx, ptr = JS_GetArrayBufferData(valObj, nogc); } if (!ptr) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "arraybuffer pointer", val); } *static_cast(buffer) = ptr; break; @@ -3056,12 +2499,10 @@ ImplicitConvert(JSContext* cx, // Same as ArrayBuffer, above, though note that this will take the // offset of the view into account. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "typed array with the appropriate type", val); } - if (convType != ConversionType::Argument) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + if (!isArgument) { + return TypeError(cx, "typed array pointer", val); } void* ptr; { @@ -3069,18 +2510,14 @@ ImplicitConvert(JSContext* cx, ptr = JS_GetArrayBufferViewData(valObj, nogc); } if (!ptr) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "typed array pointer", val); } *static_cast(buffer) = ptr; break; } - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "pointer", val); } case TYPE_array: { - MOZ_ASSERT(!funObj); - RootedObject baseType(cx, ArrayType::GetBaseType(targetType)); size_t targetLength = ArrayType::GetLength(targetType); @@ -3102,9 +2539,8 @@ ImplicitConvert(JSContext* cx, return false; if (targetLength < nbytes) { - MOZ_ASSERT(!funObj); - return ArrayLengthOverflow(cx, targetLength, targetType, nbytes, val, - convType); + JS_ReportError(cx, "ArrayType has insufficient length"); + return false; } char* charBuffer = static_cast(buffer); @@ -3120,9 +2556,8 @@ ImplicitConvert(JSContext* cx, // Copy the string data, char16_t for char16_t, including the terminator // if there's space. if (targetLength < sourceLength) { - MOZ_ASSERT(!funObj); - return ArrayLengthOverflow(cx, targetLength, targetType, - sourceLength, val, convType); + JS_ReportError(cx, "ArrayType has insufficient length"); + return false; } char16_t* dest = static_cast(buffer); @@ -3140,8 +2575,7 @@ ImplicitConvert(JSContext* cx, break; } default: - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "array", val); } } else if (val.isObject() && JS_IsArrayObject(cx, valObj)) { @@ -3149,9 +2583,8 @@ ImplicitConvert(JSContext* cx, uint32_t sourceLength; if (!JS_GetArrayLength(cx, valObj, &sourceLength) || targetLength != size_t(sourceLength)) { - MOZ_ASSERT(!funObj); - return ArrayLengthMismatch(cx, targetLength, targetType, - size_t(sourceLength), val, convType); + JS_ReportError(cx, "ArrayType length does not match source array length"); + return false; } // Convert into an intermediate, in case of failure. @@ -3169,8 +2602,7 @@ ImplicitConvert(JSContext* cx, return false; char* data = intermediate.get() + elementSize * i; - if (!ImplicitConvert(cx, item, baseType, data, convType, nullptr, - funObj, argIndex, targetType, i)) + if (!ImplicitConvert(cx, item, baseType, data, false, nullptr)) return false; } @@ -3183,9 +2615,8 @@ ImplicitConvert(JSContext* cx, size_t elementSize = CType::GetSize(baseType); size_t arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { - MOZ_ASSERT(!funObj); - return ArrayLengthMismatch(cx, arraySize, targetType, - size_t(sourceLength), val, convType); + JS_ReportError(cx, "ArrayType length does not match source ArrayBuffer length"); + return false; } JS::AutoCheckCannotGC nogc; memcpy(buffer, JS_GetArrayBufferData(valObj, nogc), sourceLength); @@ -3194,17 +2625,15 @@ ImplicitConvert(JSContext* cx, // Check that array is consistent with type, then // copy the array. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "typed array with the appropriate type", val); } uint32_t sourceLength = JS_GetTypedArrayByteLength(valObj); size_t elementSize = CType::GetSize(baseType); size_t arraySize = elementSize * targetLength; if (arraySize != size_t(sourceLength)) { - MOZ_ASSERT(!funObj); - return ArrayLengthMismatch(cx, arraySize, targetType, - size_t(sourceLength), val, convType); + JS_ReportError(cx, "typed array length does not match source TypedArray length"); + return false; } JS::AutoCheckCannotGC nogc; memcpy(buffer, JS_GetArrayBufferViewData(valObj, nogc), sourceLength); @@ -3212,8 +2641,7 @@ ImplicitConvert(JSContext* cx, } else { // Don't implicitly convert to string. Users can implicitly convert // with `String(x)` or `""+x`. - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "array", val); } break; } @@ -3235,9 +2663,8 @@ ImplicitConvert(JSContext* cx, const FieldInfoHash* fields = StructType::GetFieldInfo(targetType); if (props.length() != fields->count()) { - return FieldCountMismatch(cx, fields->count(), targetType, - props.length(), val, convType, - funObj, argIndex); + JS_ReportError(cx, "missing fields"); + return false; } RootedId id(cx); @@ -3245,8 +2672,8 @@ ImplicitConvert(JSContext* cx, id = props[i]; if (!JSID_IS_STRING(id)) { - return PropNameNonStringError(cx, id, val, convType, - funObj, argIndex); + JS_ReportError(cx, "property name is not a string"); + return false; } JSFlatString* name = JSID_TO_FLAT_STRING(id); @@ -3260,8 +2687,7 @@ ImplicitConvert(JSContext* cx, // Convert the field via ImplicitConvert(). char* fieldData = intermediate.get() + field->mOffset; - if (!ImplicitConvert(cx, prop, field->mType, fieldData, convType, - nullptr, funObj, argIndex, targetType, i)) + if (!ImplicitConvert(cx, prop, field->mType, fieldData, false, nullptr)) return false; } @@ -3269,8 +2695,7 @@ ImplicitConvert(JSContext* cx, break; } - return ConvError(cx, targetType, val, convType, funObj, argIndex, - arrObj, arrIndex); + return TypeError(cx, "struct", val); } case TYPE_void_t: case TYPE_function: @@ -3284,11 +2709,10 @@ ImplicitConvert(JSContext* cx, // storing the result in 'buffer'. This function is more forceful than // ImplicitConvert. static bool -ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, - void* buffer, ConversionType convType) +ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, void* buffer) { // If ImplicitConvert succeeds, use that result. - if (ImplicitConvert(cx, val, targetType, buffer, convType, nullptr)) + if (ImplicitConvert(cx, val, targetType, buffer, false, nullptr)) return true; // If ImplicitConvert failed, and there is no pending exception, then assume @@ -3317,7 +2741,7 @@ ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, if (!jsvalToIntegerExplicit(val, &result) && \ (!val.isString() || \ !StringToInteger(cx, val.toString(), &result))) \ - return ConvError(cx, #name, val, convType); \ + return TypeError(cx, #name, val); \ *static_cast(buffer) = result; \ break; \ } @@ -3330,7 +2754,7 @@ ExplicitConvert(JSContext* cx, HandleValue val, HandleObject targetType, // Convert a number, Int64 object, or UInt64 object to a pointer. uintptr_t result; if (!jsvalToPtrExplicit(cx, val, &result)) - return ConvError(cx, targetType, val, convType); + return TypeError(cx, "pointer", val); *static_cast(buffer) = result; break; } @@ -3844,8 +3268,7 @@ CType::ConstructBasic(JSContext* cx, return false; if (args.length() == 1) { - if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result), - ConversionType::Construct)) + if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result))) return false; } @@ -4646,8 +4069,7 @@ PointerType::ConstructData(JSContext* cx, JS_ReportError(cx, "first argument must be a function"); return false; } - return ExplicitConvert(cx, args[0], obj, CData::GetData(result), - ConversionType::Construct); + return ExplicitConvert(cx, args[0], obj, CData::GetData(result)); } // @@ -4831,8 +4253,7 @@ PointerType::ContentsSetter(JSContext* cx, JS::CallArgs args) } args.rval().setUndefined(); - return ImplicitConvert(cx, args.get(0), baseType, data, - ConversionType::Setter, nullptr); + return ImplicitConvert(cx, args.get(0), baseType, data, false, nullptr); } /******************************************************************************* @@ -4999,7 +4420,7 @@ ArrayType::ConstructData(JSContext* cx, length = sourceLength + 1; break; default: - return ConvError(cx, obj, args[0], ConversionType::Construct); + return TypeError(cx, "array", args[0]); } } else { @@ -5020,8 +4441,7 @@ ArrayType::ConstructData(JSContext* cx, args.rval().setObject(*result); if (convertObject) { - if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result), - ConversionType::Construct)) + if (!ExplicitConvert(cx, args[0], obj, CData::GetData(result))) return false; } @@ -5191,8 +4611,7 @@ ArrayType::Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle size_t length = GetLength(typeObj); bool ok = jsidToSize(cx, idval, true, &index); int32_t dummy; - if (!ok && JSID_IS_STRING(idval) && - !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { + if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { // String either isn't a number, or doesn't fit in size_t. // Chances are it's a regular property lookup, so return. return true; @@ -5220,7 +4639,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle // Bail early if we're not an ArrayType. (This setter is present for all // CData, regardless of CType.) - RootedObject typeObj(cx, CData::GetCType(obj)); + JSObject* typeObj = CData::GetCType(obj); if (CType::GetTypeCode(typeObj) != TYPE_array) return result.succeed(); @@ -5229,8 +4648,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle size_t length = GetLength(typeObj); bool ok = jsidToSize(cx, idval, true, &index); int32_t dummy; - if (!ok && JSID_IS_STRING(idval) && - !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { + if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) { // String either isn't a number, or doesn't fit in size_t. // Chances are it's a regular property lookup, so return. return result.succeed(); @@ -5240,11 +4658,10 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle return false; } - RootedObject baseType(cx, GetBaseType(typeObj)); + JSObject* baseType = GetBaseType(typeObj); size_t elementSize = CType::GetSize(baseType); char* data = static_cast(CData::GetData(obj)) + elementSize * index; - if (!ImplicitConvert(cx, vp, baseType, data, ConversionType::Setter, - nullptr, NullPtr(), 0, typeObj, index)) + if (!ImplicitConvert(cx, vp, baseType, data, false, nullptr)) return false; return result.succeed(); } @@ -5739,7 +5156,7 @@ StructType::ConstructData(JSContext* cx, // are mutually exclusive, so we can pick the right one. // Try option 1) first. - if (ExplicitConvert(cx, args[0], obj, buffer, ConversionType::Construct)) + if (ExplicitConvert(cx, args[0], obj, buffer)) return true; if (fields->count() != 1) @@ -5764,8 +5181,8 @@ StructType::ConstructData(JSContext* cx, const FieldInfo& field = r.front().value(); STATIC_ASSUME(field.mIndex < fields->count()); /* Quantified invariant */ if (!ImplicitConvert(cx, args[field.mIndex], field.mType, - buffer + field.mOffset, ConversionType::Construct, - nullptr, NullPtr(), 0, obj, field.mIndex)) + buffer + field.mOffset, + false, nullptr)) return false; } @@ -5929,7 +5346,7 @@ StructType::FieldSetter(JSContext* cx, unsigned argc, Value* vp) return false; } - RootedObject typeObj(cx, CData::GetCType(obj)); + JSObject* typeObj = CData::GetCType(obj); if (CType::GetTypeCode(typeObj) != TYPE_struct) { JS_ReportError(cx, "not a StructType"); return false; @@ -5947,8 +5364,7 @@ StructType::FieldSetter(JSContext* cx, unsigned argc, Value* vp) args.rval().setUndefined(); char* data = static_cast(CData::GetData(obj)) + field->mOffset; - return ImplicitConvert(cx, args.get(0), field->mType, data, ConversionType::Setter, nullptr, - NullPtr(), 0, typeObj, field->mIndex); + return ImplicitConvert(cx, args.get(0), field->mType, data, false, nullptr); } bool @@ -6434,8 +5850,6 @@ typedef Array AutoValueAutoArray; static bool ConvertArgument(JSContext* cx, - HandleObject funObj, - unsigned argIndex, HandleValue arg, JSObject* type, AutoValue* value, @@ -6447,9 +5861,7 @@ ConvertArgument(JSContext* cx, } bool freePointer = false; - if (!ImplicitConvert(cx, arg, type, value->mData, - ConversionType::Argument, &freePointer, - funObj, argIndex)) + if (!ImplicitConvert(cx, arg, type, value->mData, true, &freePointer)) return false; if (freePointer) { @@ -6518,8 +5930,7 @@ FunctionType::Call(JSContext* cx, } for (unsigned i = 0; i < argcFixed; ++i) - if (!ConvertArgument(cx, obj, i, args[i], fninfo->mArgTypes[i], - &values[i], &strings)) + if (!ConvertArgument(cx, args[i], fninfo->mArgTypes[i], &values[i], &strings)) return false; if (fninfo->mIsVariadic) { @@ -6544,7 +5955,7 @@ FunctionType::Call(JSContext* cx, !(type = PrepareType(cx, OBJECT_TO_JSVAL(type))) || // Relying on ImplicitConvert only for the limited purpose of // converting one CType to another (e.g., T[] to T*). - !ConvertArgument(cx, obj, i, args[i], type, &values[i], &strings) || + !ConvertArgument(cx, args[i], type, &values[i], &strings) || !(fninfo->mFFITypes[i] = CType::GetFFIType(cx, type))) { // These functions report their own errors. return false; @@ -6770,8 +6181,7 @@ CClosure::Create(JSContext* cx, return nullptr; // Do the value conversion. This might fail, in which case we throw. - if (!ImplicitConvert(cx, errVal, fninfo->mReturnType, errResult.get(), - ConversionType::Return, nullptr, typeObj)) + if (!ImplicitConvert(cx, errVal, fninfo->mReturnType, errResult.get(), false, nullptr)) return nullptr; } @@ -6918,14 +6328,14 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData) RootedValue rval(cx); bool success = JS_CallFunctionValue(cx, thisObj, jsfnVal, argv, &rval); - // Convert the result. Note that we pass 'ConversionType::Return', such that + // Convert the result. Note that we pass 'isArgument = false', such that // ImplicitConvert will *not* autoconvert a JS string into a pointer-to-char // type, which would require an allocation that we can't track. The JS // function must perform this conversion itself and return a PointerType // CData; thusly, the burden of freeing the data is left to the user. if (success && cif->rtype != &ffi_type_void) - success = ImplicitConvert(cx, rval, fninfo->mReturnType, result, - ConversionType::Return, nullptr, typeObj); + success = ImplicitConvert(cx, rval, fninfo->mReturnType, result, false, + nullptr); if (!success) { // Something failed. The callee may have thrown, or it may not have @@ -7152,8 +6562,7 @@ CData::ValueSetter(JSContext* cx, JS::CallArgs args) { RootedObject obj(cx, &args.thisv().toObject()); args.rval().setUndefined(); - return ImplicitConvert(cx, args.get(0), GetCType(obj), GetData(obj), - ConversionType::Setter, nullptr); + return ImplicitConvert(cx, args.get(0), GetCType(obj), GetData(obj), false, nullptr); } bool @@ -7641,7 +7050,7 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) TypeCode typCodePtr = CType::GetTypeCode(objCodePtrType); if (typCodePtr != TYPE_pointer) { return TypeError(cx, "a CData object of a function _pointer_ type", - valCodePtr); + valCodePtrType); } JSObject* objCodeType = PointerType::GetBaseType(objCodePtrType); @@ -7650,12 +7059,12 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) TypeCode typCode = CType::GetTypeCode(objCodeType); if (typCode != TYPE_function) { return TypeError(cx, "a CData object of a _function_ pointer type", - valCodePtr); + valCodePtrType); } uintptr_t code = *reinterpret_cast(CData::GetData(objCodePtr)); if (!code) { return TypeError(cx, "a CData object of a _non-NULL_ function pointer type", - valCodePtr); + valCodePtrType); } FunctionInfo* funInfoFinalizer = @@ -7681,17 +7090,16 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) size_t sizeArg; RootedValue valData(cx, args[0]); if (!CType::GetSafeSize(objArgType, &sizeArg)) { - RootedValue valCodeType(cx, ObjectValue(*objCodeType)); - return TypeError(cx, "a function with one known size argument", - valCodeType); + return TypeError(cx, "(an object with known size)", valData); } ScopedJSFreePtr cargs(malloc(sizeArg)); if (!ImplicitConvert(cx, valData, objArgType, cargs.get(), - ConversionType::Finalizer, &freePointer, - objCodePtrType, 0)) { - return false; + false, &freePointer)) { + RootedValue valArgType(cx, ObjectValue(*objArgType)); + return TypeError(cx, "(an object that can be converted to the following type)", + valArgType); } if (freePointer) { // Note: We could handle that case, if necessary. @@ -7727,7 +7135,7 @@ CDataFinalizer::Construct(JSContext* cx, unsigned argc, jsval* vp) MOZ_CRASH("object with unknown size"); } if (sizeBestArg != sizeArg) { - return FinalizerSizeError(cx, objCodePtrType, valData); + return TypeError(cx, "(an object with the same size as that expected by the C finalization function)", valData); } } } @@ -7838,8 +7246,8 @@ CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval* vp) if (!obj) return false; if (!CDataFinalizer::IsCDataFinalizer(obj)) { - JS_ReportError(cx, "not a CDataFinalizer"); - return false; + RootedValue val(cx, ObjectValue(*obj)); + return TypeError(cx, "a CDataFinalizer", val); } CDataFinalizer::Private* p = (CDataFinalizer::Private*) @@ -7886,8 +7294,8 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval* vp) if (!obj) return false; if (!CDataFinalizer::IsCDataFinalizer(obj)) { - JS_ReportError(cx, "not a CDataFinalizer"); - return false; + RootedValue val(cx, ObjectValue(*obj)); + return TypeError(cx, "a CDataFinalizer", val); } CDataFinalizer::Private* p = (CDataFinalizer::Private*) @@ -8126,9 +7534,8 @@ Int64::Construct(JSContext* cx, } int64_t i = 0; - if (!jsvalToBigInteger(cx, args[0], true, &i)) { - return ArgumentConvError(cx, args[0], "Int64", 0); - } + if (!jsvalToBigInteger(cx, args[0], true, &i)) + return TypeError(cx, "int64", args[0]); // Get ctypes.Int64.prototype from the 'prototype' property of the ctor. RootedValue slot(cx); @@ -8262,9 +7669,9 @@ Int64::Join(JSContext* cx, unsigned argc, jsval* vp) int32_t hi; uint32_t lo; if (!jsvalToInteger(cx, args[0], &hi)) - return ArgumentConvError(cx, args[0], "Int64.join", 0); + return TypeError(cx, "int32", args[0]); if (!jsvalToInteger(cx, args[1], &lo)) - return ArgumentConvError(cx, args[1], "Int64.join", 1); + return TypeError(cx, "uint32", args[1]); int64_t i = (int64_t(hi) << 32) + int64_t(lo); @@ -8297,9 +7704,8 @@ UInt64::Construct(JSContext* cx, } uint64_t u = 0; - if (!jsvalToBigInteger(cx, args[0], true, &u)) { - return ArgumentConvError(cx, args[0], "UInt64", 0); - } + if (!jsvalToBigInteger(cx, args[0], true, &u)) + return TypeError(cx, "uint64", args[0]); // Get ctypes.UInt64.prototype from the 'prototype' property of the ctor. RootedValue slot(cx); @@ -8429,9 +7835,9 @@ UInt64::Join(JSContext* cx, unsigned argc, jsval* vp) uint32_t hi; uint32_t lo; if (!jsvalToInteger(cx, args[0], &hi)) - return ArgumentConvError(cx, args[0], "UInt64.join", 0); + return TypeError(cx, "uint32_t", args[0]); if (!jsvalToInteger(cx, args[1], &lo)) - return ArgumentConvError(cx, args[1], "UInt64.join", 1); + return TypeError(cx, "uint32_t", args[1]); uint64_t u = (uint64_t(hi) << 32) + uint64_t(lo); diff --git a/js/src/ctypes/CTypes.h b/js/src/ctypes/CTypes.h index 7c6c971e0765..40e9fb0bbf40 100644 --- a/js/src/ctypes/CTypes.h +++ b/js/src/ctypes/CTypes.h @@ -10,7 +10,6 @@ #include "ffi.h" #include "jsalloc.h" -#include "jsprf.h" #include "prlink.h" #include "ctypes/typedefs.h" @@ -54,32 +53,6 @@ AppendString(Vector& v, const char (&array)[ArrayLength]) v[i + vlen] = array[i]; } -template -void -AppendChars(Vector& v, const char c, size_t count) -{ - size_t vlen = v.length(); - if (!v.resize(vlen + count)) - return; - - for (size_t i = 0; i < count; ++i) - v[i + vlen] = c; -} - -template -void -AppendUInt(Vector& v, unsigned n) -{ - char array[16]; - size_t alen = JS_snprintf(array, 16, "%u", n); - size_t vlen = v.length(); - if (!v.resize(vlen + alen)) - return; - - for (size_t i = 0; i < alen; ++i) - v[i + vlen] = array[i]; -} - template void AppendString(Vector& v, Vector& w) @@ -402,7 +375,6 @@ enum CDataSlot { SLOT_REFERENT = 1, // JSObject this object must keep alive, if any SLOT_DATA = 2, // pointer to a buffer containing the binary data SLOT_OWNS = 3, // JSVAL_TRUE if this CData owns its own buffer - SLOT_FUNNAME = 4, // JSString representing the function name CDATA_SLOTS }; diff --git a/js/src/ctypes/Library.cpp b/js/src/ctypes/Library.cpp index 688c8a03d836..80a2d2d7321f 100644 --- a/js/src/ctypes/Library.cpp +++ b/js/src/ctypes/Library.cpp @@ -321,7 +321,7 @@ Library::Declare(JSContext* cx, unsigned argc, jsval* vp) void* data; PRFuncPtr fnptr; - RootedString nameStr(cx, args[0].toString()); + JSString* nameStr = args[0].toString(); AutoCString symbol; if (isFunction) { // Build the symbol, with mangling if necessary. @@ -352,9 +352,6 @@ Library::Declare(JSContext* cx, unsigned argc, jsval* vp) if (!result) return false; - if (isFunction) - JS_SetReservedSlot(result, SLOT_FUNNAME, StringValue(nameStr)); - args.rval().setObject(*result); // Seal the CData object, to prevent modification of the function pointer. diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg index aa1a709fe0f1..7178fcb26b3b 100644 --- a/js/src/ctypes/ctypes.msg +++ b/js/src/ctypes/ctypes.msg @@ -10,25 +10,5 @@ */ MSG_DEF(CTYPESMSG_PLACEHOLDER_0, 0, JSEXN_NONE, NULL) +MSG_DEF(CTYPESMSG_TYPE_ERROR, 2, JSEXN_TYPEERR, "expected type {0}, got {1}") -/* type conversion */ -MSG_DEF(CTYPESMSG_CONV_ERROR_ARG,3, JSEXN_TYPEERR, "can't pass {0} to argument {1} of {2}") -MSG_DEF(CTYPESMSG_CONV_ERROR_ARRAY,3, JSEXN_TYPEERR, "can't convert {0} to element {1} of the type {2}") -MSG_DEF(CTYPESMSG_CONV_ERROR_FIN,2, JSEXN_TYPEERR, "can't convert {0} to the type of argument 1 of {1}") -MSG_DEF(CTYPESMSG_CONV_ERROR_RET,2, JSEXN_TYPEERR, "can't convert {0} to the return type of {1}") -MSG_DEF(CTYPESMSG_CONV_ERROR_SET,2, JSEXN_TYPEERR, "can't convert {0} to the type {1}") -MSG_DEF(CTYPESMSG_CONV_ERROR_STRUCT,5, JSEXN_TYPEERR, "can't convert {0} to the '{1}' field ({2}) of {3}{4}") -MSG_DEF(CTYPESMSG_NON_PRIMITIVE, 1, JSEXN_TYPEERR, ".value only works on character and numeric types, not `{0}`") -MSG_DEF(CTYPESMSG_TYPE_ERROR, 2, JSEXN_TYPEERR, "expected {0}, got {1}") - -/* array */ -MSG_DEF(CTYPESMSG_ARRAY_MISMATCH,4, JSEXN_TYPEERR, "length of {0} does not match to the length of the type {1} (expected {2}, got {3})") -MSG_DEF(CTYPESMSG_ARRAY_OVERFLOW,4, JSEXN_TYPEERR, "length of {0} does not fit to the length of the type {1} (expected {2} or lower, got {3})") - -/* struct */ -MSG_DEF(CTYPESMSG_FIELD_MISMATCH,5, JSEXN_TYPEERR, "property count of {0} does not match to field count of the type {1} (expected {2}, got {3}){4}") -MSG_DEF(CTYPESMSG_PROP_NONSTRING,3, JSEXN_TYPEERR, "property name {0} of {1} is not a string{2}") - -/* data finalizer */ -MSG_DEF(CTYPESMSG_EMPTY_FIN, 1, JSEXN_TYPEERR, "attempting to convert an empty CDataFinalizer{0}") -MSG_DEF(CTYPESMSG_FIN_SIZE_ERROR,2, JSEXN_TYPEERR, "expected an object with the same size as argument 1 of {0}, got {1}") diff --git a/js/src/jit-test/lib/asserts.js b/js/src/jit-test/lib/asserts.js index c183a446fc08..a87364542211 100644 --- a/js/src/jit-test/lib/asserts.js +++ b/js/src/jit-test/lib/asserts.js @@ -65,23 +65,3 @@ if (typeof assertNoWarning === 'undefined') { } }; } - -if (typeof assertTypeErrorMessage === 'undefined') { - var assertTypeErrorMessage = function assertTypeErrorMessage(f, test) { - try { - f(); - } catch (e) { - if (!(e instanceof TypeError)) - throw new Error("Assertion failed: expected exception TypeError, got " + e); - if (typeof test == "string") { - if (test != e.message) - throw new Error("Assertion failed: expeceted " + test + ", got " + e.message); - } else { - if (!test.test(e.message)) - throw new Error("Assertion failed: expeceted " + test.toString() + ", got " + e.message); - } - return; - } - throw new Error("Assertion failed: expected exception TypeError, no exception thrown"); - }; -} diff --git a/js/src/jit-test/tests/ctypes/conversion-array.js b/js/src/jit-test/tests/ctypes/conversion-array.js deleted file mode 100644 index 840c1a0feb43..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-array.js +++ /dev/null @@ -1,36 +0,0 @@ -// Type conversion error should report its type. - -load(libdir + 'asserts.js'); - -function test() { - // constructor - assertTypeErrorMessage(() => { ctypes.int32_t.array()("foo"); }, - "can't convert the string \"foo\" to the type ctypes.int32_t.array()"); - assertTypeErrorMessage(() => { ctypes.int32_t.array(10)("foo"); }, - "can't convert the string \"foo\" to the type ctypes.int32_t.array(10)"); - assertTypeErrorMessage(() => { ctypes.char.array(2)("foo"); }, - "length of the string \"foo\" does not fit to the length of the type ctypes.char.array(2) (expected 2 or lower, got 3)"); - assertTypeErrorMessage(() => { ctypes.char16_t.array(2)("foo"); }, - "length of the string \"foo\" does not fit to the length of the type ctypes.char16_t.array(2) (expected 2 or lower, got 3)"); - assertTypeErrorMessage(() => { ctypes.int8_t.array(2)(new ArrayBuffer(8)); }, - "length of the array buffer ({}) does not match to the length of the type ctypes.int8_t.array(2) (expected 2, got 8)"); - assertTypeErrorMessage(() => { ctypes.int8_t.array(2)(new Int8Array(8)); }, - "length of the typed array ({0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0}) does not match to the length of the type ctypes.int8_t.array(2) (expected 2, got 8)"); - - // elem setter - assertTypeErrorMessage(() => { ctypes.int32_t.array(10)()[0] = "foo"; }, - "can't convert the string \"foo\" to element 0 of the type ctypes.int32_t.array(10)"); - assertTypeErrorMessage(() => { ctypes.int32_t.array(10)()[1] = "foo"; }, - "can't convert the string \"foo\" to element 1 of the type ctypes.int32_t.array(10)"); - - // value setter - assertTypeErrorMessage(() => { ctypes.int32_t.array(1)().value = ["foo"]; }, - "can't convert the string \"foo\" to element 0 of the type ctypes.int32_t.array(1)"); - assertTypeErrorMessage(() => { ctypes.int32_t.array(1)().value = [2, "foo"]; }, - "length of the array [2, \"foo\"] does not match to the length of the type ctypes.int32_t.array(1) (expected 1, got 2)"); - assertTypeErrorMessage(() => { ctypes.int32_t.array(2)().value = [2, "foo"]; }, - "can't convert the string \"foo\" to element 1 of the type ctypes.int32_t.array(2)"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-error.js b/js/src/jit-test/tests/ctypes/conversion-error.js deleted file mode 100644 index a6823fe5ce8c..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-error.js +++ /dev/null @@ -1,14 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - let obj = { - toSource() { - throw 1; - } - }; - assertTypeErrorMessage(() => { ctypes.double().value = obj; }, - "can't convert <> to the type double"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-finalizer.js b/js/src/jit-test/tests/ctypes/conversion-finalizer.js deleted file mode 100644 index a04a40cfa203..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-finalizer.js +++ /dev/null @@ -1,61 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - // non object - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, "foo"); }, - "expected _a CData object_ of a function pointer type, got the string \"foo\""); - // non CData object - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ["foo"]); }, - "expected a _CData_ object of a function pointer type, got the array [\"foo\"]"); - - // a CData which is not a pointer - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ctypes.int32_t(0)); }, - "expected a CData object of a function _pointer_ type, got ctypes.int32_t(0)"); - // a pointer CData which is not a function - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, ctypes.int32_t.ptr(0)); }, - "expected a CData object of a _function_ pointer type, got ctypes.int32_t.ptr(ctypes.UInt64(\"0x0\"))"); - - // null function - let func_type = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, - [ctypes.int32_t, ctypes.int32_t]).ptr; - let f0 = func_type(0); - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f0); }, - "expected a CData object of a _non-NULL_ function pointer type, got ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t, ctypes.int32_t]).ptr(ctypes.UInt64(\"0x0\"))"); - - // a function with 2 arguments - let f1 = func_type(x => x); - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f1); }, - "expected a function accepting exactly one argument, got ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t, ctypes.int32_t])"); - - // non CData in argument 1 - let func_type2 = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, - [ctypes.int32_t.ptr]).ptr; - let f2 = func_type2(x => x); - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(0, f2); }, - "can't convert the number 0 to the type of argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t.ptr]).ptr"); - - // wrong struct in argument 1 - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); - let func_type3 = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, - [test_struct]).ptr; - let f3 = func_type3(x => x); - assertTypeErrorMessage(() => { ctypes.CDataFinalizer({ "x": "foo" }, f3); }, - "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct at argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [test_struct]).ptr"); - - // different size in argument 1 - let func_type4 = ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, - [ctypes.int32_t]).ptr; - let f4 = func_type4(x => x); - assertTypeErrorMessage(() => { ctypes.CDataFinalizer(ctypes.int16_t(0), f4); }, - "expected an object with the same size as argument 1 of ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, [ctypes.int32_t]).ptr, got ctypes.int16_t(0)"); - - let fin = ctypes.CDataFinalizer(ctypes.int32_t(0), f4); - fin.dispose(); - assertTypeErrorMessage(() => { ctypes.int32_t(0).value = fin; }, - "attempting to convert an empty CDataFinalizer"); - assertTypeErrorMessage(() => { f4(fin); }, - /attempting to convert an empty CDataFinalizer at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[ctypes\.int32_t\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-function.js b/js/src/jit-test/tests/ctypes/conversion-function.js deleted file mode 100644 index cd90f1b60682..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-function.js +++ /dev/null @@ -1,33 +0,0 @@ -// Type conversion error should report its type. - -load(libdir + 'asserts.js'); - -function test() { - // Note: js shell cannot handle the exception in return value. - - // primitive - let func_type = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, - [ctypes.int32_t]).ptr; - let f1 = func_type(function() {}); - assertTypeErrorMessage(() => { f1("foo"); }, - /can't pass the string "foo" to argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.voidptr_t, \[ctypes\.int32_t\]\)\.ptr\(ctypes\.UInt64\("[x0-9A-Fa-f]+"\)\)/); - - // struct - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); - let func_type2 = ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, - [test_struct]).ptr; - let f2 = func_type2(function() {}); - assertTypeErrorMessage(() => { f2({ "x": "foo" }); }, - /can't convert the string \"foo\" to the 'x' field \(int32_t\) of test_struct at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); - assertTypeErrorMessage(() => { f2({ "x": "foo", "y": "bar" }); }, - /property count of the object \(\{x:\"foo\", y:\"bar\"\}\) does not match to field count of the type test_struct \(expected 1, got 2\) at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); - assertTypeErrorMessage(() => { f2({ 0: "foo" }); }, - /property name the number 0 of the object \(\{0:\"foo\"\}\) is not a string at argument 1 of ctypes\.FunctionType\(ctypes\.default_abi, ctypes\.int32_t, \[test_struct\]\)\.ptr\(ctypes\.UInt64\(\"[x0-9A-Fa-f]+\"\)\)/); - - // error sentinel - assertTypeErrorMessage(() => { func_type(function() {}, null, "foo"); }, - "can't convert the string \"foo\" to the return type of ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, [ctypes.int32_t])"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-int64.js b/js/src/jit-test/tests/ctypes/conversion-int64.js deleted file mode 100644 index f1751bdc0547..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-int64.js +++ /dev/null @@ -1,20 +0,0 @@ -load(libdir + 'asserts.js'); - -function test() { - assertTypeErrorMessage(() => { ctypes.Int64("0xfffffffffffffffffffffff"); }, - "can't pass the string \"0xfffffffffffffffffffffff\" to argument 1 of Int64"); - assertTypeErrorMessage(() => { ctypes.Int64.join("foo", 0); }, - "can't pass the string \"foo\" to argument 1 of Int64.join"); - assertTypeErrorMessage(() => { ctypes.Int64.join(0, "foo"); }, - "can't pass the string \"foo\" to argument 2 of Int64.join"); - - assertTypeErrorMessage(() => { ctypes.UInt64("0xfffffffffffffffffffffff"); }, - "can't pass the string \"0xfffffffffffffffffffffff\" to argument 1 of UInt64"); - assertTypeErrorMessage(() => { ctypes.UInt64.join("foo", 0); }, - "can't pass the string \"foo\" to argument 1 of UInt64.join"); - assertTypeErrorMessage(() => { ctypes.UInt64.join(0, "foo"); }, - "can't pass the string \"foo\" to argument 2 of UInt64.join"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-native-function.js b/js/src/jit-test/tests/ctypes/conversion-native-function.js deleted file mode 100644 index d2196813e90d..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-native-function.js +++ /dev/null @@ -1,37 +0,0 @@ -// Type conversion error for native function should report its name and type -// in C style. - -load(libdir + 'asserts.js'); - -function test() { - let lib; - try { - lib = ctypes.open(ctypes.libraryName("c")); - } catch (e) { - } - if (!lib) - return; - - let func = lib.declare("hypot", - ctypes.default_abi, - ctypes.double, - ctypes.double, ctypes.double); - assertTypeErrorMessage(() => { func(1, "xyzzy"); }, - "can't pass the string \"xyzzy\" to argument 2 of double hypot(double, double)"); - - // test C style source for various types - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); - let test_func = ctypes.FunctionType(ctypes.default_abi, ctypes.voidptr_t, - [ctypes.int32_t]).ptr; - func = lib.declare("hypot", - ctypes.default_abi, - ctypes.double, - ctypes.double, ctypes.int32_t.ptr.ptr.ptr.array(), - test_struct, test_struct.ptr.ptr, - test_func, test_func.ptr.ptr.ptr, "..."); - assertTypeErrorMessage(() => { func("xyzzy", 1, 2, 3, 4, 5); }, - "can't pass the string \"xyzzy\" to argument 1 of double hypot(double, int32_t****, struct test_struct, struct test_struct**, void* (*)(int32_t), void* (****)(int32_t), ...)"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-pointer.js b/js/src/jit-test/tests/ctypes/conversion-pointer.js deleted file mode 100644 index cfdcc8ed87af..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-pointer.js +++ /dev/null @@ -1,29 +0,0 @@ -// Type conversion error should report its type. - -load(libdir + 'asserts.js'); - -function test() { - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); - let struct_val = test_struct(); - - // constructor - assertTypeErrorMessage(() => { ctypes.int32_t.ptr("foo"); }, - "can't convert the string \"foo\" to the type ctypes.int32_t.ptr"); - - // value setter - assertTypeErrorMessage(() => { test_struct.ptr().value = "foo"; }, - "can't convert the string \"foo\" to the type test_struct.ptr"); - assertTypeErrorMessage(() => { test_struct.ptr().value = {}; }, - "can't convert the object ({}) to the type test_struct.ptr"); - assertTypeErrorMessage(() => { test_struct.ptr().value = [1, 2]; }, - "can't convert the array [1, 2] to the type test_struct.ptr"); - assertTypeErrorMessage(() => { test_struct.ptr().value = Int8Array([1, 2]); }, - "can't convert the typed array ({0:1, 1:2}) to the type test_struct.ptr"); - - // contents setter - assertTypeErrorMessage(() => { ctypes.int32_t().address().contents = {}; }, - "can't convert the object ({}) to the type int32_t"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-primitive.js b/js/src/jit-test/tests/ctypes/conversion-primitive.js deleted file mode 100644 index aaaa95e6b8bd..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-primitive.js +++ /dev/null @@ -1,44 +0,0 @@ -// Type conversion error should report its type. - -load(libdir + 'asserts.js'); - -function test() { - // constructor - assertTypeErrorMessage(() => { ctypes.int32_t("foo"); }, - "can't convert the string \"foo\" to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t(null); }, - "can't convert null to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t(undefined); }, - "can't convert undefined to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t({}); }, - "can't convert the object ({}) to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t([]); }, - "can't convert the array [] to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t(new Int8Array([])); }, - "can't convert the typed array ({}) to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t(ctypes.int32_t); }, - "can't convert ctypes.int32_t to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t("0xfffffffffffffffffffffff"); }, - "can't convert the string \"0xfffffffffffffffffffffff\" to the type int32_t"); - if (typeof Symbol === "function") { - assertTypeErrorMessage(() => { ctypes.int32_t(Symbol.iterator); }, - "can't convert Symbol.iterator to the type int32_t"); - assertTypeErrorMessage(() => { ctypes.int32_t(Symbol("foo")); }, - "can't convert Symbol(\"foo\") to the type int32_t"); - } - - // value setter - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }]); - let struct_val = test_struct(); - assertTypeErrorMessage(() => { ctypes.bool().value = struct_val; }, - "can't convert test_struct(0) to the type boolean"); - assertTypeErrorMessage(() => { ctypes.char16_t().value = struct_val; }, - "can't convert test_struct(0) to the type char16_t"); - assertTypeErrorMessage(() => { ctypes.int8_t().value = struct_val; }, - "can't convert test_struct(0) to the type int8_t"); - assertTypeErrorMessage(() => { ctypes.double().value = struct_val; }, - "can't convert test_struct(0) to the type double"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-struct.js b/js/src/jit-test/tests/ctypes/conversion-struct.js deleted file mode 100644 index f5e43ffa563b..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-struct.js +++ /dev/null @@ -1,36 +0,0 @@ -// Type conversion error should report its type. - -load(libdir + 'asserts.js'); - -function test() { - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }, - { "bar": ctypes.int32_t }]); - - // constructor - assertTypeErrorMessage(() => { new test_struct("foo"); }, - "can't convert the string \"foo\" to the type test_struct"); - assertTypeErrorMessage(() => { new test_struct("foo", "x"); }, - "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); - assertTypeErrorMessage(() => { new test_struct({ "x": "foo", "bar": 1 }); }, - "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); - assertTypeErrorMessage(() => { new test_struct({ 0: 1, "bar": 1 }); }, - "property name the number 0 of the object ({0:1, bar:1}) is not a string"); - - // field setter - let struct_val = test_struct(); - assertTypeErrorMessage(() => { struct_val.x = "foo"; }, - "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); - assertTypeErrorMessage(() => { struct_val.bar = "foo"; }, - "can't convert the string \"foo\" to the 'bar' field (int32_t) of test_struct"); - - // value setter - assertTypeErrorMessage(() => { struct_val.value = { "x": "foo" }; }, - "property count of the object ({x:\"foo\"}) does not match to field count of the type test_struct (expected 2, got 1)"); - assertTypeErrorMessage(() => { struct_val.value = { "x": "foo", "bar": 1 }; }, - "can't convert the string \"foo\" to the 'x' field (int32_t) of test_struct"); - assertTypeErrorMessage(() => { struct_val.value = "foo"; }, - "can't convert the string \"foo\" to the type test_struct"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jit-test/tests/ctypes/conversion-to-primitive.js b/js/src/jit-test/tests/ctypes/conversion-to-primitive.js deleted file mode 100644 index cdb9a4a051d5..000000000000 --- a/js/src/jit-test/tests/ctypes/conversion-to-primitive.js +++ /dev/null @@ -1,20 +0,0 @@ -// Accessing `value` property of non primitive type should report its type. - -load(libdir + 'asserts.js'); - -function test() { - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.voidptr_t }]); - assertTypeErrorMessage(() => test_struct().value, - ".value only works on character and numeric types, not `test_struct`"); - - let test_array = ctypes.ArrayType(test_struct); - assertTypeErrorMessage(() => test_array(10).value, - ".value only works on character and numeric types, not `test_struct.array(10)`"); - - let test_pointer = ctypes.PointerType(test_struct); - assertTypeErrorMessage(() => test_pointer(10).value, - ".value only works on character and numeric types, not `test_struct.ptr`"); -} - -if (typeof ctypes === "object") - test(); diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index 703ff7de5f34..a1fdab346a00 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -930,43 +930,3 @@ JS::CreateError(JSContext* cx, JSExnType type, HandleObject stack, HandleString rval.setObject(*obj); return true; } - -const char* -js::ValueToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes) -{ - if (val.isUndefined()) { - return "undefined"; - } - if (val.isNull()) { - return "null"; - } - - RootedString str(cx, JS_ValueToSource(cx, val)); - if (!str) { - JS_ClearPendingException(cx); - return "<>"; - } - - StringBuffer sb(cx); - if (val.isObject()) { - RootedObject valObj(cx, val.toObjectOrNull()); - if (JS_IsArrayObject(cx, valObj)) { - sb.append("the array "); - } else if (JS_IsArrayBufferObject(valObj)) { - sb.append("the array buffer "); - } else if (JS_IsArrayBufferViewObject(valObj)) { - sb.append("the typed array "); - } else { - sb.append("the object "); - } - } else if (val.isNumber()) { - sb.append("the number "); - } else if (val.isString()) { - sb.append("the string "); - } else { - MOZ_ASSERT(val.isBoolean() || val.isSymbol()); - return bytes.encodeLatin1(cx, str); - } - sb.append(str); - return bytes.encodeLatin1(cx, sb.finishString()); -} diff --git a/js/src/jsexn.h b/js/src/jsexn.h index 3bcf29abd38a..1cdcac947e5d 100644 --- a/js/src/jsexn.h +++ b/js/src/jsexn.h @@ -129,9 +129,6 @@ class AutoClearPendingException } }; -extern const char* -ValueToSourceForError(JSContext* cx, HandleValue val, JSAutoByteString& bytes); - } // namespace js #endif /* jsexn_h */ diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index 5ddeab5297d5..911e8e4b251b 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -1166,7 +1166,7 @@ function run_char_tests(library, t, name, size, signed, limits) { do_check_eq(s.constructor.length, literal.length + 1); s = t.array(50)(literal); do_check_eq(s.readString(), literal); - do_check_throws(function() { t.array(3)(literal); }, TypeError); + do_check_throws(function() { t.array(3)(literal); }, Error); do_check_throws(function() { t.ptr(literal); }, TypeError); let p = t.ptr(s); @@ -1258,7 +1258,7 @@ function run_char16_tests(library, t, name, limits) { do_check_eq(s.constructor.length, literal.length + 1); s = t.array(50)(literal); do_check_eq(s.readString(), literal); - do_check_throws(function() { t.array(3)(literal); }, TypeError); + do_check_throws(function() { t.array(3)(literal); }, Error); do_check_throws(function() { t.ptr(literal); }, TypeError); let p = t.ptr(s); @@ -1587,25 +1587,25 @@ function run_StructType_tests() { do_check_eq(s.b.b, s2.b.b); // Test that structs can be set from an object using 'value'. - do_check_throws(function() { s.value; }, TypeError); + do_check_throws(function() { s.value; }, Error); let s_init = { "a": 2, "b": { "a": 9, "b": 5 }, "c": 13 }; s.value = s_init; do_check_eq(s.b.a, 9); do_check_eq(s.c, 13); do_check_throws(function() { s.value = 5; }, TypeError); do_check_throws(function() { s.value = ctypes.int32_t(); }, TypeError); - do_check_throws(function() { s.value = {}; }, TypeError); - do_check_throws(function() { s.value = { "a": 2 }; }, TypeError); + do_check_throws(function() { s.value = {}; }, Error); + do_check_throws(function() { s.value = { "a": 2 }; }, Error); do_check_throws(function() { s.value = { "a": 2, "b": 5, "c": 10 }; }, TypeError); do_check_throws(function() { s.value = { "5": 2, "b": { "a": 9, "b": 5 }, "c": 13 }; - }, TypeError); + }, Error); do_check_throws(function() { s.value = { "a": 2, "b": { "a": 9, "b": 5 }, "c": 13, "d": 17 }; - }, TypeError); + }, Error); do_check_throws(function() { s.value = { "a": 2, "b": { "a": 9, "b": 5, "e": 9 }, "c": 13 }; - }, TypeError); + }, Error); // Test that structs can be constructed similarly through ExplicitConvert, // and that the single-field case is disambiguated correctly. @@ -1682,7 +1682,7 @@ function run_PointerType_tests() { // Test ExplicitConvert. let p = p_t(); - do_check_throws(function() { p.value; }, TypeError); + do_check_throws(function() { p.value; }, Error); do_check_eq(ptrValue(p), 0); do_check_throws(function() { p.contents; }, Error); do_check_throws(function() { p.contents = g; }, Error); @@ -1798,10 +1798,10 @@ function run_PointerType_tests() { let array_type_too_large = item_type.array(number_of_items + 1); let array_type_too_small = item_type.array(number_of_items - 1); - do_check_throws(function() { array_type_too_large(c_arraybuffer); }, TypeError); - do_check_throws(function() { array_type_too_small(c_arraybuffer); }, TypeError); - do_check_throws(function() { array_type_too_large(view); }, TypeError); - do_check_throws(function() { array_type_too_small(view); }, TypeError); + do_check_throws(function() { array_type_too_large(c_arraybuffer); }, Error); + do_check_throws(function() { array_type_too_small(c_arraybuffer); }, Error); + do_check_throws(function() { array_type_too_large(view); }, Error); + do_check_throws(function() { array_type_too_small(view); }, Error); // Convert subarray of typed array to array of right size and check contents c_array = array_type_too_small(view.subarray(1)); @@ -1884,7 +1884,7 @@ function run_FunctionType_tests() { // Test ExplicitConvert. let f = fp_t(); - do_check_throws(function() { f.value; }, TypeError); + do_check_throws(function() { f.value; }, Error); do_check_eq(ptrValue(f), 0); f = fp_t(5); do_check_eq(ptrValue(f), 5); @@ -2067,11 +2067,11 @@ function run_ArrayType_tests() { c.value = c; do_check_eq(c[3], 4); - do_check_throws(function() { c.value; }, TypeError); - do_check_throws(function() { c.value = [1, 2, 3, 4, 5]; }, TypeError); - do_check_throws(function() { c.value = [1, 2, 3, 4, 5, 6, 7]; }, TypeError); + do_check_throws(function() { c.value; }, Error); + do_check_throws(function() { c.value = [1, 2, 3, 4, 5]; }, Error); + do_check_throws(function() { c.value = [1, 2, 3, 4, 5, 6, 7]; }, Error); do_check_throws(function() { c.value = [1, 2, 7.4, 4, 5, 6]; }, TypeError); - do_check_throws(function() { c.value = []; }, TypeError); + do_check_throws(function() { c.value = []; }, Error); } function run_type_toString_tests() { From 9c20e89e57bfe87a94bb51673e6693bcc956c0cf Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 22 Apr 2015 20:08:25 +0900 Subject: [PATCH 108/241] Backed out changeset 7eee0cdd0feb (bug 1155985) for xpcshell-test failure --- js/src/ctypes/CTypes.cpp | 8 +------- js/src/jit-test/tests/ctypes/bug1155985.js | 14 -------------- 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 js/src/jit-test/tests/ctypes/bug1155985.js diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 2fe4187fbfb0..640434db8d6a 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -4963,7 +4963,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb // Add field name to the hash FieldInfo info; - info.mType = nullptr; // Value of fields are not yet traceable here. + info.mType = fieldType; info.mIndex = i; info.mOffset = fieldOffset; ASSERT_OK(fields->add(entryPtr, name, info)); @@ -4996,12 +4996,6 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb if (!SizeTojsval(cx, structSize, &sizeVal)) return false; - for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) { - FieldInfo& field = r.front().value(); - MOZ_ASSERT(field.mIndex < fieldRoots.length()); - field.mType = &fieldRoots[field.mIndex].toObject(); - } - JS_SetReservedSlot(typeObj, SLOT_FIELDINFO, PRIVATE_TO_JSVAL(fields.release())); JS_SetReservedSlot(typeObj, SLOT_SIZE, sizeVal); diff --git a/js/src/jit-test/tests/ctypes/bug1155985.js b/js/src/jit-test/tests/ctypes/bug1155985.js deleted file mode 100644 index 54c24d4badfe..000000000000 --- a/js/src/jit-test/tests/ctypes/bug1155985.js +++ /dev/null @@ -1,14 +0,0 @@ -function test() { - for (let i = 0; i < 100; i++) { - let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t }, - { "bar": ctypes.uint32_t }]); - - try { - new test_struct("foo", "x"); - } catch (e) { - } - } -} - -if (typeof ctypes === "object") - test(); From 5841b014115e325daab82197bf483a9ec06ec36e Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Mon, 20 Apr 2015 23:05:00 +0200 Subject: [PATCH 109/241] Bug 1102388 - Fix DMD static constructor ordering dependency. r=mccr8 Sometimes, at least on Linux, DMDFuncs::sSingleton's static initializer (in libxul) was being called before sDMDBridge's (in libdmd). Thus sDMDBridge wasn't constructed yet in the path where its address is taken, passed down through {replace_,}get_bridge to ReplaceMallocBridge::Get, and its mVersion field is read. This patch uses dynamic allocation, following what's done for other globals in the same situation in this file. Also, naming convention fix: leading "s" is for C++ class statics; C-style static globals should be "g". --HG-- extra : rebase_source : 4a6447760555aa11109749c612094ba1694b41f6 --- memory/replace/dmd/DMD.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/memory/replace/dmd/DMD.cpp b/memory/replace/dmd/DMD.cpp index abfa93c1354d..b992ce34e2d2 100644 --- a/memory/replace/dmd/DMD.cpp +++ b/memory/replace/dmd/DMD.cpp @@ -82,13 +82,13 @@ class DMDBridge : public ReplaceMallocBridge virtual DMDFuncs* GetDMDFuncs() override; }; -static DMDBridge sDMDBridge; -static DMDFuncs sDMDFuncs; +static DMDBridge* gDMDBridge; +static DMDFuncs gDMDFuncs; DMDFuncs* DMDBridge::GetDMDFuncs() { - return &sDMDFuncs; + return &gDMDFuncs; } inline void @@ -96,7 +96,7 @@ StatusMsg(const char* aFmt, ...) { va_list ap; va_start(ap, aFmt); - sDMDFuncs.StatusMsg(aFmt, ap); + gDMDFuncs.StatusMsg(aFmt, ap); va_end(ap); } @@ -1211,7 +1211,7 @@ replace_init(const malloc_table_t* aMallocTable) ReplaceMallocBridge* replace_get_bridge() { - return &mozilla::dmd::sDMDBridge; + return mozilla::dmd::gDMDBridge; } void* @@ -1518,6 +1518,7 @@ static void Init(const malloc_table_t* aMallocTable) { gMallocTable = aMallocTable; + gDMDBridge = InfallibleAllocPolicy::new_(); // DMD is controlled by the |DMD| environment variable. const char* e = getenv("DMD"); From 3a94be560cd3a6163f3fe905f933de5e37a02412 Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Tue, 21 Apr 2015 14:56:00 +0200 Subject: [PATCH 110/241] Bug 1124076 - Properly detect certs when loaded and prompt to import them. r=sworkman/dkeeler --HG-- extra : rebase_source : 00240091ae66180390a76a9613a4215cf591401d --- dom/ipc/ContentChild.cpp | 18 + dom/ipc/ContentChild.h | 4 + dom/ipc/ContentParent.cpp | 18 + dom/ipc/ContentParent.h | 4 + dom/ipc/PContent.ipdl | 4 + .../ssl/src/PPSMContentDownloader.ipdl | 28 + .../manager/ssl/src/PSMContentListener.cpp | 502 ++++++++++++------ security/manager/ssl/src/PSMContentListener.h | 72 +++ security/manager/ssl/src/moz.build | 8 + security/manager/ssl/src/nsNSSModule.cpp | 14 +- 10 files changed, 494 insertions(+), 178 deletions(-) create mode 100644 security/manager/ssl/src/PPSMContentDownloader.ipdl diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 74b1a8b36833..799497ffd7a9 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -38,6 +38,7 @@ #include "mozilla/dom/asmjscache/AsmJSCache.h" #include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h" #include "mozilla/dom/nsIContentChild.h" +#include "mozilla/psm/PSMContentListener.h" #include "mozilla/hal_sandbox/PHalChild.h" #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/FileDescriptorSetChild.h" @@ -203,6 +204,7 @@ using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::net; using namespace mozilla::jsipc; +using namespace mozilla::psm; using namespace mozilla::widget; #if defined(MOZ_WIDGET_GONK) using namespace mozilla::system; @@ -1623,6 +1625,22 @@ ContentChild::DeallocPScreenManagerChild(PScreenManagerChild* aService) return true; } +PPSMContentDownloaderChild* +ContentChild::AllocPPSMContentDownloaderChild(const uint32_t& aCertType) +{ + // NB: We don't need aCertType in the child actor. + nsRefPtr child = new PSMContentDownloaderChild(); + return child.forget().take(); +} + +bool +ContentChild::DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aListener) +{ + auto* listener = static_cast(aListener); + nsRefPtr child = dont_AddRef(listener); + return true; +} + PExternalHelperAppChild* ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 6adf18e222d9..bb2d8d999a47 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -232,6 +232,10 @@ public: bool* aSuccess) override; virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) override; + virtual PPSMContentDownloaderChild* AllocPPSMContentDownloaderChild( + const uint32_t& aCertType) override; + virtual bool DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aDownloader) override; + virtual PExternalHelperAppChild *AllocPExternalHelperAppChild( const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 0bc87b8b197f..d8b4c25768d8 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -156,6 +156,7 @@ #include "prio.h" #include "private/pprio.h" #include "ContentProcessManager.h" +#include "mozilla/psm/PSMContentListener.h" #include "nsIBidiKeyboard.h" @@ -249,6 +250,7 @@ using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::net; using namespace mozilla::jsipc; +using namespace mozilla::psm; using namespace mozilla::widget; #ifdef ENABLE_TESTS @@ -3665,6 +3667,22 @@ ContentParent::DeallocPScreenManagerParent(PScreenManagerParent* aActor) return true; } +PPSMContentDownloaderParent* +ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType) +{ + nsRefPtr downloader = + new PSMContentDownloaderParent(aCertType); + return downloader.forget().take(); +} + +bool +ContentParent::DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aListener) +{ + auto* listener = static_cast(aListener); + nsRefPtr downloader = dont_AddRef(listener); + return true; +} + PExternalHelperAppParent* ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 8affe5a57c1d..680845e43a46 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -606,6 +606,10 @@ private: virtual bool DeallocPNeckoParent(PNeckoParent* necko) override; + virtual PPSMContentDownloaderParent* AllocPPSMContentDownloaderParent( + const uint32_t& aCertType) override; + virtual bool DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aDownloader) override; + virtual PExternalHelperAppParent* AllocPExternalHelperAppParent( const OptionalURIParams& aUri, const nsCString& aMimeContentType, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index a4af80229623..190b836330cf 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -16,6 +16,7 @@ include protocol PContentPermissionRequest; include protocol PCycleCollectWithLogs; include protocol PCrashReporter; include protocol PDocAccessible; +include protocol PPSMContentDownloader; include protocol PExternalHelperApp; include protocol PDeviceStorageRequest; include protocol PFileDescriptorSet; @@ -388,6 +389,7 @@ prio(normal upto urgent) sync protocol PContent manages PDocAccessible; manages PDeviceStorageRequest; manages PFileSystemRequest; + manages PPSMContentDownloader; manages PExternalHelperApp; manages PFileDescriptorSet; manages PFMRadio; @@ -756,6 +758,8 @@ parent: CloseAlert(nsString name, Principal principal); + PPSMContentDownloader(uint32_t aCertType); + PExternalHelperApp(OptionalURIParams uri, nsCString aMimeContentType, nsCString aContentDisposition, diff --git a/security/manager/ssl/src/PPSMContentDownloader.ipdl b/security/manager/ssl/src/PPSMContentDownloader.ipdl new file mode 100644 index 000000000000..ac97d7c444fb --- /dev/null +++ b/security/manager/ssl/src/PPSMContentDownloader.ipdl @@ -0,0 +1,28 @@ +/* vim: set sw=2 sts=2 ts=2 et tw=80 ft=cpp: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PContent; +include protocol PChannelDiverter; + +namespace mozilla { +namespace psm { + +protocol PPSMContentDownloader +{ + manager PContent; + +parent: + OnStartRequest(uint32_t contentLength); + OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); + OnStopRequest(nsresult code); + + DivertToParentUsing(PChannelDiverter diverter); + +child: + __delete__(); +}; + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/src/PSMContentListener.cpp b/security/manager/ssl/src/PSMContentListener.cpp index 789aac0fa668..84bed2805590 100644 --- a/security/manager/ssl/src/PSMContentListener.cpp +++ b/security/manager/ssl/src/PSMContentListener.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set sw=2 sts=2 ts=2 et tw=80: * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -6,16 +7,22 @@ #include "PSMContentListener.h" +#include "nsIDivertableChannel.h" #include "nsIStreamListener.h" #include "nsIX509CertDB.h" +#include "nsIXULAppInfo.h" #include "mozilla/Casting.h" #include "mozilla/Services.h" +#include "mozilla/unused.h" + +#include "mozilla/dom/ContentChild.h" +#include "mozilla/net/ChannelDiverterParent.h" +#include "mozilla/net/ChannelDiverterChild.h" #include "nsCRT.h" #include "nsNetUtil.h" #include "nsNSSHelper.h" -#include "nsNSSShutDown.h" #include "prlog.h" @@ -27,139 +34,158 @@ namespace mozilla { namespace psm { namespace { -class PSMContentDownloader : public nsIStreamListener -{ -public: - PSMContentDownloader() {NS_ASSERTION(false, "don't use this constructor."); } - explicit PSMContentDownloader(uint32_t type); - void setSilentDownload(bool flag); - - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - enum {UNKNOWN_TYPE = 0}; - enum {X509_CA_CERT = 1}; - enum {X509_USER_CERT = 2}; - enum {X509_EMAIL_CERT = 3}; - enum {X509_SERVER_CERT = 4}; - -protected: - virtual ~PSMContentDownloader(); - - char* mByteData; - int32_t mBufferOffset; - int32_t mBufferSize; - uint32_t mType; - nsCOMPtr mURI; -}; - -PSMContentDownloader::PSMContentDownloader(uint32_t type) - : mByteData(nullptr), - mType(type) -{ -} - -PSMContentDownloader::~PSMContentDownloader() -{ - if (mByteData) - free(mByteData); -} - -NS_IMPL_ISUPPORTS(PSMContentDownloader, nsIStreamListener, nsIRequestObserver) - const int32_t kDefaultCertAllocLength = 2048; -NS_IMETHODIMP -PSMContentDownloader::OnStartRequest(nsIRequest* request, nsISupports* context) -{ - nsresult rv; - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStartRequest\n")); - nsCOMPtr channel(do_QueryInterface(request)); - if (!channel) return NS_ERROR_FAILURE; +enum { + UNKNOWN_TYPE = 0, + X509_CA_CERT = 1, + X509_USER_CERT = 2, + X509_EMAIL_CERT = 3, + X509_SERVER_CERT = 4 +}; - // Get the URI // - channel->GetURI(getter_AddRefs(mURI)); +/* other mime types that we should handle sometime: + + application/x-pkcs7-mime + application/pkcs7-signature + application/pre-encrypted + +*/ + +uint32_t +getPSMContentType(const char* aContentType) +{ + // Don't forget to update the registration of content listeners in nsNSSModule.cpp + // for every supported content type. + + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert")) + return X509_CA_CERT; + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert")) + return X509_SERVER_CERT; + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert")) + return X509_USER_CERT; + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert")) + return X509_EMAIL_CERT; + + return UNKNOWN_TYPE; +} + +int64_t +ComputeContentLength(nsIRequest* request) +{ + nsCOMPtr channel(do_QueryInterface(request)); + if (!channel) { + return -1; + } int64_t contentLength; - rv = channel->GetContentLength(&contentLength); - if (NS_FAILED(rv) || contentLength <= 0) - contentLength = kDefaultCertAllocLength; - if (contentLength > INT32_MAX) - return NS_ERROR_OUT_OF_MEMORY; - - mBufferOffset = 0; - mBufferSize = 0; - mByteData = (char*)moz_xmalloc(AssertedCast(contentLength)); - if (!mByteData) - return NS_ERROR_OUT_OF_MEMORY; - - mBufferSize = int32_t(contentLength); + nsresult rv = channel->GetContentLength(&contentLength); + if (NS_FAILED(rv) || contentLength <= 0) { + return kDefaultCertAllocLength; + } + + if (contentLength > INT32_MAX) { + return -1; + } + + return contentLength; +} + +class ImportCertRunnable : public nsRunnable +{ +public: + ImportCertRunnable(PSMContentStreamListener* streamer) + : mStreamer(streamer) + { + } + + NS_IMETHOD Run() + { + mStreamer->ImportCertificate(); + return NS_OK; + } + +private: + nsRefPtr mStreamer; +}; + + +} // unnamed namespace + +/* ------------------------ + * PSMContentStreamListener + * ------------------------ */ + +PSMContentStreamListener::PSMContentStreamListener(uint32_t type) + : mType(type) +{ +} + +PSMContentStreamListener::~PSMContentStreamListener() +{ +} + +NS_IMPL_ISUPPORTS(PSMContentStreamListener, nsIStreamListener, nsIRequestObserver) + +NS_IMETHODIMP +PSMContentStreamListener::OnStartRequest(nsIRequest* request, nsISupports* context) +{ + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStartRequest\n")); + + int64_t contentLength = ComputeContentLength(request); + if (contentLength < 0) { + return NS_ERROR_FAILURE; + } + + mByteData.SetCapacity(contentLength); return NS_OK; } NS_IMETHODIMP -PSMContentDownloader::OnDataAvailable(nsIRequest* request, - nsISupports* context, - nsIInputStream *aIStream, - uint64_t aSourceOffset, - uint32_t aLength) +PSMContentStreamListener::OnDataAvailable(nsIRequest* request, + nsISupports* context, + nsIInputStream* aIStream, + uint64_t aSourceOffset, + uint32_t aLength) { - if (!mByteData) - return NS_ERROR_OUT_OF_MEMORY; - - uint32_t amt; - nsresult err; - //Do a check to see if we need to allocate more memory. - if ((mBufferOffset + (int32_t)aLength) > mBufferSize) { - size_t newSize = (mBufferOffset + aLength) *2; // grow some more than needed - char *newBuffer; - newBuffer = (char*)moz_xrealloc(mByteData, newSize); - if (!newBuffer) { - return NS_ERROR_OUT_OF_MEMORY; - } - mByteData = newBuffer; - mBufferSize = newSize; - } - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnDataAvailable\n")); - do { - err = aIStream->Read(mByteData+mBufferOffset, - aLength, &amt); - if (NS_FAILED(err)) return err; - if (amt == 0) break; - - aLength -= amt; - mBufferOffset += amt; - - } while (aLength > 0); - + + nsCString chunk; + nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength); + if (NS_FAILED(rv)) { + return rv; + } + + mByteData.Append(chunk); return NS_OK; } NS_IMETHODIMP -PSMContentDownloader::OnStopRequest(nsIRequest* request, - nsISupports* context, - nsresult aStatus) +PSMContentStreamListener::OnStopRequest(nsIRequest* request, + nsISupports* context, + nsresult aStatus) { - nsNSSShutDownPreventionLock locker; - //Check if the download succeeded - it might have failed due to - //network issues, etc. - if (NS_FAILED(aStatus)){ - return aStatus; - } - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStopRequest\n")); + // Because importing the cert can spin the event loop (via alerts), we can't + // do it here. Do it off the event loop instead. + nsCOMPtr r = new ImportCertRunnable(this); + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r))); + + return NS_OK; +} + +void +PSMContentStreamListener::ImportCertificate() +{ nsCOMPtr certdb; - nsresult rv; nsCOMPtr ctx = new PipUIContext(); switch (mType) { - case PSMContentDownloader::X509_CA_CERT: - case PSMContentDownloader::X509_USER_CERT: - case PSMContentDownloader::X509_EMAIL_CERT: + case X509_CA_CERT: + case X509_USER_CERT: + case X509_EMAIL_CERT: certdb = do_GetService(NS_X509CERTDB_CONTRACTID); break; @@ -167,48 +193,172 @@ PSMContentDownloader::OnStopRequest(nsIRequest* request, break; } + if (!certdb) { + return; + } + switch (mType) { - case PSMContentDownloader::X509_CA_CERT: - return certdb->ImportCertificates((uint8_t*)mByteData, mBufferOffset, mType, ctx); - case PSMContentDownloader::X509_USER_CERT: - return certdb->ImportUserCertificate((uint8_t*)mByteData, mBufferOffset, ctx); - case PSMContentDownloader::X509_EMAIL_CERT: - return certdb->ImportEmailCertificate((uint8_t*)mByteData, mBufferOffset, ctx); + case X509_CA_CERT: + certdb->ImportCertificates(reinterpret_cast(mByteData.BeginWriting()), + mByteData.Length(), mType, ctx); + break; + + case X509_USER_CERT: + certdb->ImportUserCertificate(reinterpret_cast(mByteData.BeginWriting()), + mByteData.Length(), ctx); + break; + + case X509_EMAIL_CERT: + certdb->ImportEmailCertificate(reinterpret_cast(mByteData.BeginWriting()), + mByteData.Length(), ctx); + break; + default: - rv = NS_ERROR_FAILURE; break; } - +} + +/* ------------------------ + * PSMContentDownloaderParent + * ------------------------ */ + +PSMContentDownloaderParent::PSMContentDownloaderParent(uint32_t type) + : PSMContentStreamListener(type) + , mIPCOpen(true) +{ +} + +PSMContentDownloaderParent::~PSMContentDownloaderParent() +{ +} + +bool +PSMContentDownloaderParent::RecvOnStartRequest(const uint32_t& contentLength) +{ + mByteData.SetCapacity(contentLength); + return true; +} + +bool +PSMContentDownloaderParent::RecvOnDataAvailable(const nsCString& data, + const uint64_t& offset, + const uint32_t& count) +{ + mByteData.Append(data); + return true; +} + +bool +PSMContentDownloaderParent::RecvOnStopRequest(const nsresult& code) +{ + if (NS_SUCCEEDED(code)) { + // See also PSMContentStreamListener::OnStopRequest. In this case, we don't + // have to dispatch ImportCertificate off of an event because we don't have + // to worry about Necko sending "clean up" events and destroying us if + // ImportCertificate spins the event loop. + ImportCertificate(); + } + + if (mIPCOpen) { + mozilla::unused << Send__delete__(this); + } + return true; +} + +NS_IMETHODIMP +PSMContentDownloaderParent::OnStopRequest(nsIRequest* request, nsISupports* context, nsresult code) +{ + nsresult rv = PSMContentStreamListener::OnStopRequest(request, context, code); + + if (mIPCOpen) { + mozilla::unused << Send__delete__(this); + } return rv; } -/* other mime types that we should handle sometime: - - application/x-pkcs7-mime - application/pkcs7-signature - application/pre-encrypted - -*/ - -uint32_t -getPSMContentType(const char * aContentType) -{ - // Don't forget to update the registration of content listeners in nsNSSModule.cpp - // for every supported content type. - - if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert")) - return PSMContentDownloader::X509_CA_CERT; - else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert")) - return PSMContentDownloader::X509_SERVER_CERT; - else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert")) - return PSMContentDownloader::X509_USER_CERT; - else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert")) - return PSMContentDownloader::X509_EMAIL_CERT; - - return PSMContentDownloader::UNKNOWN_TYPE; +bool +PSMContentDownloaderParent::RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent* diverter) +{ + MOZ_ASSERT(diverter); + auto p = static_cast(diverter); + p->DivertTo(this); + mozilla::unused << p->Send__delete__(p); + return true; } -} // unnamed namespace +void +PSMContentDownloaderParent::ActorDestroy(ActorDestroyReason why) +{ + mIPCOpen = false; +} + +/* ------------------------ + * PSMContentDownloaderChild + * ------------------------ */ + +NS_IMPL_ISUPPORTS(PSMContentDownloaderChild, nsIStreamListener) + +PSMContentDownloaderChild::PSMContentDownloaderChild() +{ +} + +PSMContentDownloaderChild::~PSMContentDownloaderChild() +{ +} + +NS_IMETHODIMP +PSMContentDownloaderChild::OnStartRequest(nsIRequest* request, nsISupports* context) +{ + nsCOMPtr divertable = do_QueryInterface(request); + if (divertable) { + mozilla::net::ChannelDiverterChild* diverter = nullptr; + nsresult rv = divertable->DivertToParent(&diverter); + if (NS_FAILED(rv)) { + return rv; + } + MOZ_ASSERT(diverter); + + return SendDivertToParentUsing(diverter) ? NS_OK : NS_ERROR_FAILURE; + } + + int64_t contentLength = ComputeContentLength(request); + if (contentLength < 0) { + return NS_ERROR_FAILURE; + } + + mozilla::unused << SendOnStartRequest(contentLength); + return NS_OK; +} + +NS_IMETHODIMP +PSMContentDownloaderChild::OnDataAvailable(nsIRequest* request, + nsISupports* context, + nsIInputStream* aIStream, + uint64_t aSourceOffset, + uint32_t aLength) +{ + nsCString chunk; + nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength); + if (NS_FAILED(rv)) { + return rv; + } + + mozilla::unused << SendOnDataAvailable(chunk, aSourceOffset, aLength); + return NS_OK; +} + +NS_IMETHODIMP +PSMContentDownloaderChild::OnStopRequest(nsIRequest* request, + nsISupports* context, + nsresult aStatus) +{ + mozilla::unused << SendOnStopRequest(aStatus); + return NS_OK; +} + +/* ------------------------ + * PSMContentListener + * ------------------------ */ NS_IMPL_ISUPPORTS(PSMContentListener, nsIURIContentListener, @@ -231,7 +381,7 @@ PSMContentListener::init() } NS_IMETHODIMP -PSMContentListener::OnStartURIOpen(nsIURI *aURI, bool *aAbortOpen) +PSMContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen) { //if we don't want to handle the URI, return true in //*aAbortOpen @@ -239,73 +389,77 @@ PSMContentListener::OnStartURIOpen(nsIURI *aURI, bool *aAbortOpen) } NS_IMETHODIMP -PSMContentListener::IsPreferred(const char * aContentType, - char ** aDesiredContentType, - bool * aCanHandleContent) +PSMContentListener::IsPreferred(const char* aContentType, + char** aDesiredContentType, + bool* aCanHandleContent) { return CanHandleContent(aContentType, true, aDesiredContentType, aCanHandleContent); } NS_IMETHODIMP -PSMContentListener::CanHandleContent(const char * aContentType, +PSMContentListener::CanHandleContent(const char* aContentType, bool aIsContentPreferred, - char ** aDesiredContentType, - bool * aCanHandleContent) + char** aDesiredContentType, + bool* aCanHandleContent) { - uint32_t type; - type = getPSMContentType(aContentType); - if (type == PSMContentDownloader::UNKNOWN_TYPE) { - *aCanHandleContent = false; - } else { - *aCanHandleContent = true; - } + uint32_t type = getPSMContentType(aContentType); + *aCanHandleContent = (type != UNKNOWN_TYPE); return NS_OK; } NS_IMETHODIMP -PSMContentListener::DoContent(const nsACString & aContentType, +PSMContentListener::DoContent(const nsACString& aContentType, bool aIsContentPreferred, - nsIRequest * aRequest, - nsIStreamListener ** aContentHandler, - bool * aAbortProcess) + nsIRequest* aRequest, + nsIStreamListener** aContentHandler, + bool* aAbortProcess) { uint32_t type; type = getPSMContentType(PromiseFlatCString(aContentType).get()); - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n")); - if (type != PSMContentDownloader::UNKNOWN_TYPE) { - nsRefPtr downLoader = new PSMContentDownloader(type); - downLoader.forget(aContentHandler); + if (gPIPNSSLog) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n")); + } + if (type != UNKNOWN_TYPE) { + nsCOMPtr downloader; + if (XRE_GetProcessType() == GeckoProcessType_Default) { + downloader = new PSMContentStreamListener(type); + } else { + downloader = static_cast( + dom::ContentChild::GetSingleton()->SendPPSMContentDownloaderConstructor(type)); + } + + downloader.forget(aContentHandler); return NS_OK; } return NS_ERROR_FAILURE; } NS_IMETHODIMP -PSMContentListener::GetLoadCookie(nsISupports * *aLoadCookie) +PSMContentListener::GetLoadCookie(nsISupports** aLoadCookie) { - *aLoadCookie = mLoadCookie; - NS_IF_ADDREF(*aLoadCookie); + nsCOMPtr loadCookie(mLoadCookie); + loadCookie.forget(aLoadCookie); return NS_OK; } NS_IMETHODIMP -PSMContentListener::SetLoadCookie(nsISupports * aLoadCookie) +PSMContentListener::SetLoadCookie(nsISupports* aLoadCookie) { mLoadCookie = aLoadCookie; return NS_OK; } NS_IMETHODIMP -PSMContentListener::GetParentContentListener(nsIURIContentListener ** aContentListener) +PSMContentListener::GetParentContentListener(nsIURIContentListener** aContentListener) { - *aContentListener = mParentContentListener; - NS_IF_ADDREF(*aContentListener); + nsCOMPtr listener(mParentContentListener); + listener.forget(aContentListener); return NS_OK; } NS_IMETHODIMP -PSMContentListener::SetParentContentListener(nsIURIContentListener * aContentListener) +PSMContentListener::SetParentContentListener(nsIURIContentListener* aContentListener) { mParentContentListener = aContentListener; return NS_OK; diff --git a/security/manager/ssl/src/PSMContentListener.h b/security/manager/ssl/src/PSMContentListener.h index 49239029bfc8..13bff90b7c49 100644 --- a/security/manager/ssl/src/PSMContentListener.h +++ b/security/manager/ssl/src/PSMContentListener.h @@ -10,12 +10,84 @@ #include "nsCOMPtr.h" #include "nsIURIContentListener.h" #include "nsWeakReference.h" +#include "mozilla/psm/PPSMContentDownloaderChild.h" +#include "mozilla/psm/PPSMContentDownloaderParent.h" #define NS_PSMCONTENTLISTEN_CID {0xc94f4a30, 0x64d7, 0x11d4, {0x99, 0x60, 0x00, 0xb0, 0xd0, 0x23, 0x54, 0xa0}} #define NS_PSMCONTENTLISTEN_CONTRACTID "@mozilla.org/security/psmdownload;1" +namespace mozilla { +namespace net { + +class PChannelDiverterParent; + +} +} + namespace mozilla { namespace psm { +// PSMContentStreamListener for parent-process downloading. +class PSMContentStreamListener : public nsIStreamListener +{ +public: + explicit PSMContentStreamListener(uint32_t type); + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + + void ImportCertificate(); + +protected: + virtual ~PSMContentStreamListener(); + + nsCString mByteData; + uint32_t mType; +}; + +// Parent actor for importing a remote cert when the load was started by the +// child. +class PSMContentDownloaderParent : public PPSMContentDownloaderParent + , public PSMContentStreamListener +{ +public: + explicit PSMContentDownloaderParent(uint32_t type); + + virtual bool RecvOnStartRequest(const uint32_t &contentLength) override; + virtual bool RecvOnDataAvailable(const nsCString &data, + const uint64_t &offset, + const uint32_t &count) override; + virtual bool RecvOnStopRequest(const nsresult &code) override; + + // We inherit most of nsIStreamListener from PSMContentStreamListener, but + // we have to override OnStopRequest to know when we're done with our IPC + // ref. + NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *aContext, nsresult code) override; + + virtual bool RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent *diverter) override; + +protected: + virtual ~PSMContentDownloaderParent(); + + virtual void ActorDestroy(ActorDestroyReason why) override; + bool mIPCOpen; +}; + +// Child actor for importing a cert. +class PSMContentDownloaderChild : public nsIStreamListener + , public PPSMContentDownloaderChild +{ +public: + PSMContentDownloaderChild(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + +private: + ~PSMContentDownloaderChild(); +}; + + class PSMContentListener : public nsIURIContentListener, public nsSupportsWeakReference { diff --git a/security/manager/ssl/src/moz.build b/security/manager/ssl/src/moz.build index 75276a43d168..2efc4a6ae4f9 100644 --- a/security/manager/ssl/src/moz.build +++ b/security/manager/ssl/src/moz.build @@ -23,6 +23,10 @@ EXPORTS.mozilla += [ 'PublicSSL.h', ] +EXPORTS.mozilla.psm += [ + 'PSMContentListener.h', +] + UNIFIED_SOURCES += [ 'CryptoTask.cpp', 'nsCertOverrideService.cpp', @@ -74,6 +78,10 @@ SOURCES += [ 'nsNSSCertificateDB.cpp', ] +IPDL_SOURCES += [ + 'PPSMContentDownloader.ipdl', +] + LOCAL_INCLUDES += [ '/security/manager/boot/src', ] diff --git a/security/manager/ssl/src/nsNSSModule.cpp b/security/manager/ssl/src/nsNSSModule.cpp index c407d91be05e..8ec8fe936a2f 100644 --- a/security/manager/ssl/src/nsNSSModule.cpp +++ b/security/manager/ssl/src/nsNSSModule.cpp @@ -135,14 +135,20 @@ _InstanceClassChrome##Constructor(nsISupports *aOuter, REFNSIID aIID, \ { \ nsresult rv; \ \ - *aResult = nullptr; \ - if (nullptr != aOuter) { \ + *aResult = nullptr; \ + if (nullptr != aOuter) { \ rv = NS_ERROR_NO_AGGREGATION; \ return rv; \ } \ \ - if (!EnsureNSSInitialized(ensureOperator)) \ + if (!NS_IS_PROCESS_DEFAULT && \ + ensureOperator == nssEnsureChromeOrContent) { \ + if (!EnsureNSSInitializedChromeOrContent()) { \ + return NS_ERROR_FAILURE; \ + } \ + } else if (!EnsureNSSInitialized(ensureOperator)) { \ return NS_ERROR_FAILURE; \ + } \ \ if (NS_IS_PROCESS_DEFAULT) \ NS_NSS_INSTANTIATE_INIT(ensureOperator, \ @@ -182,7 +188,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsTLSSocketProvider) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsSecretDecoderRing) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPK11TokenDB) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPKCS11ModuleDB) -NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, PSMContentListener, init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PSMContentListener, init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly, nsNSSCertificate, nsNSSCertificateFakeTransport) From 4a748bd7664640d199c06f6ec64581f25c516fd1 Mon Sep 17 00:00:00 2001 From: Steve Singer Date: Sat, 18 Apr 2015 19:44:00 +0200 Subject: [PATCH 111/241] Bug 1141642 - Fix disable-skia builds. r=jmuizelaar --HG-- extra : rebase_source : 6c6e1664973547b6131a5f5410bb0eec9afd750d --- gfx/layers/basic/BasicCompositor.cpp | 2 +- gfx/layers/basic/BasicLayerManager.cpp | 2 +- image/src/moz.build | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index 17d40d10e7cc..4b2b3061387d 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -280,7 +280,7 @@ Transform(DataSourceSurface* aDest, (uint32_t*)aSource->GetData(), aSource->Stride()); - NS_ABORT_IF_FALSE(src && dest, "Failed to create pixman images?"); + MOZ_ASSERT(src !=0 && dest != 0, "Failed to create pixman images?"); pixman_transform pixTransform = Matrix3DToPixman(aTransform); pixman_transform pixTransformInverted; diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp index b9f4caa54bd2..06a2e0077a8b 100644 --- a/gfx/layers/basic/BasicLayerManager.cpp +++ b/gfx/layers/basic/BasicLayerManager.cpp @@ -711,7 +711,7 @@ Transform(const gfxImageSurface* aDest, (uint32_t*)aSrc->GetData(), aSrc->Stride()); - NS_ABORT_IF_FALSE(src && dest, "Failed to create pixman images?"); + MOZ_ASSERT(src != 0 && dest !=0, "Failed to create pixman images?"); pixman_transform pixTransform = BasicLayerManager_Matrix3DToPixman(aTransform); pixman_transform pixTransformInverted; diff --git a/image/src/moz.build b/image/src/moz.build index 7c7824079ef8..5f7d8b93c08c 100644 --- a/image/src/moz.build +++ b/image/src/moz.build @@ -19,7 +19,6 @@ UNIFIED_SOURCES += [ 'ClippedImage.cpp', 'DecodePool.cpp', 'Decoder.cpp', - 'Downscaler.cpp', 'DynamicImage.cpp', 'FrameAnimator.cpp', 'FrozenImage.cpp', @@ -39,6 +38,8 @@ UNIFIED_SOURCES += [ 'SVGDocumentWrapper.cpp', 'VectorImage.cpp', ] +if CONFIG['MOZ_ENABLE_SKIA']: + UNIFIED_SOURCES += [ 'Downscaler.cpp'] # These files can't be unified because of ImageLogging.h #include order issues. SOURCES += [ From 10d96f3c21775133f8390a613078f750b0915734 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 22 Apr 2015 13:14:33 +0200 Subject: [PATCH 112/241] Backed out changeset bc6db8bcf480 (bug 1085783) --- .../green-circle-with-blue-border.png | Bin 12279 -> 0 bytes .../image-high-quality-scaling-1-ref.html | 22 ------------------ .../image-high-quality-scaling-1.html | 22 ------------------ layout/reftests/pixel-rounding/reftest.list | 4 ---- 4 files changed, 48 deletions(-) delete mode 100644 layout/reftests/pixel-rounding/green-circle-with-blue-border.png delete mode 100644 layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html delete mode 100644 layout/reftests/pixel-rounding/image-high-quality-scaling-1.html diff --git a/layout/reftests/pixel-rounding/green-circle-with-blue-border.png b/layout/reftests/pixel-rounding/green-circle-with-blue-border.png deleted file mode 100644 index 570fd24944a815efd7026eea8df31326a206e52d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12279 zcmZ{K1z42ZxBd(`AVVr30)n)3Nq2V)-O>Wm-8hJZbc1w?bTdHn~kFb#eKb|W{&P|!cl;wa(rxFrcP`etn6(68_CV)^?!Hof3WUL{!f~vm(Bk{yD#~R_D30i^-&0^Q2}K~ z3!B&8Ql@T}BAo0T+$`)|ES&6`9Q*?8Tmn4<vxS{Pzg|uq9nAP2C(_G#wr7L?AX^ zmUi~{uM{s?U$S!i#r-GZALRRS2&lT)SRxgCuSO9h{Qr~v8!zc-@8n|X>Uxjo{u}>K z*}w7XmadL=?)TMeIoP;~aQ;pCm-yc-z5gy3;r$QipTd6=bpJQPKZXAw+)sqSA5G~> z+1Oh;{22=;7jiWJYstTvl8$zcE*egz=9c#g`$PGM=-=o+?dbh?J1^PU|JlwzO8#aF zvE5tqKdk#N*ZCtw`i=+~Ij8^eLlLmWHvrPTnbzf{#5KKuyO|h%1k$s2t-dZ|k5MRT z=75iX3qD+WEDlPPRzszC@n(*AcX_7!#M#)${lrMmEy-UCV&Mq_>PbTqrGdc!;N!%r zkOvPjV&Bu?#fwF6-HNt<=wX)?{vj-U_U*Zdr0Ne1RpFD;J-3$9(o$(@wFk3?8aXn_ zp05TKMGc%v_GkN+)2_{`3;0&w$lru7)4N)x8WMlf3}w(-QqW3;kkP%@{$RRasg6}1 z-(9M-r1dCjn55S*!p87hUG-#{v)onFWe~g<*KUDRD&8<6LIIQNpgajB=OXl_6-?OA z^sV-2bA}HszjDc;KE{tF{TqtY+$2*LSM$fL^(svZObn|F4x@W-;K^aKQnkZ$uw5GG zM5lfAu8vcST|PtiZMpo(6?p~eL~5q9Pahsxe$A|z^=udVY%pW)AMeBU!PC(nxRiPB zF&h;;JtTU0F*rLCo=?oeR0|iZKT?| z^jo60V!qq#V|C7bLt8SC3*TeTdf6taQ2T`S93vyIYs~ZONq7p+FTE4@o>KH{B3s{Q zNoc~jQLT4F2Gm!*QxR3;I9Z8{YrbpM=8okIe3$+;>I)Q*D}%_k*|p#8Y{Gb=xvm>x z_SCIL;sc)2$|pxVFSRQo%lQ_9S(GW(WZVP{ZJm1DqX-;`oZjY)mm8*iCy%m%KC-{tS%5HQj zB`{i9-)n*EvvZTSGshUub#O(b&)di;6MK6^ABjYymt+UC^tqC~$K0JGbvmyPz~71ajrO{wWL zs~&i+0^vXB`>1c;*Y+E;cUE7IG5Dq^D`0##O$Mx9wKTt;-6k_;{Y^u}&HcFfz4@U% zg8qhwVV?7SSgDN9`mxqmF`+r*Ibp+DpX^xkRj)9DbkTs>gTCUR?T-?C<_AQzVk=ic z!dDw3QC#~TEu4$KmNPns_Qse|tQU}?R}NJ6?Z$JQ+H>xWYHD5Bcg?Ot*}uOH(}%(q zUpSqIL=1kvc%f4H+%BwasPm5Avn<}xcr8(a;QF-s-8{Je@*^RBD&NUM7t61%gl z$<9&3<=zh~#Kpl$P=b9E@sB$fMj$LLm3`_1vErAUX4x9kFdvyBMlnt=VfnxRP)Rm3^SiVg>U`6%48aG zjhS`H==?7tefY**ffH3b`Pn17+}>e#B05Wzeno5R1u&mxx3{YEb__-@2`PM!i&})w zrNwRL^Ow_zm*WWLzsj5mR9&9PNE*;?o-X#i3;1$IZESz#7f|D(ydlZuv`b&as)_b? zLwa7=us$^)rp_niw=JYP;AhYHt`Vn4SZI$&yMX8l>3S@dpZQ&LRM2s~A+7Hm`cUV| zW%!jZgYyQx&5v&_435HP17kWq7t?cuZ7ti0;b|N|G4)ZC*dodRG6h#__=lqqQeLS~rU^*S>?uzkO$8 zjMp9~2t2g&Dv?}y@`~do##i*2{fIwWl)Ej@87geJq!euo?rt|~pGNxP;UVUDC&q{9 zcjD>~RCEeF5z}91#>C`F+JSty80GvY3~5{H#)v3$8^rhF*>GMkR^wtZuO}k)3&~ zE59vM6#8nQfBdP*yl!fdlx}bQ+Cak0EpqBzR^6Emj5kyGqg?4r(afTlrUXYLqo;y>z zk;3L&2p{_LF+Xk|m$o+kBUVVP1V(5q>dx@eQ{(xy<6bhlvK$X;#9ty&JP@ zkar#+u>Qw|3&@;^jK&wW@q%)HDT7Lz!^-iQjdSt_6U9r>P@6ZALN-~~-y_n(V>wEo z$4kbAYqe@GZG*aE9Dj1Urn-kupZSM5>Zx7c+3&!T^rL~;3L~|z8L72>j0T`sVsm_5 z$2b|K)=dw#g(+E9&Kl+ODwzT6OnyBUov$1}W$TtMeM;jzH#kv`ACsTEguinoY}!=n zNa=`=HgDK{>s=M2#D9zdTLK2NvRSR#O|X|rHDA3v$~Meg9zj@%JJ?(vsUKW1TvO3R z&N&~C-op01-k%}x07bO(#`A?34i~u>4|qlGD-7Pv=J0ns-&Eez*wnkFa;P~LL40v- zwDGZ4&$`IF{&nOKA2cVR0pLPk%Uqi+lFXJEpDps`>l@y9fx1z2(-wL4E?%ZdSSi%V zU0-(KN<{^J@yzpXR%^rO9d8VR`icElfG3=Ky}8)!s{e%5vk!F>x1FL+xO?ltC6Uj^ zZ!=`CU#5D&f3H*MZE~UB!I#oz6E=9W6KlM6Dt}0{b}Ay*S=dz)E$`%(XL&J zYg3M+wb^)ShU^VLS4ROLR&L(WE8V#r}&$ zdd^CL($yafw~gPUlX3PP;fL1WcCwwvG~-B!9B%90Kq8W}>}q7kRmYN&qWw-u*ye(! zKHhCOzk?@mSywRC5L`Yar(I%rc!Sf9i?#oh)N+L%W~w(0t5wy?TKD17+R8-3S9~8L zEmNOx-J}>8BE3zJvtXzbJ8{(sh+V8O`E~6Ry+^rMNMv!ESruMlPO_pmj!%-Ut`|ECE;g1)IDD25*Y3<1`Xms&xN8{gp{qRAk zzhb88<{XYgJ$w(;1ds|PBkM|WY~o12S`o`SH}Pkp!jH2mnoYM*OC0J-EKw(J1OywJC?;;KCE*m_{mkywmACzT*iO#g&DtRo;AP zE40t+*eLxtw7T* zsoN0Vw$qdbF-?F^^3fuw4)F5#MCbWYLak1vo6qMt!wD2@ovicd>*ME;mz?{ypaR^5 zWbF}&bdzw=x7Ua`dlD`w7H;CFZ?DNY_V94$wiPun9F+anvim27C#J1`bz;Q^rP*+^ zr|vZi1}ypL^3fR^wY+awgoy3#JoW3-pg=$8(0)vP!CKLFdO63Jb$$z9L?KtK!FT{N z1M}fpb>c!SOcJ72ud-q|ZO2~ZbbU#{fz_WKRWB;?o$N{M~ZpNt$ zHkkK8FTY7IzQE7(OccX*M;u@>lwMNb3JakDn|tM4$3zl)eau{#?wOS@V@{2VOAkOA zeGVZ|QH@V5D$;$l?*|vH zUld*<2)Tb`-{A|s3>;Q?cSV=Eg{cT6*M|z2#H{tHWxa+O>t^e@<|a|=Xxogc4#!;g zZ42(kqcDRs_0zIn>pet)p#Q42|K-Yk)NZHO)=rd8kd>XU{OFQo6}->h(~}hyIeQ*p zJHU3H>e=n={W!`SzNuvV2&DP?add4IRG1>x-aMf+YVRz0`BX?$DxG4Ji2(rKkL{7n zsZZsre6o`?5S?_LVRy0ZRV3YTy@(*QQe$N3)D)vFlIHm)1waXuY>0BNK!e>`*;KpB zhh7PZiid(2;s^jBuk)p)2`ak1>ymcR1;bfCm8$L(Q{@H2&~loG9FPqBeol?fFvfzA z>xV^vLE9p*lri%c-jw!{v1e9pPPTZw+yd)V|)Xq6}twG-27g=qi zh%c3TQyO8;?h*pVGZutR;KbfgB@v3mDxC2uUDKbQqh55QE@T~dHU79Lp1WP?i#Uec zLen*=D93m>T(IU$+nm^lJ=OiSN1(zx+^huX8?ZIVOLy7yu~hfPf;(lU33|^!qz)|vC=l)QJEHIO*)qdK zuV5is{HxN5jE(+LGY}qz935a%MVPwBR^g5wZaM#2>%RU)b9wvEinZ3{T5S3h0w*pH$}>zM>?AIYgy^}~@UQuvJhAJ`q1#Bx+ESTQ z=VUO6L}4_aQK-ezCOg8$M;kBjG)1S6xlObeYc7CNf(JYFx=&Hd1PnSyIS>)2WD>F} ziI13O>eX2pOu|rxuYyW#{HCzSiJ~6`5rihhhhUEI@S^rxre-!cr_& zXW{dSDAX^=&K43SjOBoyj5&uPQF(l;Q$U0u=T5a`QfP%KDFj(x6AHb%phqZN=gly0 zWG%t3Ejvf6%si~z1bkazYXm+x=R4u`vPt4Z^4?l#48z*jGOr${#Kb6O)FEonTn<#h z$P3iN;e>fS`*h~8oil%;zk9vZWyh0;;W&w4KN5xB_w;!7u-(d2(xVKyo3cY4q6N(r z0EV)J+j$R+^tHS%#B@BITtt`C%kkD)6oJP^eqwCwc1AbKes8^h6+m_usg7j=Kk-Xo zT4dgk_SeaRpO!!;ISl|P#K@EGP}L6)e8e3;#3E_UgvkHZpg6Gt6(~{zKsyn#lzzV8 z${tCEk(p6-l56P61buAXv#;!D%=foM?t?#vYJV)BRKj`9EKEviCn-?F83GS^D&VRZTeC+Z^dM}G~W}jYXcJ{ZQ~vH zjamde8nvtX5Sbjlcy@Tl!$G3J5~N zA~b#Aze->m=fn*b2-x|B$+(UNV*ew~ObKp-ip#sS!QPXay+|nlqvjX1?>RhM{ zi$8fU_Lg;wDeswjCkvQ7`d8AFi{Th=x!5~B}37<5J`&| z73vCLY6&WMR{#|OO{{pb{9r^_xhTt#_3~2TS^63RBfsdEXu&WKt3GP&&ym^}K-m~_ zL?XV-y(!kdVC{Hch7rhm(_a?GDG%hOhqB1(D%KBqx|`yA+<@03j51v0fjxwfw5qJ- z!0i&YV#x({=QVCS@djIo?}R-o)S(4XMX;37lkQ3mA$m*fK>IBdN{^M0izd>1lp!k6 zTq!_?u8M`M_5HJS!jTAHxY&X`@C7)>0tG%Z{xXbNKI474wRzBopJE#L_@n@1NlBjL_!867{ zUTIYad7#uEatX8K0-78z+oL1~xB=M2>PcsVrjhn@4BVr41Vwi0oyuSnWY6ObgEO+} zO$Wc>I)Jn0;_p`vWOw9?#Vgo?W8Zji-}hVgzP|MHQA8tlwyFwry*YZ0=Xd{}1h;tO_>av+GP32ag{)yea$!xj(7&L-zPM0dYX zD7==#e%A59k@t(L!+aT_pSMccueBL>u>FdF0yba7;(ZE35%NAoc}`Javwf zvrCE9`9|HxkWS!~@E5WfgY){ulSc@L?dL8#@klKp+0?8!#qZB$9^~1v{bdbNJv$L` zg=GMyoo_5Y$s&mxgdh_qyg@e@@JDBZfY;;M)p*yJ+~_xwovbRzShNJrQJPXOKO`d# zZO_fEDqK2XA~!WXmIU;e)7$Qa{Oc0OmEx zZ<6*X%j1S+j~kZ{`qhHFDgZ+k_ukDyO)3`^uKO-Y7Bi(9E>?D!c)zd%CLSsYAfQ$` zB!^ls(+F$#T#tdDMRF;rV+FZxG5=ZNo_rWoZ0h^vK<)_Ak^}Q;0}8)(yOJU11x!@= zGq$&y7!_ziLX`lSKMPr?n?>fR*tOY{gWU^<0ur+SRPvQOn6`~cNdF4O(1sBKzD(LkZdung+v!LJ$af$2f~7g_43u- zi*ZlH=(@r~(VyaxHB*2LH2`Z9X~;10Vt|*Md(>RZzc@HHyOT3VNWF6&8HPG@kFcMj z#j{-So`)2y&$}`c<9PN4p^|;lpki1g{wsui*jptZ)UTNw_w@Nhtcl662mvOFk%l-f z`?`(mhN`f9FzYu;_MfG^*N#FCb`S4?Fw7O5vM!#GE8}LOHkCP$emoNl@cqTqIiZkb zTDnUI%kSwXJrOcX+A$%zL0!thqK!k5p@-I>AEWe4Y0dZYS{!eMmJw3^CO0+8I+X{; zFhFapR4Z8!xSzO8Lzx^pLjTxQI)T{F+M?;?J%;&Kli_;lu#avJJvDIS4T`{@ziY|x zjfPyP#TANGMg_7UOye0~;~b>a>6Oc;9DjBZPK_wb4OcT-fJP)DiUkoXT=o1=M#)C8 zB#P)#0o-H&WY`6I5aKi=H%0lV`n6J zZ~5SJOb=(|R)mWIdWhDG(s(LDwvR0%9Fo<*TdxuqkZO06gd9#IBlK`RQg^^ll{mbu zPHIq5BKxbSZO|9*efpgEkn(;W_tX_`G_s=`DHmLhmelf`CTA)*6d7(L3B=@4wTsSv z|E^*k@ay4Igm=l3J*lEm*ded~^$mw%Q3M2;glb*IbLTD5?&xd&4W<+Kl>*`O@I}1n}p?$FYAeWO_y=yj_{2F zO`{sAzjv%+#Hb2^T2?1~YouVMX2D*)>XzehYv-MtFl@^N6dyv!R*9H4j)lh1@>O5g zmreR`O@E80tsrDwJ-w;Bib@J6aDgCRCMXR>b& zs+yB%+PzE~KKgXcYi4dXziwTAr?O5J{4@`Mt3#iimsh2In@mW%yl}K0F+y}KWmNGK z&s;8H5QD))jl#m>1EgP|EiG+L%MUK`SX%MX71`=Jb};(&dVzm+y7~~whxCE@Kl|2c z0>}rmZtUNIN<4EWLHpQGT%T`JgmDV$9}7VL1a?x8Q=XI_Ek4`{hR)?k%)3d{@cbY} zuvfB9fYN|wXiW>Ci;_1p)kzckr6JHT!;w8r)<;hQ)Xk+5^f2+=sNhQ-gJ9ufs)+FO4*;TuaJ! zo1+nnn^RXRx=*x9I3wiBe!|HL=1l3|>A|67NMc#flZ)nO&Aa)n;C8_LqAz z)AuJt1x16wWP&O!iq&Y&rIv3OG$r-LbVqQi9qCwmBVGRufq)?4CdH7xi1)y39Au^TA>p&3q+No{^XTX!m!?R6zQetx>4r5`N_3c&mOJw3V7BG`Va zn{)i1_FgH<4+w7H7qVr!XGj+p05pI}8Al(K@PQ8>;QZv7Y9=`kF&kHvb~uJ&kE>1y zpv=Aiy&+tr3=I{t6|O(HnanZhPN;&P@Mmr^&*_`ZZm5Y_(iP#uAJ3qo{N&+jo;?rg zPI$3GJ$HYy=G(N5W$Ns~!u93he6xNvug1XcINTqxtHXzBd?*W-x>N!4AvFUMJi@Wb z!u-YWyvU{Z62YG7x9nJ(d3nVhw6Sqs%5wAk7kGc-aDS!fXACDFf!a&NqGeZV;3i72 zgeg;24q3m{2k}Daki03AM?xTPPPF|ByACemM2Rv+NpNE#(><@wq{68>${oC$fYJaq zw99vSXWvN*3Dx5tobKUmy6E_d+Wk0|n{Vlh)we50!Oscta)HK#5R9&@SoBF~qp_m( zmGKJ%d+VC#H?|xtq$NfiE9h!|GT{dBK=JBM#7H*m7=3jFF3@E6BA-EHf_rweEV+s& zUU?{}5iXjdK1H2$+bPW6!;|+pxhS>nGg~*BoL0?wZGmS81`u|l&Au_gl9L?GAl@H~ zao2{e)wW_zUhxl?D>}Ns)@!pQdZ>CMYl370nW`x@aB?uM`f(RB&pabpKUrVCC9Ze4 zJCVr1Qy(ppfWA&$cmI0?PV5(tdIK0>ewx$fx<+O^tf^2#!w6>r|qh4u}bFkjsr6@LQeHa@_4N zsHth!im~Eup5D$?mGJlV7N2W0HoV@M7qOP$F03?~@^fKTB@6scFaVW)Zo-dZ$i1m6 z1~}ljuTDK&9rLV|ZCp?+Lyq6vf7qy|Nf(3U&}1E-B@7&lU%C>#^2J-@%W~Jax%&qSTR> zo|n+q<9PxX?Z9KsWA0fj6SP6`(K?c+Uh=cEnhQ9V&K~CY^rc#1L}1pQ;PW| zJ#7%gbNn$i`2Yo-Wj5XR`k<93BuW+c^EA1E%M&HjFA^k=rWfo3)FgKG>^Q`&A3CAb zH5E($UKSK!zOLn^rL21#WpM4?v{k=`oS^d*l!>B=TCb7Zq)v>9cLv)vPDBX2k(*sO z;*2Zc==TF6So+uMm%kh;ko0WwXUQKN5bF(apDK_&EwG@oWF!Royg6Q_}DGf*N8nL{#)vZpDfV*H`5v9={`Wyi^5BF zAA8ixbG35;f3j&76|)t%Ty#*pYPc{sNDUTyTbv&_!)aSzjr`UdB)iPHd4ZOtTbXV< zE99EPho4P}v5>f6vo5Mkn6|d>MMuiUM&)_=-Lueq(Yz5M`a#whz z(3CH|UtR5c6nW)6s8-rz#;fQ(e3}r&OW5=nQ@9U<_gI8|k)uic$@l?wQhjvz!v5K% zx_JeE-E#ETPj@#(5c1v8vHX^w;6z!;=i;i>9-iT&Rz1RwLta6-Pm!WO zP+PYFVeuDlcx(vlBfB&}0NGFx?{LCd59d7QJ8m85uGL&Uy%J1Lv-9X@QN3Chu3&mh z|IoH*@NH_b+pPJ@dzg(qgRy2*fj;kMF4MSc!UY}ZQ zwV+HQ5DB+8&pNU_@+V_%yklv?uchZqk%U|=t(xZHVPbw#w1Y+n^4{|V?S(zLniv`5 zMF9A%76!HFGymF--znkyI`8#;O#LQA=

5X^8m zePq^Tf5o6-v(tE6dyE3L~eL1W!;7?BQjji;t>T&Xu_AmUQ@Rnfg zgfpvK7D^6%_;X!bT=JPScbNFQn(dOnBM&lz{0)`L>+Y9_O}Iii`Ptf(5SsWs*kv1~9E1udPhNba zGmckV&nExu@5G1Q2%Useqjg?C$xYi@6=5NR5`lDU1QwU{R4xr9nEi#2=l{453om}KdR7R)pv6;*e|upNGq|faWg9DQKt=F zppA>P@jX?M>&@)=I=wnY?eWX6Fa`a|+E=2i9`%5JWLL>A-oQ7G5|V7yaMIt?F``bD z4jdYENVA~!iy7&Gqkp!_Y}r0y<~`YW^-YN+%d2c6QoNu=`O z_@cVy2Xuh?Q$QTd$JDX!qz|f}sgAp0{sc3wuw~^yrR&hzW|!*(nz^&R81hsvO~4#6 ziH?3X_{>4)`1oq2vG5=?9IUaCJ#n0oURZX66Iu6H4ic@DVg2|?ZelpvWW)T z_)Hxri^<@|aNu{fGtXAQCAZUg#V#NWPnMgbyMr5k zWAk0>cc8ya5uGYEa-%-eUe($Ij(L_hIBoGC9rd(oH*e_v{&D+FjsICKdL+DcamfMb z`sfQDCH;AYz37OM_hD)FbmgWsE7l|^McJ81Mp@|K>kRCcJM?`ZTN=zSbD@4{jsj(v+sK0(or5kpKdWWKh_U0?SSk`B?5 zdjarA)Ri91zI%$ez4u3^&b0oY8H;PJ+7wS;d)xG6X&Ljj`2b#D`g&Ijjft$VYmgiZ zas9q!a*XqJmr~(ZGaBE;r1#cuzGgiml}3a@A3wt*UFHuW7jU= zw9s}V;tg1#cR4S%l=g%vJbxs~)J5yFI$?!oa90t83=J3j!8FM%^^zf2E4{mviX??Q zta*yBflfrm<`HT9Ou=m|kMb3-qd1qKR)*lp9jc$9Re*E~%lG?ie0gaVsR{{`cmEI6 Cd^~jk diff --git a/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html b/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html deleted file mode 100644 index 62df7fa51163..000000000000 --- a/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -

- -
- - diff --git a/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html b/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html deleted file mode 100644 index e3d14a61f930..000000000000 --- a/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
- -
- - diff --git a/layout/reftests/pixel-rounding/reftest.list b/layout/reftests/pixel-rounding/reftest.list index 5dc55cde480c..5a775b41570f 100644 --- a/layout/reftests/pixel-rounding/reftest.list +++ b/layout/reftests/pixel-rounding/reftest.list @@ -123,10 +123,6 @@ fails == collapsed-border-top-6.html border-top-10-ref.html == image-width-left-5.html image-width-5.html == image-width-left-6.html image-width-6.html - -pref(image.high_quality_downscaling.enabled,true) == image-high-quality-scaling-1.html image-high-quality-scaling-1-ref.html - - != offscreen-0-ref.html offscreen-10-ref.html == offscreen-background-color-pos-4.html offscreen-0-ref.html == offscreen-background-color-pos-5.html offscreen-10-ref.html From 611ec988a9e030054490fc8895efd086a5688b26 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 22 Apr 2015 13:14:35 +0200 Subject: [PATCH 113/241] Backed out changeset 60bbc4230cd7 (bug 1085783) --- layout/base/nsLayoutUtils.cpp | 74 ++++++++++++++--------------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index b22e5cad1b3e..204c1676fd6a 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5831,12 +5831,11 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, // Avoid unnecessarily large offsets. bool doTile = !aDest.Contains(aFill); - nsRect appUnitDest = doTile ? TileNearRect(aDest, aFill.Intersect(aDirty)) - : aDest; - nsPoint anchor = aAnchor + (appUnitDest.TopLeft() - aDest.TopLeft()); + nsRect dest = doTile ? TileNearRect(aDest, aFill.Intersect(aDirty)) : aDest; + nsPoint anchor = aAnchor + (dest.TopLeft() - aDest.TopLeft()); gfxRect devPixelDest = - nsLayoutUtils::RectToGfxRect(appUnitDest, aAppUnitsPerDevPixel); + nsLayoutUtils::RectToGfxRect(dest, aAppUnitsPerDevPixel); gfxRect devPixelFill = nsLayoutUtils::RectToGfxRect(aFill, aAppUnitsPerDevPixel); gfxRect devPixelDirty = @@ -5844,57 +5843,52 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, gfxMatrix currentMatrix = aCtx->CurrentMatrix(); gfxRect fill = devPixelFill; - gfxRect dest = devPixelDest; bool didSnap; // Snap even if we have a scale in the context. But don't snap if // we have something that's not translation+scale, or if the scale flips in // the X or Y direction, because snapped image drawing can't handle that yet. if (!currentMatrix.HasNonAxisAlignedTransform() && currentMatrix._11 > 0.0 && currentMatrix._22 > 0.0 && - aCtx->UserToDevicePixelSnapped(fill, true) && - aCtx->UserToDevicePixelSnapped(dest, true)) { - // We snapped. On this code path, |fill| and |dest| take into account - // currentMatrix's transform. + aCtx->UserToDevicePixelSnapped(fill, true)) { didSnap = true; + if (fill.IsEmpty()) { + return SnappedImageDrawingParameters(); + } } else { - // We didn't snap. On this code path, |fill| and |dest| do not take into - // account currentMatrix's transform. didSnap = false; fill = devPixelFill; - dest = devPixelDest; } - // If we snapped above, |dest| already takes into account |currentMatrix|'s scale - // and has integer coordinates. If not, we need these properties to compute - // the optimal drawn image size, so compute |snappedDestSize| here. - gfxSize snappedDestSize = dest.Size(); - if (!didSnap) { - gfxSize scaleFactors = currentMatrix.ScaleFactors(true); - snappedDestSize.Scale(scaleFactors.width, scaleFactors.height); - snappedDestSize.width = NS_round(snappedDestSize.width); - snappedDestSize.height = NS_round(snappedDestSize.height); - } - - // We need to be sure that this is at least one pixel in width and height, - // or we'll end up drawing nothing even if we have a nonempty fill. - snappedDestSize.width = std::max(snappedDestSize.width, 1.0); - snappedDestSize.height = std::max(snappedDestSize.height, 1.0); - - // Bail if we're not going to end up drawing anything. - if (fill.IsEmpty() || snappedDestSize.IsEmpty()) { + // Apply the context's scale to the dest rect. + gfxSize destScale = didSnap ? gfxSize(currentMatrix._11, currentMatrix._22) + : currentMatrix.ScaleFactors(true); + gfxSize appUnitScaledDest(dest.width * destScale.width, + dest.height * destScale.height); + gfxSize scaledDest = appUnitScaledDest / aAppUnitsPerDevPixel; + if (scaledDest.IsEmpty()) { return SnappedImageDrawingParameters(); } + // Compute a snapped version of the scaled dest rect, which we'll use to + // determine the optimal image size to draw with. We need to be sure that + // this rect is at least one pixel in width and height, or we'll end up + // drawing nothing even if we have a nonempty fill. + gfxSize snappedScaledDest = + gfxSize(NSAppUnitsToIntPixels(appUnitScaledDest.width, aAppUnitsPerDevPixel), + NSAppUnitsToIntPixels(appUnitScaledDest.height, aAppUnitsPerDevPixel)); + snappedScaledDest.width = std::max(snappedScaledDest.width, 1.0); + snappedScaledDest.height = std::max(snappedScaledDest.height, 1.0); + nsIntSize intImageSize = - aImage->OptimalImageSizeForDest(snappedDestSize, + aImage->OptimalImageSizeForDest(snappedScaledDest, imgIContainer::FRAME_CURRENT, aGraphicsFilter, aImageFlags); gfxSize imageSize(intImageSize.width, intImageSize.height); - // XXX(seth): May be buggy; see bug 1151016. CSSIntSize svgViewportSize = currentMatrix.IsIdentity() ? CSSIntSize(intImageSize.width, intImageSize.height) - : CSSIntSize(devPixelDest.width, devPixelDest.height); + : CSSIntSize(NSAppUnitsToIntPixels(dest.width, aAppUnitsPerDevPixel), //XXX BUG! + NSAppUnitsToIntPixels(dest.height, aAppUnitsPerDevPixel)); //XXX BUG! // Compute the set of pixels that would be sampled by an ideal rendering gfxPoint subimageTopLeft = @@ -5910,9 +5904,8 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, gfxMatrix transform; gfxMatrix invTransform; - bool anchorAtUpperLeft = anchor.x == appUnitDest.x && - anchor.y == appUnitDest.y; - bool exactlyOneImageCopy = aFill.IsEqualEdges(appUnitDest); + bool anchorAtUpperLeft = anchor.x == dest.x && anchor.y == dest.y; + bool exactlyOneImageCopy = aFill.IsEqualEdges(dest); if (anchorAtUpperLeft && exactlyOneImageCopy) { // The simple case: we can ignore the anchor point and compute the // transformation from the sampled region (the subimage) to the fill rect. @@ -5940,14 +5933,7 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, anchorPoint = StableRound(anchorPoint); } - // Compute an unsnapped version of the dest rect's size. We continue to - // follow the pattern that we take |currentMatrix| into account only if - // |didSnap| is true. - gfxSize unsnappedDestSize - = didSnap ? devPixelDest.Size() * currentMatrix.ScaleFactors(true) - : devPixelDest.Size(); - - gfxRect anchoredDestRect(anchorPoint, unsnappedDestSize); + gfxRect anchoredDestRect(anchorPoint, scaledDest); gfxRect anchoredImageRect(imageSpaceAnchorPoint, imageSize); // Calculate anchoredDestRect with snapped fill rect when the devPixelFill rect From f6bf2cb1164f12eaddb29f583f309f818c7366de Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 22 Apr 2015 13:18:03 +0200 Subject: [PATCH 114/241] Backed out changeset dc6d37458b88 (bug 1068881) for windows 7 reftest perma failure --- .../image-scrolling-zoom-1-notref.html | 36 ------------- .../image-scrolling-zoom-1-ref.html | 36 ------------- .../invalidation/image-scrolling-zoom-1.html | 51 ------------------ .../one-pixel-wide-background.png | Bin 1059 -> 0 bytes layout/reftests/invalidation/reftest.list | 2 - 5 files changed, 125 deletions(-) delete mode 100644 layout/reftests/invalidation/image-scrolling-zoom-1-notref.html delete mode 100644 layout/reftests/invalidation/image-scrolling-zoom-1-ref.html delete mode 100644 layout/reftests/invalidation/image-scrolling-zoom-1.html delete mode 100644 layout/reftests/invalidation/one-pixel-wide-background.png diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1-notref.html b/layout/reftests/invalidation/image-scrolling-zoom-1-notref.html deleted file mode 100644 index 524109ff9651..000000000000 --- a/layout/reftests/invalidation/image-scrolling-zoom-1-notref.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - -
-
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
-
- - diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html b/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html deleted file mode 100644 index e989d0e86376..000000000000 --- a/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - -
-
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
-
- - diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1.html b/layout/reftests/invalidation/image-scrolling-zoom-1.html deleted file mode 100644 index 85a2753b0367..000000000000 --- a/layout/reftests/invalidation/image-scrolling-zoom-1.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - -
-
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
Item
-
-
- - - diff --git a/layout/reftests/invalidation/one-pixel-wide-background.png b/layout/reftests/invalidation/one-pixel-wide-background.png deleted file mode 100644 index 09f59e39ac05bad3f390aeecd72bf750069b738a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1059 zcmZ{jPm9w)7{+G}ENhlMErO^EA$mXzscg4K{K770hfbumQjoG;W1Wie71~YPk%{)%I z8vr*){4>TZ(DFD+GL(1p!h!g=kfE*>7WTTMkNX3yODNV_X4ABEPt`QdrL#F2`j0D| zk2?A*#!>{~VzDq64U^E9&~CTe&~l*T7~ElGX9){(BgyWTi!9giaWUSLs1kK6y#>i#Z?Q;M@p_*<1<*6RKt&Pa4BmVcgv%yTNFCfBLSYTkRW zWMr`pjMo9OC;{RiP*JI|AI3N-a^bnJ)$3fBM1(#|gDDo}DiBGkyNf6jDT*bBktQn8 zh2mG1e(kbv3Y9mGr}6_`Hle5fdUx*!@5>uKe}A;KH~oEa@o-mB6las#0MIYW=Iyti Q6w$f8N5}s8!HYM40j82W^#A|> diff --git a/layout/reftests/invalidation/reftest.list b/layout/reftests/invalidation/reftest.list index 34081a30e114..df3ef58d958e 100644 --- a/layout/reftests/invalidation/reftest.list +++ b/layout/reftests/invalidation/reftest.list @@ -64,5 +64,3 @@ pref(layout.animated-image-layers.enabled,true) random-if(Android||gtk2Widget) = skip-if(asyncPanZoom&&winWidget) != layer-splitting-5.html about:blank skip-if(asyncPanZoom&&winWidget) != layer-splitting-6.html about:blank != layer-splitting-7.html about:blank -fuzzy-if(gtk2Widget,2,4) == image-scrolling-zoom-1.html image-scrolling-zoom-1-ref.html -!= image-scrolling-zoom-1-ref.html image-scrolling-zoom-1-notref.html From 615e9c5418b9d6b06dd260c348e5f1660fb9372b Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 115/241] Bug 1149163 part 1 - Clean up nsHTMLEditRules::GetInnerContent; r=froydnj --- editor/libeditor/nsHTMLEditRules.cpp | 81 ++++++++++++++++------------ editor/libeditor/nsHTMLEditRules.h | 11 +++- 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 875b2fed0a12..c571edcf67dc 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -13,6 +13,7 @@ #include "mozilla/Preferences.h" #include "mozilla/dom/Selection.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/OwningNonNull.h" #include "mozilla/mozalloc.h" #include "nsAString.h" #include "nsAlgorithm.h" @@ -5158,44 +5159,58 @@ nsHTMLEditRules::CheckForInvisibleBR(nsIDOMNode *aBlock, } -/////////////////////////////////////////////////////////////////////////// -// GetInnerContent: aList and aTbl allow the caller to specify what kind -// of content to "look inside". If aTbl is true, look inside -// any table content, and insert the inner content into the -// supplied issupportsarray at offset aIndex. -// Similarly with aList and list content. -// aIndex is updated to point past inserted elements. -// +//////////////////////////////////////////////////////////////////////////////// +// GetInnerContent: aList and aTbl allow the caller to specify what kind of +// content to "look inside". If aTbl is true, look inside any +// table content, and insert the inner content into the +// supplied issupportsarray at offset aIndex. Similarly with +// aList and list content. aIndex is updated to point past +// inserted elements. +// nsresult -nsHTMLEditRules::GetInnerContent(nsIDOMNode *aNode, nsCOMArray &outArrayOfNodes, - int32_t *aIndex, bool aList, bool aTbl) +nsHTMLEditRules::GetInnerContent(nsIDOMNode* aNode, + nsCOMArray& aOutArrayOfDOMNodes, + int32_t* aIndex, bool aLists, bool aTables) { - nsCOMPtr aNode_ = do_QueryInterface(aNode); - NS_ENSURE_TRUE(aNode_ && aIndex, NS_ERROR_NULL_POINTER); - - nsCOMPtr node = - GetAsDOMNode(mHTMLEditor->GetFirstEditableChild(*aNode_)); - nsresult res = NS_OK; - while (NS_SUCCEEDED(res) && node) - { - if ( ( aList && (nsHTMLEditUtils::IsList(node) || - nsHTMLEditUtils::IsListItem(node) ) ) - || ( aTbl && nsHTMLEditUtils::IsTableElement(node) ) ) - { - res = GetInnerContent(node, outArrayOfNodes, aIndex, aList, aTbl); - NS_ENSURE_SUCCESS(res, res); + // To be removed in a subsequent patch + nsCOMPtr node = do_QueryInterface(aNode); + NS_ENSURE_STATE(node); + nsTArray> aOutArrayOfNodes; + for (int32_t i = 0; i < aOutArrayOfDOMNodes.Count(); i++) { + nsCOMPtr newNode = do_QueryInterface(aOutArrayOfDOMNodes[i]); + if (newNode) { + aOutArrayOfNodes.AppendElement(newNode); } - else - { - outArrayOfNodes.InsertObjectAt(node, *aIndex); - (*aIndex)++; - } - nsCOMPtr tmp; - res = node->GetNextSibling(getter_AddRefs(tmp)); - node = tmp; + } + GetInnerContent(*node, aOutArrayOfNodes, aIndex, + aLists ? Lists::yes : Lists::no, + aTables ? Tables::yes : Tables::no); + aOutArrayOfDOMNodes.Clear(); + for (auto& node : aOutArrayOfNodes) { + aOutArrayOfDOMNodes.AppendElement(GetAsDOMNode(node)); } - return res; + return NS_OK; +} + +void +nsHTMLEditRules::GetInnerContent(nsINode& aNode, + nsTArray>& aOutArrayOfNodes, + int32_t* aIndex, Lists aLists, Tables aTables) +{ + MOZ_ASSERT(aIndex); + + for (nsCOMPtr node = mHTMLEditor->GetFirstEditableChild(aNode); + node; node = node->GetNextSibling()) { + if ((aLists == Lists::yes && (nsHTMLEditUtils::IsList(node) || + nsHTMLEditUtils::IsListItem(node))) || + (aTables == Tables::yes && nsHTMLEditUtils::IsTableElement(node))) { + GetInnerContent(*node, aOutArrayOfNodes, aIndex, aLists, aTables); + } else { + aOutArrayOfNodes.InsertElementAt(*aIndex, node); + (*aIndex)++; + } + } } /////////////////////////////////////////////////////////////////////////// diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 01760d2cffaf..01eeffa5a25a 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -198,7 +198,16 @@ protected: nsresult AppendInnerFormatNodes(nsCOMArray& aArray, nsIDOMNode *aNode); nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat); - nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray& outArrayOfNodes, int32_t *aIndex, bool aList = true, bool aTble = true); + enum class Lists { no, yes }; + enum class Tables { no, yes }; + nsresult GetInnerContent(nsIDOMNode* aNode, + nsCOMArray& aOutArrayOfNodes, + int32_t* aIndex, bool aLists = true, + bool aTables = true); + void GetInnerContent(nsINode& aNode, + nsTArray>& aOutArrayOfNodes, + int32_t* aIndex, Lists aLists = Lists::yes, + Tables aTables = Tables::yes); already_AddRefed IsInListItem(nsIDOMNode* aNode); mozilla::dom::Element* IsInListItem(nsINode* aNode); nsresult ReturnInHeader(mozilla::dom::Selection* aSelection, From b0c93122c4a5ff05e7f14f41189b2f4afc01f975 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 116/241] Bug 1149163 part 2 - Make nsDOMIterator infallible; r=froydnj --- editor/libeditor/nsEditorUtils.cpp | 82 +++++++++---------------- editor/libeditor/nsEditorUtils.h | 22 +++---- editor/libeditor/nsHTMLDataTransfer.cpp | 7 +-- editor/libeditor/nsHTMLEditRules.cpp | 46 +++++--------- 4 files changed, 59 insertions(+), 98 deletions(-) diff --git a/editor/libeditor/nsEditorUtils.cpp b/editor/libeditor/nsEditorUtils.cpp index 210a201beffe..3e7433dd2856 100644 --- a/editor/libeditor/nsEditorUtils.cpp +++ b/editor/libeditor/nsEditorUtils.cpp @@ -66,91 +66,69 @@ nsAutoSelectionReset::Abort() * some helper classes for iterating the dom tree *****************************************************************************/ -nsDOMIterator::nsDOMIterator() : -mIter(nullptr) +nsDOMIterator::nsDOMIterator(nsRange& aRange) +{ + MOZ_ASSERT(aRange.GetStartParent(), "Invalid range"); + mIter = NS_NewContentIterator(); + DebugOnly res = mIter->Init(&aRange); + MOZ_ASSERT(NS_SUCCEEDED(res)); +} + +nsDOMIterator::nsDOMIterator(nsIDOMNode& aNode) +{ + mIter = NS_NewContentIterator(); + nsCOMPtr node = do_QueryInterface(&aNode); + NS_ENSURE_TRUE(node, ); + DebugOnly res = mIter->Init(node); + MOZ_ASSERT(NS_SUCCEEDED(res)); +} + +nsDOMIterator::nsDOMIterator() { } - + nsDOMIterator::~nsDOMIterator() { } - -nsresult -nsDOMIterator::Init(nsRange* aRange) -{ - nsresult res; - mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res); - NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE); - return mIter->Init(aRange); -} -nsresult -nsDOMIterator::Init(nsIDOMNode* aNode) -{ - nsresult res; - mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res); - NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE); - nsCOMPtr content = do_QueryInterface(aNode); - return mIter->Init(content); -} - -nsresult +void nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor, nsTArray>& arrayOfNodes) const { // Iterate through dom and build list - while (!mIter->IsDone()) { + for (; !mIter->IsDone(); mIter->Next()) { nsCOMPtr node = mIter->GetCurrentNode(); - NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); if (functor(node)) { arrayOfNodes.AppendElement(node); } - mIter->Next(); } - return NS_OK; } -nsresult +void nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor, nsCOMArray& arrayOfNodes) const { - nsCOMPtr node; - // iterate through dom and build list - while (!mIter->IsDone()) - { - node = do_QueryInterface(mIter->GetCurrentNode()); - NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); + for (; !mIter->IsDone(); mIter->Next()) { + nsCOMPtr node = mIter->GetCurrentNode()->AsDOMNode(); - if (functor(node)) - { + if (functor(node)) { arrayOfNodes.AppendObject(node); } - mIter->Next(); } - return NS_OK; } -nsDOMSubtreeIterator::nsDOMSubtreeIterator() +nsDOMSubtreeIterator::nsDOMSubtreeIterator(nsRange& aRange) { + mIter = NS_NewContentSubtreeIterator(); + DebugOnly res = mIter->Init(&aRange); + MOZ_ASSERT(NS_SUCCEEDED(res)); } - + nsDOMSubtreeIterator::~nsDOMSubtreeIterator() { } - -nsresult -nsDOMSubtreeIterator::Init(nsRange* aRange) -{ - nsresult res; - mIter = do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res); - NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE); - return mIter->Init(aRange); -} /****************************************************************************** * some general purpose editor utils diff --git a/editor/libeditor/nsEditorUtils.h b/editor/libeditor/nsEditorUtils.h index 868572d9232d..e76c3f064251 100644 --- a/editor/libeditor/nsEditorUtils.h +++ b/editor/libeditor/nsEditorUtils.h @@ -177,26 +177,26 @@ class nsBoolDomIterFunctor class MOZ_STACK_CLASS nsDOMIterator { public: - nsDOMIterator(); + explicit nsDOMIterator(nsRange& aRange); + explicit nsDOMIterator(nsIDOMNode& aNode); virtual ~nsDOMIterator(); - - nsresult Init(nsRange* aRange); - nsresult Init(nsIDOMNode* aNode); - nsresult AppendList(nsBoolDomIterFunctor& functor, - nsTArray>& arrayOfNodes) const; - nsresult AppendList(nsBoolDomIterFunctor& functor, - nsCOMArray& arrayOfNodes) const; + + void AppendList(nsBoolDomIterFunctor& functor, + nsTArray>& arrayOfNodes) const; + void AppendList(nsBoolDomIterFunctor& functor, + nsCOMArray& arrayOfNodes) const; protected: nsCOMPtr mIter; + + // For nsDOMSubtreeIterator + nsDOMIterator(); }; class MOZ_STACK_CLASS nsDOMSubtreeIterator : public nsDOMIterator { public: - nsDOMSubtreeIterator(); + explicit nsDOMSubtreeIterator(nsRange& aRange); virtual ~nsDOMSubtreeIterator(); - - nsresult Init(nsRange* aRange); }; class nsTrivialFunctor : public nsBoolDomIterFunctor diff --git a/editor/libeditor/nsHTMLDataTransfer.cpp b/editor/libeditor/nsHTMLDataTransfer.cpp index 284a08ef78bf..72918fa0c173 100644 --- a/editor/libeditor/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/nsHTMLDataTransfer.cpp @@ -2197,11 +2197,10 @@ nsresult nsHTMLEditor::CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode, // now use a subtree iterator over the range to create a list of nodes nsTrivialFunctor functor; - nsDOMSubtreeIterator iter; - rv = iter.Init(docFragRange); - NS_ENSURE_SUCCESS(rv, rv); + nsDOMSubtreeIterator iter(*docFragRange); + iter.AppendList(functor, outNodeList); - return iter.AppendList(functor, outNodeList); + return NS_OK; } nsresult diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index c571edcf67dc..a2a8d68f9387 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -2440,11 +2440,8 @@ nsHTMLEditRules::WillDeleteSelection(Selection* aSelection, // Build a list of nodes in the range nsTArray> arrayOfNodes; nsTrivialFunctor functor; - nsDOMSubtreeIterator iter; - res = iter.Init(range); - NS_ENSURE_SUCCESS(res, res); - res = iter.AppendList(functor, arrayOfNodes); - NS_ENSURE_SUCCESS(res, res); + nsDOMSubtreeIterator iter(*range); + iter.AppendList(functor, arrayOfNodes); // Now that we have the list, delete non-table elements int32_t listCount = arrayOfNodes.Length(); @@ -4933,11 +4930,8 @@ nsHTMLEditRules::AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType) // gather list of table cells or list items nsCOMArray arrayOfNodes; nsTableCellAndListItemFunctor functor; - nsDOMIterator iter; - res = iter.Init(aNode); - NS_ENSURE_SUCCESS(res, res); - res = iter.AppendList(functor, arrayOfNodes); - NS_ENSURE_SUCCESS(res, res); + nsDOMIterator iter(*aNode); + iter.AppendList(functor, arrayOfNodes); // now that we have the list, align their contents as requested int32_t listCount = arrayOfNodes.Count(); @@ -5939,13 +5933,10 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& inArrayOfRang { opRange = inArrayOfRanges[i]; - nsDOMSubtreeIterator iter; - res = iter.Init(opRange); - NS_ENSURE_SUCCESS(res, res); + nsDOMSubtreeIterator iter(*opRange); if (outArrayOfNodes.Count() == 0) { nsTrivialFunctor functor; - res = iter.AppendList(functor, outArrayOfNodes); - NS_ENSURE_SUCCESS(res, res); + iter.AppendList(functor, outArrayOfNodes); } else { // We don't want duplicates in outArrayOfNodes, so we use an @@ -5953,8 +5944,7 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& inArrayOfRang // outArrayOfNodes. nsCOMArray nodes; nsUniqueFunctor functor(outArrayOfNodes); - res = iter.AppendList(functor, nodes); - NS_ENSURE_SUCCESS(res, res); + iter.AppendList(functor, nodes); if (!outArrayOfNodes.AppendObjects(nodes)) return NS_ERROR_OUT_OF_MEMORY; } @@ -6344,11 +6334,8 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsIDOMNode *inNode, // the inline container. nsCOMArray arrayOfBreaks; nsBRNodeFunctor functor; - nsDOMIterator iter; - nsresult res = iter.Init(inNode); - NS_ENSURE_SUCCESS(res, res); - res = iter.AppendList(functor, arrayOfBreaks); - NS_ENSURE_SUCCESS(res, res); + nsDOMIterator iter(*inNode); + iter.AppendList(functor, arrayOfBreaks); // if there aren't any breaks, just put inNode itself in the array int32_t listCount = arrayOfBreaks.Count(); @@ -6376,7 +6363,7 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsIDOMNode *inNode, splitParentNode = GetAsDOMNode(nsEditor::GetNodeLocation(breakNode, &splitOffset)); NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->SplitNodeDeep(splitDeepNode, splitParentNode, splitOffset, + nsresult res = mHTMLEditor->SplitNodeDeep(splitDeepNode, splitParentNode, splitOffset, &resultOffset, false, address_of(leftNode), address_of(rightNode)); NS_ENSURE_SUCCESS(res, res); // put left node in node list @@ -6404,7 +6391,7 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsIDOMNode *inNode, return NS_ERROR_FAILURE; } } - return res; + return NS_OK; } @@ -7622,11 +7609,8 @@ nsHTMLEditRules::AdjustSpecialBreaks(bool aSafeToAskFrames) // gather list of empty nodes NS_ENSURE_STATE(mHTMLEditor); nsEmptyEditableFunctor functor(mHTMLEditor); - nsDOMIterator iter; - nsresult res = iter.Init(mDocChangeRange); - NS_ENSURE_SUCCESS(res, res); - res = iter.AppendList(functor, arrayOfNodes); - NS_ENSURE_SUCCESS(res, res); + nsDOMIterator iter(*mDocChangeRange); + iter.AppendList(functor, arrayOfNodes); // put moz-br's into these empty li's and td's nodeCount = arrayOfNodes.Count(); @@ -7639,13 +7623,13 @@ nsHTMLEditRules::AdjustSpecialBreaks(bool aSafeToAskFrames) uint32_t len; nsCOMPtr theNode = arrayOfNodes[0]; arrayOfNodes.RemoveObjectAt(0); - res = nsEditor::GetLengthOfDOMNode(theNode, len); + nsresult res = nsEditor::GetLengthOfDOMNode(theNode, len); NS_ENSURE_SUCCESS(res, res); res = CreateMozBR(theNode, (int32_t)len); NS_ENSURE_SUCCESS(res, res); } - return res; + return NS_OK; } nsresult From d62de0f8961940165ef03fa79fbd0868588c340c Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 117/241] Bug 1149163 part 3 - Clean up nsHTMLEditRules::BustUpInlinesAtBRs; r=froydnj --- editor/libeditor/nsHTMLEditRules.cpp | 132 +++++++++++++-------------- editor/libeditor/nsHTMLEditRules.h | 4 +- 2 files changed, 65 insertions(+), 71 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index a2a8d68f9387..525167462b7b 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -6014,18 +6014,23 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& inArrayOfRang int32_t listCount = outArrayOfNodes.Count(); for (i=listCount-1; i>=0; i--) { - nsCOMPtr node = outArrayOfNodes[i]; - if (!aDontTouchContent && IsInlineNode(node) && + nsCOMPtr node = do_QueryInterface(outArrayOfNodes[i]); + NS_ENSURE_STATE(node); + if (!aDontTouchContent && IsInlineNode(GetAsDOMNode(node)) && (!mHTMLEditor || mHTMLEditor->IsContainer(node)) && (!mHTMLEditor || !mHTMLEditor->IsTextNode(node))) { NS_ENSURE_STATE(mHTMLEditor); - nsCOMArray arrayOfInlines; - res = BustUpInlinesAtBRs(node, arrayOfInlines); + nsTArray> arrayOfInlines; + res = BustUpInlinesAtBRs(*node, arrayOfInlines); NS_ENSURE_SUCCESS(res, res); + nsCOMArray arrayOfInlinesDOM; + for (auto& inlineNode : arrayOfInlines) { + arrayOfInlinesDOM.AppendObject(GetAsDOMNode(inlineNode)); + } // put these nodes in outArrayOfNodes, replacing the current node outArrayOfNodes.RemoveObjectAt(i); - outArrayOfNodes.InsertObjectsAt(arrayOfInlines, i); + outArrayOfNodes.InsertObjectsAt(arrayOfInlinesDOM, i); } } } @@ -6320,76 +6325,65 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item) -/////////////////////////////////////////////////////////////////////////// -// BustUpInlinesAtBRs: -// -nsresult -nsHTMLEditRules::BustUpInlinesAtBRs(nsIDOMNode *inNode, - nsCOMArray& outArrayOfNodes) +nsresult +nsHTMLEditRules::BustUpInlinesAtBRs(nsINode& aNode, + nsTArray>& aOutArrayOfNodes) { - nsCOMPtr node = do_QueryInterface(inNode); - NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); + NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); - // first step is to build up a list of all the break nodes inside - // the inline container. - nsCOMArray arrayOfBreaks; + // First build up a list of all the break nodes inside the inline container. + nsTArray> arrayOfBreaks; nsBRNodeFunctor functor; - nsDOMIterator iter(*inNode); + nsDOMIterator iter(*GetAsDOMNode(&aNode)); iter.AppendList(functor, arrayOfBreaks); - - // if there aren't any breaks, just put inNode itself in the array - int32_t listCount = arrayOfBreaks.Count(); - if (!listCount) - { - if (!outArrayOfNodes.AppendObject(inNode)) - return NS_ERROR_FAILURE; + + // If there aren't any breaks, just put inNode itself in the array + if (arrayOfBreaks.IsEmpty()) { + aOutArrayOfNodes.AppendElement(&aNode); + return NS_OK; } - else - { - // else we need to bust up inNode along all the breaks - nsCOMPtr breakNode; - nsCOMPtr inlineParentNode = node->GetParentNode(); - nsCOMPtr leftNode; - nsCOMPtr rightNode; - nsCOMPtr splitDeepNode = inNode; - nsCOMPtr splitParentNode; - int32_t splitOffset, resultOffset, i; - - for (i=0; i< listCount; i++) - { - breakNode = do_QueryInterface(arrayOfBreaks[i]); - NS_ENSURE_TRUE(breakNode, NS_ERROR_NULL_POINTER); - NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER); - splitParentNode = GetAsDOMNode(nsEditor::GetNodeLocation(breakNode, - &splitOffset)); - NS_ENSURE_STATE(mHTMLEditor); - nsresult res = mHTMLEditor->SplitNodeDeep(splitDeepNode, splitParentNode, splitOffset, - &resultOffset, false, address_of(leftNode), address_of(rightNode)); - NS_ENSURE_SUCCESS(res, res); - // put left node in node list - if (leftNode) - { - // might not be a left node. a break might have been at the very - // beginning of inline container, in which case splitnodedeep - // would not actually split anything - if (!outArrayOfNodes.AppendObject(leftNode)) - return NS_ERROR_FAILURE; - } - // move break outside of container and also put in node list - NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->MoveNode(breakNode, inlineParentNode, resultOffset); - NS_ENSURE_SUCCESS(res, res); - if (!outArrayOfNodes.AppendObject(GetAsDOMNode(breakNode))) - return NS_ERROR_FAILURE; - // now rightNode becomes the new node to split - splitDeepNode = rightNode; - } - // now tack on remaining rightNode, if any, to the list - if (rightNode) - { - if (!outArrayOfNodes.AppendObject(rightNode)) - return NS_ERROR_FAILURE; + + // Else we need to bust up inNode along all the breaks + nsCOMPtr inlineParentNode = aNode.GetParentNode(); + nsCOMPtr splitDeepNode = GetAsDOMNode(&aNode); + nsCOMPtr leftDOMNode, rightDOMNode; + + for (uint32_t i = 0; i < arrayOfBreaks.Length(); i++) { + nsCOMPtr breakNode = arrayOfBreaks[i]->AsElement(); + NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER); + nsCOMPtr splitParentNode = breakNode->GetParentNode(); + int32_t splitOffset = splitParentNode ? + splitParentNode->IndexOf(breakNode) : -1; + + int32_t resultOffset; + nsresult res = mHTMLEditor->SplitNodeDeep(splitDeepNode, + GetAsDOMNode(splitParentNode), splitOffset, &resultOffset, false, + address_of(leftDOMNode), address_of(rightDOMNode)); + NS_ENSURE_SUCCESS(res, res); + + // Put left node in node list + if (leftDOMNode) { + // Might not be a left node. A break might have been at the very + // beginning of inline container, in which case SplitNodeDeep would not + // actually split anything + nsCOMPtr leftNode = do_QueryInterface(leftDOMNode); + NS_ENSURE_STATE(leftNode); + aOutArrayOfNodes.AppendElement(leftNode); } + // Move break outside of container and also put in node list + res = mHTMLEditor->MoveNode(breakNode, inlineParentNode, resultOffset); + NS_ENSURE_SUCCESS(res, res); + aOutArrayOfNodes.AppendElement(breakNode); + + // Now rightNode becomes the new node to split + splitDeepNode = rightDOMNode; + } + // Now tack on remaining rightNode, if any, to the list + if (rightDOMNode) { + nsCOMPtr rightNode = do_QueryInterface(rightDOMNode); + NS_ENSURE_STATE(rightNode); + aOutArrayOfNodes.AppendElement(rightNode); } return NS_OK; } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 01eeffa5a25a..e4d030a64845 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -295,8 +295,8 @@ protected: nsresult GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, bool aDontTouchContent=false); nsresult LookInsideDivBQandList(nsCOMArray& aNodeArray); nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange); - nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode, - nsCOMArray& outArrayOfNodes); + nsresult BustUpInlinesAtBRs(nsINode& aNode, + nsTArray>& aOutArrayOfNodes); nsCOMPtr GetHighestInlineParent(nsIDOMNode* aNode); nsresult MakeTransitionList(nsCOMArray& inArrayOfNodes, nsTArray &inTransitionArray); From 179b7441b831639631463802ead514d364407d86 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 118/241] Bug 1149163 part 4 - Allow use of temporary nsBoolDomIterFunctor; r=froydnj --- editor/libeditor/nsEditorUtils.cpp | 4 ++-- editor/libeditor/nsEditorUtils.h | 11 ++++++----- editor/libeditor/nsHTMLEditRules.cpp | 12 +++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/editor/libeditor/nsEditorUtils.cpp b/editor/libeditor/nsEditorUtils.cpp index 3e7433dd2856..b0047a518e46 100644 --- a/editor/libeditor/nsEditorUtils.cpp +++ b/editor/libeditor/nsEditorUtils.cpp @@ -92,7 +92,7 @@ nsDOMIterator::~nsDOMIterator() } void -nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor, +nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, nsTArray>& arrayOfNodes) const { // Iterate through dom and build list @@ -106,7 +106,7 @@ nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor, } void -nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor, +nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, nsCOMArray& arrayOfNodes) const { // iterate through dom and build list diff --git a/editor/libeditor/nsEditorUtils.h b/editor/libeditor/nsEditorUtils.h index e76c3f064251..c35287c0a1df 100644 --- a/editor/libeditor/nsEditorUtils.h +++ b/editor/libeditor/nsEditorUtils.h @@ -167,8 +167,8 @@ class MOZ_STACK_CLASS nsAutoUpdateViewBatch class nsBoolDomIterFunctor { public: - virtual bool operator()(nsIDOMNode* aNode)=0; - bool operator()(nsINode* aNode) + virtual bool operator()(nsIDOMNode* aNode) const = 0; + bool operator()(nsINode* aNode) const { return operator()(GetAsDOMNode(aNode)); } @@ -181,9 +181,9 @@ class MOZ_STACK_CLASS nsDOMIterator explicit nsDOMIterator(nsIDOMNode& aNode); virtual ~nsDOMIterator(); - void AppendList(nsBoolDomIterFunctor& functor, + void AppendList(const nsBoolDomIterFunctor& functor, nsTArray>& arrayOfNodes) const; - void AppendList(nsBoolDomIterFunctor& functor, + void AppendList(const nsBoolDomIterFunctor& functor, nsCOMArray& arrayOfNodes) const; protected: nsCOMPtr mIter; @@ -202,7 +202,8 @@ class MOZ_STACK_CLASS nsDOMSubtreeIterator : public nsDOMIterator class nsTrivialFunctor : public nsBoolDomIterFunctor { public: - virtual bool operator()(nsIDOMNode* aNode) // used to build list of all nodes iterator covers + // Used to build list of all nodes iterator covers + virtual bool operator()(nsIDOMNode* aNode) const { return true; } diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 525167462b7b..9fd0e90743b3 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -107,7 +107,8 @@ IsStyleCachePreservingAction(EditAction action) class nsTableCellAndListItemFunctor : public nsBoolDomIterFunctor { public: - virtual bool operator()(nsIDOMNode* aNode) // used to build list of all li's, td's & th's iterator covers + // Used to build list of all li's, td's & th's iterator covers + virtual bool operator()(nsIDOMNode* aNode) const { if (nsHTMLEditUtils::IsTableCell(aNode)) return true; if (nsHTMLEditUtils::IsListItem(aNode)) return true; @@ -118,7 +119,7 @@ class nsTableCellAndListItemFunctor : public nsBoolDomIterFunctor class nsBRNodeFunctor : public nsBoolDomIterFunctor { public: - virtual bool operator()(nsIDOMNode* aNode) + virtual bool operator()(nsIDOMNode* aNode) const { if (nsTextEditUtils::IsBreak(aNode)) return true; return false; @@ -129,7 +130,7 @@ class nsEmptyEditableFunctor : public nsBoolDomIterFunctor { public: explicit nsEmptyEditableFunctor(nsHTMLEditor* editor) : mHTMLEditor(editor) {} - virtual bool operator()(nsIDOMNode* aNode) + virtual bool operator()(nsIDOMNode* aNode) const { if (mHTMLEditor->IsEditable(aNode) && (nsHTMLEditUtils::IsListItem(aNode) || @@ -151,7 +152,7 @@ class nsEditableTextFunctor : public nsBoolDomIterFunctor { public: explicit nsEditableTextFunctor(nsHTMLEditor* editor) : mHTMLEditor(editor) {} - virtual bool operator()(nsIDOMNode* aNode) + virtual bool operator()(nsIDOMNode* aNode) const { if (nsEditor::IsTextNode(aNode) && mHTMLEditor->IsEditable(aNode)) { @@ -5864,7 +5865,8 @@ public: explicit nsUniqueFunctor(nsCOMArray &aArray) : mArray(aArray) { } - virtual bool operator()(nsIDOMNode* aNode) // used to build list of all nodes iterator covers + // used to build list of all nodes iterator covers + virtual bool operator()(nsIDOMNode* aNode) const { return mArray.IndexOf(aNode) < 0; } From 12ccfaab765e41448659952c24be0f5106e31330 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 119/241] Bug 1149163 part 5 - Clean up nsHTMLEditRules::GetNodesForOperation; r=froydnj --- editor/libeditor/nsHTMLEditRules.cpp | 280 +++++++++++++-------------- editor/libeditor/nsHTMLEditRules.h | 9 +- 2 files changed, 139 insertions(+), 150 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 9fd0e90743b3..f05e522f5822 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -841,11 +841,11 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) NS_ENSURE_SUCCESS(res, res); // use these ranges to construct a list of nodes to act on. - nsCOMArray arrayOfNodes; + nsTArray> arrayOfNodes; res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, - EditAction::align, true); + EditAction::align, TouchContent::no); NS_ENSURE_SUCCESS(res, res); - nodeToExamine = arrayOfNodes.SafeObjectAt(0); + nodeToExamine = GetAsDOMNode(arrayOfNodes.SafeElementAt(0)); } NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER); @@ -3870,10 +3870,15 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, NS_ENSURE_SUCCESS(res, res); // use these ranges to contruct a list of nodes to act on. - nsCOMArray arrayOfNodes; - res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::indent); + nsTArray> array; + res = GetNodesForOperation(arrayOfRanges, array, EditAction::indent); NS_ENSURE_SUCCESS(res, res); + nsCOMArray arrayOfNodes; + for (auto& node : array) { + arrayOfNodes.AppendObject(GetAsDOMNode(node)); + } + // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { @@ -5859,184 +5864,153 @@ nsHTMLEditRules::PromoteRange(nsRange* inRange, EditAction inOperationType) return res; } +class NodeComparator +{ + public: + bool Equals(const nsINode* node, const nsIDOMNode* domNode) const + { + return domNode == GetAsDOMNode(const_cast(node)); + } +}; + class nsUniqueFunctor : public nsBoolDomIterFunctor { public: - explicit nsUniqueFunctor(nsCOMArray &aArray) : mArray(aArray) + explicit nsUniqueFunctor(nsTArray> &aArray) : mArray(aArray) { } // used to build list of all nodes iterator covers virtual bool operator()(nsIDOMNode* aNode) const { - return mArray.IndexOf(aNode) < 0; + return !mArray.Contains(aNode, NodeComparator()); } private: - nsCOMArray &mArray; + nsTArray>& mArray; }; -/////////////////////////////////////////////////////////////////////////// -// GetNodesForOperation: run through the ranges in the array and construct -// a new array of nodes to be acted on. -// -nsresult -nsHTMLEditRules::GetNodesForOperation(nsTArray>& inArrayOfRanges, - nsCOMArray& outArrayOfNodes, - EditAction inOperationType, - bool aDontTouchContent) +/////////////////////////////////////////////////////////////////////////////// +// GetNodesForOperation: Run through the ranges in the array and construct a +// new array of nodes to be acted on. +// +nsresult +nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRanges, + nsTArray>& aOutArrayOfNodes, + EditAction aOperationType, + TouchContent aTouchContent) { - int32_t rangeCount = inArrayOfRanges.Length(); - - int32_t i; - nsRefPtr opRange; + NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); - nsresult res = NS_OK; - - // bust up any inlines that cross our range endpoints, - // but only if we are allowed to touch content. - - if (!aDontTouchContent) - { + int32_t rangeCount = aArrayOfRanges.Length(); + nsresult res; + + // Bust up any inlines that cross our range endpoints, but only if we are + // allowed to touch content. + + if (aTouchContent == TouchContent::yes) { nsTArray> rangeItemArray; rangeItemArray.AppendElements(rangeCount); - NS_ASSERTION(static_cast(rangeCount) == rangeItemArray.Length(), - "How did that happen?"); - - // first register ranges for special editor gravity - for (i = 0; i < rangeCount; i++) - { - opRange = inArrayOfRanges[0]; + // First register ranges for special editor gravity + for (int32_t i = 0; i < rangeCount; i++) { rangeItemArray[i] = new nsRangeStore(); - rangeItemArray[i]->StoreRange(opRange); - NS_ENSURE_STATE(mHTMLEditor); + rangeItemArray[i]->StoreRange(aArrayOfRanges[0]); mHTMLEditor->mRangeUpdater.RegisterRangeItem(rangeItemArray[i]); - inArrayOfRanges.RemoveElementAt(0); - } - // now bust up inlines. Safe to start at rangeCount-1, since we - // asserted we have enough items above. - for (i = rangeCount-1; i >= 0 && NS_SUCCEEDED(res); i--) - { - res = BustUpInlinesAtRangeEndpoints(*rangeItemArray[i]); - } - // then unregister the ranges - for (i = 0; i < rangeCount; i++) - { - nsRangeStore* item = rangeItemArray[i]; - NS_ENSURE_STATE(mHTMLEditor); + aArrayOfRanges.RemoveElementAt(0); + } + // Now bust up inlines. + for (auto& item : Reversed(rangeItemArray)) { + res = BustUpInlinesAtRangeEndpoints(*item); + if (NS_FAILED(res)) { + break; + } + } + // Then unregister the ranges + for (auto& item : rangeItemArray) { mHTMLEditor->mRangeUpdater.DropRangeItem(item); - opRange = item->GetRange(); - inArrayOfRanges.AppendElement(opRange); + aArrayOfRanges.AppendElement(item->GetRange()); } NS_ENSURE_SUCCESS(res, res); } - // gather up a list of all the nodes - for (i = 0; i < rangeCount; i++) - { - opRange = inArrayOfRanges[i]; - - nsDOMSubtreeIterator iter(*opRange); - if (outArrayOfNodes.Count() == 0) { - nsTrivialFunctor functor; - iter.AppendList(functor, outArrayOfNodes); - } - else { - // We don't want duplicates in outArrayOfNodes, so we use an + // Gather up a list of all the nodes + for (auto& range : aArrayOfRanges) { + nsDOMSubtreeIterator iter(*range); + if (aOutArrayOfNodes.Length() == 0) { + iter.AppendList(nsTrivialFunctor(), aOutArrayOfNodes); + } else { + // We don't want duplicates in aOutArrayOfNodes, so we use an // iterator/functor that only return nodes that are not already in - // outArrayOfNodes. - nsCOMArray nodes; - nsUniqueFunctor functor(outArrayOfNodes); - iter.AppendList(functor, nodes); - if (!outArrayOfNodes.AppendObjects(nodes)) - return NS_ERROR_OUT_OF_MEMORY; + // aOutArrayOfNodes. + nsTArray> nodes; + iter.AppendList(nsUniqueFunctor(aOutArrayOfNodes), nodes); + aOutArrayOfNodes.AppendElements(nodes); } - } + } - // certain operations should not act on li's and td's, but rather inside - // them. alter the list as needed - if (inOperationType == EditAction::makeBasicBlock) { - int32_t listCount = outArrayOfNodes.Count(); - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr node = outArrayOfNodes[i]; - if (nsHTMLEditUtils::IsListItem(node)) - { - int32_t j=i; - outArrayOfNodes.RemoveObjectAt(i); - res = GetInnerContent(node, outArrayOfNodes, &j); - NS_ENSURE_SUCCESS(res, res); + // Certain operations should not act on li's and td's, but rather inside + // them. Alter the list as needed. + if (aOperationType == EditAction::makeBasicBlock) { + for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { + nsCOMPtr node = aOutArrayOfNodes[i]; + if (nsHTMLEditUtils::IsListItem(node)) { + int32_t j = i; + aOutArrayOfNodes.RemoveElementAt(i); + GetInnerContent(*node, aOutArrayOfNodes, &j); + } + } + // Indent/outdent already do something special for list items, but we still + // need to make sure we don't act on table elements + } else if (aOperationType == EditAction::outdent || + aOperationType == EditAction::indent || + aOperationType == EditAction::setAbsolutePosition) { + for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { + nsCOMPtr node = aOutArrayOfNodes[i]; + if (nsHTMLEditUtils::IsTableElementButNotTable(node)) { + int32_t j = i; + aOutArrayOfNodes.RemoveElementAt(i); + GetInnerContent(*node, aOutArrayOfNodes, &j); } } } - // indent/outdent already do something special for list items, but - // we still need to make sure we don't act on table elements - else if (inOperationType == EditAction::outdent || - inOperationType == EditAction::indent || - inOperationType == EditAction::setAbsolutePosition) { - int32_t listCount = outArrayOfNodes.Count(); - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr node = outArrayOfNodes[i]; - if (nsHTMLEditUtils::IsTableElementButNotTable(node)) - { - int32_t j=i; - outArrayOfNodes.RemoveObjectAt(i); - res = GetInnerContent(node, outArrayOfNodes, &j); - NS_ENSURE_SUCCESS(res, res); - } - } - } - // outdent should look inside of divs. - if (inOperationType == EditAction::outdent && - (!mHTMLEditor || !mHTMLEditor->IsCSSEnabled())) { - NS_ENSURE_STATE(mHTMLEditor); - int32_t listCount = outArrayOfNodes.Count(); - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr node = outArrayOfNodes[i]; - if (nsHTMLEditUtils::IsDiv(node)) - { - int32_t j=i; - outArrayOfNodes.RemoveObjectAt(i); - res = GetInnerContent(node, outArrayOfNodes, &j, false, false); - NS_ENSURE_SUCCESS(res, res); + // Outdent should look inside of divs. + if (aOperationType == EditAction::outdent && + !mHTMLEditor->IsCSSEnabled()) { + for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { + nsCOMPtr node = aOutArrayOfNodes[i]; + if (node->IsHTMLElement(nsGkAtoms::div)) { + int32_t j = i; + aOutArrayOfNodes.RemoveElementAt(i); + GetInnerContent(*node, aOutArrayOfNodes, &j, Lists::no, Tables::no); } } } - // post process the list to break up inline containers that contain br's. - // but only for operations that might care, like making lists or para's... - if (inOperationType == EditAction::makeBasicBlock || - inOperationType == EditAction::makeList || - inOperationType == EditAction::align || - inOperationType == EditAction::setAbsolutePosition || - inOperationType == EditAction::indent || - inOperationType == EditAction::outdent) { - int32_t listCount = outArrayOfNodes.Count(); - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr node = do_QueryInterface(outArrayOfNodes[i]); - NS_ENSURE_STATE(node); - if (!aDontTouchContent && IsInlineNode(GetAsDOMNode(node)) && - (!mHTMLEditor || mHTMLEditor->IsContainer(node)) && - (!mHTMLEditor || !mHTMLEditor->IsTextNode(node))) - { - NS_ENSURE_STATE(mHTMLEditor); + // Post-process the list to break up inline containers that contain br's, but + // only for operations that might care, like making lists or paragraphs + if (aOperationType == EditAction::makeBasicBlock || + aOperationType == EditAction::makeList || + aOperationType == EditAction::align || + aOperationType == EditAction::setAbsolutePosition || + aOperationType == EditAction::indent || + aOperationType == EditAction::outdent) { + for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { + nsCOMPtr node = aOutArrayOfNodes[i]; + if (aTouchContent == TouchContent::yes && + IsInlineNode(GetAsDOMNode(node)) && mHTMLEditor->IsContainer(node) && + !mHTMLEditor->IsTextNode(node)) { nsTArray> arrayOfInlines; res = BustUpInlinesAtBRs(*node, arrayOfInlines); NS_ENSURE_SUCCESS(res, res); - nsCOMArray arrayOfInlinesDOM; - for (auto& inlineNode : arrayOfInlines) { - arrayOfInlinesDOM.AppendObject(GetAsDOMNode(inlineNode)); - } - // put these nodes in outArrayOfNodes, replacing the current node - outArrayOfNodes.RemoveObjectAt(i); - outArrayOfNodes.InsertObjectsAt(arrayOfInlinesDOM, i); + + // Put these nodes in aOutArrayOfNodes, replacing the current node + aOutArrayOfNodes.RemoveElementAt(i); + aOutArrayOfNodes.InsertElementsAt(i, arrayOfInlines); } } } - return res; + return NS_OK; } @@ -6433,7 +6407,12 @@ nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point, arrayOfRanges.AppendElement(range); // use these ranges to contruct a list of nodes to act on. - res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, operation, dontTouchContent); + nsTArray> array; + res = GetNodesForOperation(arrayOfRanges, array, operation, dontTouchContent + ? TouchContent::no : TouchContent::yes); + for (auto& node : array) { + arrayOfNodes.AppendObject(GetAsDOMNode(node)); + } return res; } @@ -6457,7 +6436,12 @@ nsHTMLEditRules::GetNodesFromSelection(Selection* selection, NS_ENSURE_SUCCESS(res, res); // use these ranges to contruct a list of nodes to act on. - res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, operation, dontTouchContent); + nsTArray> array; + res = GetNodesForOperation(arrayOfRanges, array, operation, dontTouchContent + ? TouchContent::no : TouchContent::yes); + for (auto& node : array) { + arrayOfNodes.AppendObject(GetAsDOMNode(node)); + } return res; } @@ -9079,11 +9063,15 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection, NS_ENSURE_SUCCESS(res, res); // use these ranges to contruct a list of nodes to act on. - nsCOMArray arrayOfNodes; - res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, + nsTArray> array; + res = GetNodesForOperation(arrayOfRanges, array, EditAction::setAbsolutePosition); NS_ENSURE_SUCCESS(res, res); + nsCOMArray arrayOfNodes; + for (auto& node : array) { + arrayOfNodes.AppendObject(GetAsDOMNode(node)); + } // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index e4d030a64845..b589c3d28d7d 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -276,10 +276,11 @@ protected: nsTArray>& outArrayOfRanges, EditAction inOperationType); nsresult PromoteRange(nsRange* inRange, EditAction inOperationType); - nsresult GetNodesForOperation(nsTArray>& inArrayOfRanges, - nsCOMArray& outArrayOfNodes, - EditAction inOperationType, - bool aDontTouchContent=false); + enum class TouchContent { no, yes }; + nsresult GetNodesForOperation(nsTArray>& aArrayOfRanges, + nsTArray>& aOutArrayOfNodes, + EditAction aOperationType, + TouchContent aTouchContent = TouchContent::yes); nsresult GetChildNodesForOperation(nsIDOMNode *inNode, nsCOMArray& outArrayOfNodes); nsresult GetNodesFromPoint(::DOMPoint point, From cde03c2171c03fdb3dc014ea7a504c97072c90b9 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 120/241] Bug 1149163 part 6 - Clean up nsHTMLEditRules::LookInsideDivBQandList; r=froydnj --- editor/libeditor/nsHTMLEditRules.cpp | 107 ++++++++++++++------------- editor/libeditor/nsHTMLEditRules.h | 2 +- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index f05e522f5822..5fa1ce17bd5f 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -3093,16 +3093,16 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); - nsCOMArray arrayOfNodes; - res = GetListActionNodes(arrayOfNodes, aEntireList); + nsCOMArray arrayOfDOMNodes; + res = GetListActionNodes(arrayOfDOMNodes, aEntireList); NS_ENSURE_SUCCESS(res, res); - int32_t listCount = arrayOfNodes.Count(); + int32_t listCount = arrayOfDOMNodes.Count(); // check if all our nodes are
s, or empty inlines bool bOnlyBreaks = true; for (int32_t j = 0; j < listCount; j++) { - nsIDOMNode* curNode = arrayOfNodes[j]; + nsIDOMNode* curNode = arrayOfDOMNodes[j]; // if curNode is not a Break or empty inline, we're done if (!nsTextEditUtils::IsBreak(curNode) && !IsEmptyInline(curNode)) { bOnlyBreaks = false; @@ -3117,7 +3117,7 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, if (bOnlyBreaks) { for (int32_t j = 0; j < (int32_t)listCount; j++) { NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->DeleteNode(arrayOfNodes[j]); + res = mHTMLEditor->DeleteNode(arrayOfDOMNodes[j]); NS_ENSURE_SUCCESS(res, res); } } @@ -3159,21 +3159,26 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, // if there is only one node in the array, and it is a list, div, or // blockquote, then look inside of it until we find inner list or content. - res = LookInsideDivBQandList(arrayOfNodes); - NS_ENSURE_SUCCESS(res, res); + nsTArray> arrayOfNodes; + for (int32_t i = 0; i < arrayOfDOMNodes.Count(); i++) { + nsCOMPtr node = do_QueryInterface(arrayOfDOMNodes[i]); + NS_ENSURE_STATE(node); + arrayOfNodes.AppendElement(node); + } + LookInsideDivBQandList(arrayOfNodes); // Ok, now go through all the nodes and put then in the list, // or whatever is approriate. Wohoo! - listCount = arrayOfNodes.Count(); + listCount = arrayOfNodes.Length(); nsCOMPtr curParent; nsCOMPtr curList, prevListItem; for (int32_t i = 0; i < listCount; i++) { // here's where we actually figure out what to do nsCOMPtr newBlock; - nsCOMPtr curNode = do_QueryInterface(arrayOfNodes[i]); - NS_ENSURE_STATE(curNode); + NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); + nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); int32_t offset; curParent = nsEditor::GetNodeLocation(curNode, &offset); @@ -3293,12 +3298,11 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, if (curNode->IsHTMLElement(nsGkAtoms::div)) { prevListItem = nullptr; int32_t j = i + 1; - res = GetInnerContent(curNode->AsDOMNode(), arrayOfNodes, &j); - NS_ENSURE_SUCCESS(res, res); + GetInnerContent(*curNode, arrayOfNodes, &j); NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->RemoveContainer(curNode); NS_ENSURE_SUCCESS(res, res); - listCount = arrayOfNodes.Count(); + listCount = arrayOfNodes.Length(); continue; } @@ -6118,67 +6122,68 @@ nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, // if there is only one node in the array, and it is a list, div, or blockquote, // then look inside of it until we find inner list or content. - res = LookInsideDivBQandList(outArrayOfNodes); - return res; + nsTArray> arrayOfNodes; + for (int32_t i = 0; i < outArrayOfNodes.Count(); i++) { + nsCOMPtr node = do_QueryInterface(outArrayOfNodes[i]); + NS_ENSURE_STATE(node); + arrayOfNodes.AppendElement(node); + } + LookInsideDivBQandList(arrayOfNodes); + outArrayOfNodes.Clear(); + for (auto& node : arrayOfNodes) { + outArrayOfNodes.AppendObject(GetAsDOMNode(node)); + } + return NS_OK; } -/////////////////////////////////////////////////////////////////////////// -// LookInsideDivBQandList: -// -nsresult -nsHTMLEditRules::LookInsideDivBQandList(nsCOMArray& aNodeArray) +void +nsHTMLEditRules::LookInsideDivBQandList(nsTArray>& aNodeArray) { - // if there is only one node in the array, and it is a list, div, or blockquote, - // then look inside of it until we find inner list or content. - int32_t listCount = aNodeArray.Count(); + NS_ENSURE_TRUE(mHTMLEditor, ); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); + + // If there is only one node in the array, and it is a list, div, or + // blockquote, then look inside of it until we find inner list or content. + int32_t listCount = aNodeArray.Length(); if (listCount != 1) { - return NS_OK; + return; } - nsCOMPtr curNode = do_QueryInterface(aNodeArray[0]); - NS_ENSURE_STATE(curNode); + nsCOMPtr curNode = aNodeArray[0]; - while (curNode->IsElement() && - (curNode->IsHTMLElement(nsGkAtoms::div) || - nsHTMLEditUtils::IsList(curNode) || - curNode->IsHTMLElement(nsGkAtoms::blockquote))) { - // dive as long as there is only one child, and it is a list, div, blockquote - NS_ENSURE_STATE(mHTMLEditor); + while (curNode->IsHTMLElement(nsGkAtoms::div) || + nsHTMLEditUtils::IsList(curNode) || + curNode->IsHTMLElement(nsGkAtoms::blockquote)) { + // Dive as long as there's only one child, and it's a list, div, blockquote uint32_t numChildren = mHTMLEditor->CountEditableChildren(curNode); if (numChildren != 1) { break; } - // keep diving - // XXX One would expect to dive into the one editable node. - nsIContent* tmp = curNode->GetFirstChild(); - if (!tmp->IsElement()) { + // Keep diving! XXX One would expect to dive into the one editable node. + nsCOMPtr child = curNode->GetFirstChild(); + if (!child->IsHTMLElement(nsGkAtoms::div) && + !nsHTMLEditUtils::IsList(child) && + !child->IsHTMLElement(nsGkAtoms::blockquote)) { break; } - dom::Element* element = tmp->AsElement(); - if (!element->IsHTMLElement(nsGkAtoms::div) && - !nsHTMLEditUtils::IsList(element) && - !element->IsHTMLElement(nsGkAtoms::blockquote)) { - break; - } - - // check editablility XXX floppy moose - curNode = tmp; + // check editability XXX floppy moose + curNode = child; } - // we've found innermost list/blockquote/div: - // replace the one node in the array with these nodes - aNodeArray.RemoveObjectAt(0); + // We've found innermost list/blockquote/div: replace the one node in the + // array with these nodes + aNodeArray.RemoveElementAt(0); if (curNode->IsAnyOfHTMLElements(nsGkAtoms::div, nsGkAtoms::blockquote)) { int32_t j = 0; - return GetInnerContent(curNode->AsDOMNode(), aNodeArray, &j, false, false); + GetInnerContent(*curNode, aNodeArray, &j, Lists::no, Tables::no); + return; } - aNodeArray.AppendObject(curNode->AsDOMNode()); - return NS_OK; + aNodeArray.AppendElement(curNode); } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index b589c3d28d7d..7e7f52a8ff50 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -294,7 +294,7 @@ protected: nsresult GetListActionNodes(nsCOMArray &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false); void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD); nsresult GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, bool aDontTouchContent=false); - nsresult LookInsideDivBQandList(nsCOMArray& aNodeArray); + void LookInsideDivBQandList(nsTArray>& aNodeArray); nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange); nsresult BustUpInlinesAtBRs(nsINode& aNode, nsTArray>& aOutArrayOfNodes); From 86f93aa7f3e695ca5e31f4cb38497e860949e416 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 121/241] Bug 1149163 part 7 - Clean up nsHTMLEditRules::PromoteRange; r=froydnj --- editor/libeditor/nsHTMLEditRules.cpp | 131 +++++++++++---------------- editor/libeditor/nsHTMLEditRules.h | 2 +- 2 files changed, 54 insertions(+), 79 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 5fa1ce17bd5f..8158bc57ffb3 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -447,8 +447,7 @@ nsHTMLEditRules::AfterEditInner(EditAction action, nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor); // expand the "changed doc range" as needed - res = PromoteRange(mDocChangeRange, action); - NS_ENSURE_SUCCESS(res, res); + PromoteRange(*mDocChangeRange, action); // if we did a ranged deletion or handling backspace key, make sure we have // a place to put caret. @@ -5768,8 +5767,7 @@ nsHTMLEditRules::GetPromotedRanges(Selection* inSelection, // The basic idea is to push out the range endpoints // to truly enclose the blocks that we will affect. // This call alters opRange. - res = PromoteRange(opRange, inOperationType); - NS_ENSURE_SUCCESS(res, res); + PromoteRange(*opRange, inOperationType); // stuff new opRange into array outArrayOfRanges.AppendElement(opRange); @@ -5778,95 +5776,76 @@ nsHTMLEditRules::GetPromotedRanges(Selection* inSelection, } -/////////////////////////////////////////////////////////////////////////// -// PromoteRange: expand a range to include any parents for which all -// editable children are already in range. -// -nsresult -nsHTMLEditRules::PromoteRange(nsRange* inRange, EditAction inOperationType) +/////////////////////////////////////////////////////////////////////////////// +// PromoteRange: Expand a range to include any parents for which all editable +// children are already in range. +// +void +nsHTMLEditRules::PromoteRange(nsRange& aRange, EditAction aOperationType) { - NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER); - nsresult res; - nsCOMPtr startNode, endNode; - int32_t startOffset, endOffset; - - res = inRange->GetStartContainer(getter_AddRefs(startNode)); - NS_ENSURE_SUCCESS(res, res); - res = inRange->GetStartOffset(&startOffset); - NS_ENSURE_SUCCESS(res, res); - res = inRange->GetEndContainer(getter_AddRefs(endNode)); - NS_ENSURE_SUCCESS(res, res); - res = inRange->GetEndOffset(&endOffset); - NS_ENSURE_SUCCESS(res, res); - + NS_ENSURE_TRUE(mHTMLEditor, ); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); + + nsCOMPtr startNode = aRange.GetStartParent(); + nsCOMPtr endNode = aRange.GetEndParent(); + int32_t startOffset = aRange.StartOffset(); + int32_t endOffset = aRange.EndOffset(); + // MOOSE major hack: // GetPromotedPoint doesn't really do the right thing for collapsed ranges // inside block elements that contain nothing but a solo
. It's easier // to put a workaround here than to revamp GetPromotedPoint. :-( - if ( (startNode == endNode) && (startOffset == endOffset)) - { - nsCOMPtr block; - if (IsBlockNode(startNode)) { - block = startNode; + if (startNode == endNode && startOffset == endOffset) { + nsCOMPtr block; + if (IsBlockNode(GetAsDOMNode(startNode))) { + block = startNode->AsElement(); } else { - NS_ENSURE_STATE(mHTMLEditor); block = mHTMLEditor->GetBlockNodeParent(startNode); } - if (block) - { + if (block) { bool bIsEmptyNode = false; - // check for the editing host - NS_ENSURE_STATE(mHTMLEditor); - nsIContent *rootContent = mHTMLEditor->GetActiveEditingHost(); - nsCOMPtr rootNode = do_QueryInterface(rootContent); - nsCOMPtr blockNode = do_QueryInterface(block); - NS_ENSURE_TRUE(rootNode && blockNode, NS_ERROR_UNEXPECTED); + nsCOMPtr root = mHTMLEditor->GetActiveEditingHost(); // Make sure we don't go higher than our root element in the content tree - if (!nsContentUtils::ContentIsDescendantOf(rootNode, blockNode)) - { - NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, true, false); + NS_ENSURE_TRUE(root, ); + if (!nsContentUtils::ContentIsDescendantOf(root, block)) { + mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, true, false); } - if (bIsEmptyNode) - { - uint32_t numChildren; - nsEditor::GetLengthOfDOMNode(block, numChildren); + if (bIsEmptyNode) { startNode = block; endNode = block; startOffset = 0; - endOffset = numChildren; + endOffset = block->Length(); } } } - // make a new adjusted range to represent the appropriate block content. - // this is tricky. the basic idea is to push out the range endpoints - // to truly enclose the blocks that we will affect - + // Make a new adjusted range to represent the appropriate block content. + // This is tricky. The basic idea is to push out the range endpoints to + // truly enclose the blocks that we will affect. + nsCOMPtr opStartNode; nsCOMPtr opEndNode; int32_t opStartOffset, opEndOffset; nsRefPtr opRange; - - GetPromotedPoint(kStart, startNode, startOffset, inOperationType, - address_of(opStartNode), &opStartOffset); - GetPromotedPoint(kEnd, endNode, endOffset, inOperationType, + + GetPromotedPoint(kStart, GetAsDOMNode(startNode), startOffset, + aOperationType, address_of(opStartNode), &opStartOffset); + GetPromotedPoint(kEnd, GetAsDOMNode(endNode), endOffset, aOperationType, address_of(opEndNode), &opEndOffset); // Make sure that the new range ends up to be in the editable section. - NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsDescendantOfEditorRoot(nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) || - !mHTMLEditor || // Check again, since it may have gone away - !mHTMLEditor->IsDescendantOfEditorRoot(nsEditor::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) { - NS_ENSURE_STATE(mHTMLEditor); - return NS_OK; + if (!mHTMLEditor->IsDescendantOfEditorRoot( + nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) || + !mHTMLEditor->IsDescendantOfEditorRoot( + nsEditor::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) { + return; } - res = inRange->SetStart(opStartNode, opStartOffset); - NS_ENSURE_SUCCESS(res, res); - res = inRange->SetEnd(opEndNode, opEndOffset); - return res; -} + DebugOnly res = aRange.SetStart(opStartNode, opStartOffset); + MOZ_ASSERT(NS_SUCCEEDED(res)); + res = aRange.SetEnd(opEndNode, opEndOffset); + MOZ_ASSERT(NS_SUCCEEDED(res)); +} class NodeComparator { @@ -6042,23 +6021,20 @@ nsHTMLEditRules::GetChildNodesForOperation(nsIDOMNode *inNode, -/////////////////////////////////////////////////////////////////////////// -// GetListActionNodes: -// -nsresult -nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, +nsresult +nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, bool aEntireList, bool aDontTouchContent) { nsresult res = NS_OK; - + NS_ENSURE_STATE(mHTMLEditor); nsRefPtr selection = mHTMLEditor->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE); // added this in so that ui code can ask to change an entire list, even if selection // is only in part of it. used by list item dialog. if (aEntireList) - { + { uint32_t rangeCount = selection->RangeCount(); for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) { nsRefPtr range = selection->GetRangeAt(rangeIdx); @@ -6094,8 +6070,8 @@ nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, outArrayOfNodes, aDontTouchContent); NS_ENSURE_SUCCESS(res, res); } - - // pre process our list of nodes... + + // pre process our list of nodes... int32_t listCount = outArrayOfNodes.Count(); int32_t i; for (i=listCount-1; i>=0; i--) @@ -6108,7 +6084,7 @@ nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, { outArrayOfNodes.RemoveObjectAt(i); } - + // scan for table elements and divs. If we find table elements other than table, // replace it with a list of any editable non-table content. if (nsHTMLEditUtils::IsTableElementButNotTable(testNode)) @@ -6402,8 +6378,7 @@ nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point, NS_ENSURE_SUCCESS(res, res); // expand the range to include adjacent inlines - res = PromoteRange(range, operation); - NS_ENSURE_SUCCESS(res, res); + PromoteRange(*range, operation); // make array of ranges nsTArray> arrayOfRanges; diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 7e7f52a8ff50..64ee1a9fa98e 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -275,7 +275,7 @@ protected: nsresult GetPromotedRanges(mozilla::dom::Selection* aSelection, nsTArray>& outArrayOfRanges, EditAction inOperationType); - nsresult PromoteRange(nsRange* inRange, EditAction inOperationType); + void PromoteRange(nsRange& aRange, EditAction inOperationType); enum class TouchContent { no, yes }; nsresult GetNodesForOperation(nsTArray>& aArrayOfRanges, nsTArray>& aOutArrayOfNodes, From a589a12b04739d155d696b73aef4b8db8c70087d Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 122/241] Bug 1149163 part 8 - Clean up nsHTMLEditRules::GetPromotedRanges; r=froydnj --- editor/libeditor/nsHTMLEditRules.cpp | 62 +++++++++++----------------- editor/libeditor/nsHTMLEditRules.h | 6 +-- 2 files changed, 26 insertions(+), 42 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 8158bc57ffb3..d96d5e87a175 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -836,8 +836,7 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) else { nsTArray> arrayOfRanges; - res = GetPromotedRanges(selection, arrayOfRanges, EditAction::align); - NS_ENSURE_SUCCESS(res, res); + GetPromotedRanges(*selection, arrayOfRanges, EditAction::align); // use these ranges to construct a list of nodes to act on. nsTArray> arrayOfNodes; @@ -3379,8 +3378,7 @@ nsHTMLEditRules::WillRemoveList(Selection* aSelection, nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); nsTArray> arrayOfRanges; - res = GetPromotedRanges(aSelection, arrayOfRanges, EditAction::makeList); - NS_ENSURE_SUCCESS(res, res); + GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::makeList); // use these ranges to contruct a list of nodes to act on. nsCOMArray arrayOfNodes; @@ -3869,8 +3867,7 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, // whose children are all in the range nsTArray> arrayOfRanges; - res = GetPromotedRanges(aSelection, arrayOfRanges, EditAction::indent); - NS_ENSURE_SUCCESS(res, res); + GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::indent); // use these ranges to contruct a list of nodes to act on. nsTArray> array; @@ -5736,43 +5733,32 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode, } -/////////////////////////////////////////////////////////////////////////// -// GetPromotedRanges: run all the selection range endpoint through +/////////////////////////////////////////////////////////////////////////////// +// GetPromotedRanges: Run all the selection range endpoint through // GetPromotedPoint() -// -nsresult -nsHTMLEditRules::GetPromotedRanges(Selection* inSelection, - nsTArray>& outArrayOfRanges, +// +void +nsHTMLEditRules::GetPromotedRanges(Selection& aSelection, + nsTArray>& outArrayOfRanges, EditAction inOperationType) { - NS_ENSURE_TRUE(inSelection, NS_ERROR_NULL_POINTER); + uint32_t rangeCount = aSelection.RangeCount(); - int32_t rangeCount; - nsresult res = inSelection->GetRangeCount(&rangeCount); - NS_ENSURE_SUCCESS(res, res); - - int32_t i; - nsRefPtr selectionRange; - nsRefPtr opRange; + for (uint32_t i = 0; i < rangeCount; i++) { + nsRefPtr selectionRange = aSelection.GetRangeAt(i); + MOZ_ASSERT(selectionRange); - for (i = 0; i < rangeCount; i++) - { - selectionRange = inSelection->GetRangeAt(i); - NS_ENSURE_STATE(selectionRange); + // Clone range so we don't muck with actual selection ranges + nsRefPtr opRange = selectionRange->CloneRange(); - // clone range so we don't muck with actual selection ranges - opRange = selectionRange->CloneRange(); - - // make a new adjusted range to represent the appropriate block content. - // The basic idea is to push out the range endpoints - // to truly enclose the blocks that we will affect. - // This call alters opRange. + // Make a new adjusted range to represent the appropriate block content. + // The basic idea is to push out the range endpoints to truly enclose the + // blocks that we will affect. This call alters opRange. PromoteRange(*opRange, inOperationType); - - // stuff new opRange into array + + // Stuff new opRange into array outArrayOfRanges.AppendElement(opRange); } - return res; } @@ -6412,8 +6398,7 @@ nsHTMLEditRules::GetNodesFromSelection(Selection* selection, // promote selection ranges nsTArray> arrayOfRanges; - res = GetPromotedRanges(selection, arrayOfRanges, operation); - NS_ENSURE_SUCCESS(res, res); + GetPromotedRanges(*selection, arrayOfRanges, operation); // use these ranges to contruct a list of nodes to act on. nsTArray> array; @@ -9038,9 +9023,8 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection, // whose children are all in the range nsTArray> arrayOfRanges; - res = GetPromotedRanges(aSelection, arrayOfRanges, - EditAction::setAbsolutePosition); - NS_ENSURE_SUCCESS(res, res); + GetPromotedRanges(*aSelection, arrayOfRanges, + EditAction::setAbsolutePosition); // use these ranges to contruct a list of nodes to act on. nsTArray> array; diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 64ee1a9fa98e..547944e2c221 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -272,9 +272,9 @@ protected: void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode, int32_t aOffset, EditAction actionID, nsCOMPtr* outNode, int32_t* outOffset); - nsresult GetPromotedRanges(mozilla::dom::Selection* aSelection, - nsTArray>& outArrayOfRanges, - EditAction inOperationType); + void GetPromotedRanges(mozilla::dom::Selection& aSelection, + nsTArray>& outArrayOfRanges, + EditAction inOperationType); void PromoteRange(nsRange& aRange, EditAction inOperationType); enum class TouchContent { no, yes }; nsresult GetNodesForOperation(nsTArray>& aArrayOfRanges, From 0482d1aa1bf4a79d2ea69c3f5f7c83ccf10b991e Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 123/241] Bug 1149163 part 9 - Clean up nsHTMLEditRules::GetNodesFromSelection; r=froydnj --- editor/libeditor/nsHTMLEditRules.cpp | 267 ++++++++++++--------------- editor/libeditor/nsHTMLEditRules.h | 12 +- 2 files changed, 125 insertions(+), 154 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index d96d5e87a175..fd0b3a882d9b 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -965,23 +965,17 @@ nsHTMLEditRules::GetIndentState(bool *aCanIndent, bool *aCanOutdent) OwningNonNull selection = *mHTMLEditor->GetSelection(); // contruct a list of nodes to act on. - nsCOMArray arrayOfNodes; - nsresult res = GetNodesFromSelection(selection, EditAction::indent, - arrayOfNodes, true); + nsTArray> arrayOfNodes; + nsresult res = GetNodesFromSelection(*selection, EditAction::indent, + arrayOfNodes, TouchContent::no); NS_ENSURE_SUCCESS(res, res); // examine nodes in selection for blockquotes or list elements; // these we can outdent. Note that we return true for canOutdent // if *any* of the selection is outdentable, rather than all of it. - int32_t listCount = arrayOfNodes.Count(); - int32_t i; NS_ENSURE_STATE(mHTMLEditor); bool useCSS = mHTMLEditor->IsCSSEnabled(); - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr curNode = do_QueryInterface(arrayOfNodes[i]); - NS_ENSURE_STATE(curNode || !arrayOfNodes[i]); - + for (auto& curNode : Reversed(arrayOfNodes)) { if (nsHTMLEditUtils::IsNodeThatCanOutdent(GetAsDOMNode(curNode))) { *aCanOutdent = true; break; @@ -3468,22 +3462,26 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, nsString tString(*aBlockType); // contruct a list of nodes to act on. - nsCOMArray arrayOfNodes; - res = GetNodesFromSelection(aSelection, EditAction::makeBasicBlock, - arrayOfNodes); + nsTArray> array; + res = GetNodesFromSelection(*aSelection, EditAction::makeBasicBlock, + array); NS_ENSURE_SUCCESS(res, res); // Remove all non-editable nodes. Leave them be. - int32_t listCount = arrayOfNodes.Count(); + int32_t listCount = array.Length(); int32_t i; for (i=listCount-1; i>=0; i--) { NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsEditable(arrayOfNodes[i])) - { - arrayOfNodes.RemoveObjectAt(i); + if (!mHTMLEditor->IsEditable(array[i])) { + array.RemoveElementAt(i); } } + + nsCOMArray arrayOfNodes; + for (auto& node : array) { + arrayOfNodes.AppendObject(GetAsDOMNode(node)); + } // reset list count listCount = arrayOfNodes.Count(); @@ -3651,20 +3649,21 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); nsTArray> arrayOfRanges; - nsCOMArray arrayOfNodes; + nsTArray> array; // short circuit: detect case of collapsed selection inside an
  • . // just sublist that
  • . This prevents bug 97797. - nsCOMPtr liNode; + nsCOMPtr liNode; if (aSelection->Collapsed()) { - nsCOMPtr node, block; + nsCOMPtr node; + nsCOMPtr block; int32_t offset; NS_ENSURE_STATE(mHTMLEditor); nsresult res = mHTMLEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(node), &offset); NS_ENSURE_SUCCESS(res, res); - if (IsBlockNode(node)) { - block = node; + if (IsBlockNode(GetAsDOMNode(node))) { + block = node->AsElement(); } else { NS_ENSURE_STATE(mHTMLEditor); block = mHTMLEditor->GetBlockNodeParent(node); @@ -3675,7 +3674,7 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, if (liNode) { - arrayOfNodes.AppendObject(liNode); + array.AppendElement(liNode); } else { @@ -3683,9 +3682,14 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, // this basically just expands the range to include the immediate // block parent, and then further expands to include any ancestors // whose children are all in the range - res = GetNodesFromSelection(aSelection, EditAction::indent, arrayOfNodes); + res = GetNodesFromSelection(*aSelection, EditAction::indent, array); NS_ENSURE_SUCCESS(res, res); } + + nsCOMArray arrayOfNodes; + for (auto& node : array) { + arrayOfNodes.AppendObject(GetAsDOMNode(node)); + } // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) @@ -4105,8 +4109,8 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, // this basically just expands the range to include the immediate // block parent, and then further expands to include any ancestors // whose children are all in the range - nsCOMArray arrayOfNodes; - res = GetNodesFromSelection(aSelection, EditAction::outdent, + nsTArray> arrayOfNodes; + res = GetNodesFromSelection(*aSelection, EditAction::outdent, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); @@ -4115,20 +4119,13 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, nsCOMPtr curBlockQuote, firstBQChild, lastBQChild; bool curBlockQuoteIsIndentedWithCSS = false; - int32_t listCount = arrayOfNodes.Count(); - int32_t i; - for (i=0; i curNode = arrayOfNodes[i]; - nsCOMPtr curNode_ = do_QueryInterface(curNode); - NS_ENSURE_STATE(curNode_); - nsCOMPtr curParent = curNode_->GetParentNode(); - int32_t offset = curParent ? curParent->IndexOf(curNode_) : -1; + nsCOMPtr curParent = curNode->GetParentNode(); + int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; // is it a blockquote? - if (nsHTMLEditUtils::IsBlockquote(curNode)) - { + if (curNode->IsHTMLElement(nsGkAtoms::blockquote)) { // if it is a blockquote, remove it. // So we need to finish up dealng with any curBlockQuote first. if (curBlockQuote) @@ -4142,18 +4139,19 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, curBlockQuoteIsIndentedWithCSS = false; } NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->RemoveBlockContainer(curNode); + res = mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(curNode)); NS_ENSURE_SUCCESS(res, res); continue; } // is it a block with a 'margin' property? - if (useCSS && IsBlockNode(curNode)) - { + if (useCSS && IsBlockNode(GetAsDOMNode(curNode))) { NS_ENSURE_STATE(mHTMLEditor); - nsIAtom* marginProperty = MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, curNode); + nsIAtom* marginProperty = + MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, + GetAsDOMNode(curNode)); nsAutoString value; NS_ENSURE_STATE(mHTMLEditor); - mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(*curNode_, + mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(*curNode, *marginProperty, value); float f; @@ -4162,7 +4160,7 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, mHTMLEditor->mHTMLCSSUtils->ParseLength(value, &f, getter_AddRefs(unit)); if (f > 0) { - RelativeChangeIndentationOfElementNode(curNode, -1); + RelativeChangeIndentationOfElementNode(GetAsDOMNode(curNode), -1); continue; } } @@ -4183,7 +4181,7 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, curBlockQuoteIsIndentedWithCSS = false; } bool bOutOfList; - res = PopListItem(curNode, &bOutOfList); + res = PopListItem(GetAsDOMNode(curNode), &bOutOfList); NS_ENSURE_SUCCESS(res, res); continue; } @@ -4191,9 +4189,9 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (curBlockQuote) { // if so, is this node a descendant? - if (nsEditorUtils::IsDescendantOf(curNode, curBlockQuote)) - { - lastBQChild = curNode; + if (nsEditorUtils::IsDescendantOf(GetAsDOMNode(curNode), + curBlockQuote)) { + lastBQChild = GetAsDOMNode(curNode); continue; // then we don't need to do anything different for this node } else @@ -4213,7 +4211,7 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, } // are we inside a blockquote? - nsCOMPtr n = curNode_; + nsCOMPtr n = curNode; curBlockQuoteIsIndentedWithCSS = false; // keep looking up the hierarchy as long as we don't hit the body or the // active editing host or a table element (other than an entire table) @@ -4228,14 +4226,16 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (n->IsHTMLElement(nsGkAtoms::blockquote)) { // if so, remember it, and remember first node we are taking out of it. curBlockQuote = GetAsDOMNode(n); - firstBQChild = curNode; - lastBQChild = curNode; + firstBQChild = GetAsDOMNode(curNode); + lastBQChild = GetAsDOMNode(curNode); break; } else if (useCSS) { NS_ENSURE_STATE(mHTMLEditor); - nsIAtom* marginProperty = MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, curNode); + nsIAtom* marginProperty = + MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, + GetAsDOMNode(curNode)); nsAutoString value; NS_ENSURE_STATE(mHTMLEditor); mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(*n, *marginProperty, @@ -4247,8 +4247,8 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (f > 0 && !(nsHTMLEditUtils::IsList(curParent) && nsHTMLEditUtils::IsList(curNode))) { curBlockQuote = GetAsDOMNode(n); - firstBQChild = curNode; - lastBQChild = curNode; + firstBQChild = GetAsDOMNode(curNode); + lastBQChild = GetAsDOMNode(curNode); curBlockQuoteIsIndentedWithCSS = true; break; } @@ -4263,17 +4263,14 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (nsHTMLEditUtils::IsList(curNode)) // just unwrap this sublist { NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->RemoveBlockContainer(curNode); + res = mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(curNode)); NS_ENSURE_SUCCESS(res, res); } // handled list item case above } else if (nsHTMLEditUtils::IsList(curNode)) // node is a list, but parent is non-list: move list items out { - nsCOMPtr childDOM; - curNode->GetLastChild(getter_AddRefs(childDOM)); - nsCOMPtr child = do_QueryInterface(childDOM); - NS_ENSURE_STATE(!childDOM || child); + nsCOMPtr child = curNode->GetLastChild(); while (child) { if (nsHTMLEditUtils::IsListItem(child)) @@ -4300,13 +4297,11 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, res = mHTMLEditor->DeleteNode(child); NS_ENSURE_SUCCESS(res, res); } - curNode->GetLastChild(getter_AddRefs(childDOM)); - child = do_QueryInterface(childDOM); - NS_ENSURE_STATE(!childDOM || child); + child = curNode->GetLastChild(); } // delete the now-empty list NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->RemoveBlockContainer(curNode); + res = mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(curNode)); NS_ENSURE_SUCCESS(res, res); } else if (useCSS) { @@ -4709,21 +4704,20 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, // block parent, and then further expands to include any ancestors // whose children are all in the range *aHandled = true; - nsCOMArray arrayOfNodes; - res = GetNodesFromSelection(aSelection, EditAction::align, arrayOfNodes); + nsTArray> array; + res = GetNodesFromSelection(*aSelection, EditAction::align, array); NS_ENSURE_SUCCESS(res, res); // if we don't have any nodes, or we have only a single br, then we are // creating an empty alignment div. We have to do some different things for these. bool emptyDiv = false; - int32_t listCount = arrayOfNodes.Count(); + int32_t listCount = array.Length(); if (!listCount) emptyDiv = true; if (listCount == 1) { - nsCOMPtr theNode = arrayOfNodes[0]; + nsCOMPtr theNode = array[0]; - if (nsHTMLEditUtils::SupportsAlignAttr(theNode)) - { + if (nsHTMLEditUtils::SupportsAlignAttr(GetAsDOMNode(theNode))) { // the node is a table element, an horiz rule, a paragraph, a div // or a section header; in HTML 4, it can directly carry the ALIGN // attribute and we don't need to make a div! If we are in CSS mode, @@ -4814,6 +4808,11 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, // Next we detect all the transitions in the array, where a transition // means that adjacent nodes in the array don't have the same parent. + nsCOMArray arrayOfNodes; + for (auto& node : array) { + arrayOfNodes.AppendObject(GetAsDOMNode(node)); + } + nsTArray transitionList; res = MakeTransitionList(arrayOfNodes, transitionList); NS_ENSURE_SUCCESS(res, res); @@ -5160,39 +5159,13 @@ nsHTMLEditRules::CheckForInvisibleBR(nsIDOMNode *aBlock, //////////////////////////////////////////////////////////////////////////////// -// GetInnerContent: aList and aTbl allow the caller to specify what kind of -// content to "look inside". If aTbl is true, look inside any -// table content, and insert the inner content into the -// supplied issupportsarray at offset aIndex. Similarly with -// aList and list content. aIndex is updated to point past -// inserted elements. +// GetInnerContent: aLists and aTables allow the caller to specify what kind of +// content to "look inside". If aTables is Tables::yes, look +// inside any table content, and insert the inner content into +// the supplied issupportsarray at offset aIndex. Similarly +// with aLists and list content. aIndex is updated to point +// past inserted elements. // -nsresult -nsHTMLEditRules::GetInnerContent(nsIDOMNode* aNode, - nsCOMArray& aOutArrayOfDOMNodes, - int32_t* aIndex, bool aLists, bool aTables) -{ - // To be removed in a subsequent patch - nsCOMPtr node = do_QueryInterface(aNode); - NS_ENSURE_STATE(node); - nsTArray> aOutArrayOfNodes; - for (int32_t i = 0; i < aOutArrayOfDOMNodes.Count(); i++) { - nsCOMPtr newNode = do_QueryInterface(aOutArrayOfDOMNodes[i]); - if (newNode) { - aOutArrayOfNodes.AppendElement(newNode); - } - } - GetInnerContent(*node, aOutArrayOfNodes, aIndex, - aLists ? Lists::yes : Lists::no, - aTables ? Tables::yes : Tables::no); - aOutArrayOfDOMNodes.Clear(); - for (auto& node : aOutArrayOfNodes) { - aOutArrayOfDOMNodes.AppendElement(GetAsDOMNode(node)); - } - - return NS_OK; -} - void nsHTMLEditRules::GetInnerContent(nsINode& aNode, nsTArray>& aOutArrayOfNodes, @@ -6046,29 +6019,38 @@ nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, if (outArrayOfNodes.Count()) return NS_OK; } + nsTArray> arrayOfNodes; + for (int32_t i = 0; i < outArrayOfNodes.Count(); i++) { + nsCOMPtr node = do_QueryInterface(outArrayOfNodes[i]); + NS_ENSURE_STATE(node || !outArrayOfNodes[i]); + arrayOfNodes.AppendElement(node); + } + { // We don't like other people messing with our selection! NS_ENSURE_STATE(mHTMLEditor); nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor); // contruct a list of nodes to act on. - res = GetNodesFromSelection(selection, EditAction::makeList, - outArrayOfNodes, aDontTouchContent); + res = GetNodesFromSelection(*selection, EditAction::makeList, + arrayOfNodes, aDontTouchContent ? + TouchContent::no : TouchContent::yes); NS_ENSURE_SUCCESS(res, res); } // pre process our list of nodes... - int32_t listCount = outArrayOfNodes.Count(); + int32_t listCount = arrayOfNodes.Length(); int32_t i; for (i=listCount-1; i>=0; i--) { - nsCOMPtr testNode = outArrayOfNodes[i]; + nsCOMPtr testNode = arrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. NS_ENSURE_STATE(mHTMLEditor); if (!mHTMLEditor->IsEditable(testNode)) { - outArrayOfNodes.RemoveObjectAt(i); + arrayOfNodes.RemoveElementAt(i); + continue; } // scan for table elements and divs. If we find table elements other than table, @@ -6076,20 +6058,13 @@ nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, if (nsHTMLEditUtils::IsTableElementButNotTable(testNode)) { int32_t j=i; - outArrayOfNodes.RemoveObjectAt(i); - res = GetInnerContent(testNode, outArrayOfNodes, &j, false); - NS_ENSURE_SUCCESS(res, res); + arrayOfNodes.RemoveElementAt(i); + GetInnerContent(*testNode, arrayOfNodes, &j, Lists::no); } } // if there is only one node in the array, and it is a list, div, or blockquote, // then look inside of it until we find inner list or content. - nsTArray> arrayOfNodes; - for (int32_t i = 0; i < outArrayOfNodes.Count(); i++) { - nsCOMPtr node = do_QueryInterface(outArrayOfNodes[i]); - NS_ENSURE_STATE(node); - arrayOfNodes.AppendElement(node); - } LookInsideDivBQandList(arrayOfNodes); outArrayOfNodes.Clear(); for (auto& node : arrayOfNodes) { @@ -6180,26 +6155,29 @@ nsHTMLEditRules::GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes bool aDontTouchContent) { NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); + nsRefPtr selection = mHTMLEditor->GetSelection(); NS_ENSURE_STATE(selection); // contruct a list of nodes to act on. - nsresult res = GetNodesFromSelection(selection, EditAction::makeBasicBlock, - outArrayOfNodes, aDontTouchContent); + nsTArray> arrayOfNodes; + nsresult res = GetNodesFromSelection(*selection, EditAction::makeBasicBlock, + arrayOfNodes, aDontTouchContent ? + TouchContent::no : TouchContent::yes); NS_ENSURE_SUCCESS(res, res); // pre process our list of nodes... - int32_t listCount = outArrayOfNodes.Count(); + int32_t listCount = arrayOfNodes.Length(); int32_t i; for (i=listCount-1; i>=0; i--) { - nsCOMPtr testNode = outArrayOfNodes[i]; + nsCOMPtr testNode = arrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. - NS_ENSURE_STATE(mHTMLEditor); if (!mHTMLEditor->IsEditable(testNode)) { - outArrayOfNodes.RemoveObjectAt(i); + arrayOfNodes.RemoveElementAt(i); } // scan for table elements. If we find table elements other than table, @@ -6209,11 +6187,13 @@ nsHTMLEditRules::GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes nsHTMLEditUtils::IsListItem(testNode) ) { int32_t j=i; - outArrayOfNodes.RemoveObjectAt(i); - res = GetInnerContent(testNode, outArrayOfNodes, &j); - NS_ENSURE_SUCCESS(res, res); + arrayOfNodes.RemoveElementAt(i); + GetInnerContent(*testNode, arrayOfNodes, &j); } } + for (auto& node : arrayOfNodes) { + outArrayOfNodes.AppendObject(GetAsDOMNode(node)); + } return res; } @@ -6383,31 +6363,26 @@ nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point, } -/////////////////////////////////////////////////////////////////////////// -// GetNodesFromSelection: given a particular operation, construct a list -// of nodes from the selection that will be operated on. -// -nsresult -nsHTMLEditRules::GetNodesFromSelection(Selection* selection, - EditAction operation, - nsCOMArray& arrayOfNodes, - bool dontTouchContent) +/////////////////////////////////////////////////////////////////////////////// +// GetNodesFromSelection: Given a particular operation, construct a list of +// nodes from the selection that will be operated on. +// +nsresult +nsHTMLEditRules::GetNodesFromSelection(Selection& aSelection, + EditAction aOperation, + nsTArray>& outArrayOfNodes, + TouchContent aTouchContent) { - NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - nsresult res; - - // promote selection ranges + // Promote selection ranges nsTArray> arrayOfRanges; - GetPromotedRanges(*selection, arrayOfRanges, operation); - - // use these ranges to contruct a list of nodes to act on. - nsTArray> array; - res = GetNodesForOperation(arrayOfRanges, array, operation, dontTouchContent - ? TouchContent::no : TouchContent::yes); - for (auto& node : array) { - arrayOfNodes.AppendObject(GetAsDOMNode(node)); - } - return res; + GetPromotedRanges(aSelection, arrayOfRanges, aOperation); + + // Use these ranges to contruct a list of nodes to act on. + nsresult res = GetNodesForOperation(arrayOfRanges, outArrayOfNodes, + aOperation, aTouchContent); + NS_ENSURE_SUCCESS(res, res); + + return NS_OK; } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 547944e2c221..ef114ecce2c1 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -200,10 +200,6 @@ protected: nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat); enum class Lists { no, yes }; enum class Tables { no, yes }; - nsresult GetInnerContent(nsIDOMNode* aNode, - nsCOMArray& aOutArrayOfNodes, - int32_t* aIndex, bool aLists = true, - bool aTables = true); void GetInnerContent(nsINode& aNode, nsTArray>& aOutArrayOfNodes, int32_t* aIndex, Lists aLists = Lists::yes, @@ -287,10 +283,10 @@ protected: EditAction operation, nsCOMArray& arrayOfNodes, bool dontTouchContent); - nsresult GetNodesFromSelection(mozilla::dom::Selection* selection, - EditAction operation, - nsCOMArray& arrayOfNodes, - bool aDontTouchContent=false); + nsresult GetNodesFromSelection(mozilla::dom::Selection& aSelection, + EditAction aOperation, + nsTArray>& outArrayOfNodes, + TouchContent aTouchContent = TouchContent::yes); nsresult GetListActionNodes(nsCOMArray &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false); void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD); nsresult GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, bool aDontTouchContent=false); From 2d24577b859147ac2a899480319b4772553ca098 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 124/241] Bug 1153629 part 1 - Clean up nsHTMLEditRules::GetListActionNodes; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 203 +++++++++++---------------- editor/libeditor/nsHTMLEditRules.h | 5 +- 2 files changed, 84 insertions(+), 124 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index fd0b3a882d9b..90f2e8b2e7b8 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -692,33 +692,30 @@ nsHTMLEditRules::GetListState(bool *aMixed, bool *aOL, bool *aUL, bool *aDL) *aDL = false; bool bNonList = false; - nsCOMArray arrayOfNodes; - nsresult res = GetListActionNodes(arrayOfNodes, false, true); + nsTArray> arrayOfNodes; + nsresult res = GetListActionNodes(arrayOfNodes, EntireList::no, + TouchContent::no); NS_ENSURE_SUCCESS(res, res); // Examine list type for nodes in selection. - int32_t listCount = arrayOfNodes.Count(); - for (int32_t i = listCount - 1; i >= 0; --i) { - nsIDOMNode* curDOMNode = arrayOfNodes[i]; - nsCOMPtr curElement = do_QueryInterface(curDOMNode); - - if (!curElement) { + for (const auto& curNode : arrayOfNodes) { + if (!curNode->IsElement()) { bNonList = true; - } else if (curElement->IsHTMLElement(nsGkAtoms::ul)) { + } else if (curNode->IsHTMLElement(nsGkAtoms::ul)) { *aUL = true; - } else if (curElement->IsHTMLElement(nsGkAtoms::ol)) { + } else if (curNode->IsHTMLElement(nsGkAtoms::ol)) { *aOL = true; - } else if (curElement->IsHTMLElement(nsGkAtoms::li)) { - if (dom::Element* parent = curElement->GetParentElement()) { + } else if (curNode->IsHTMLElement(nsGkAtoms::li)) { + if (dom::Element* parent = curNode->GetParentElement()) { if (parent->IsHTMLElement(nsGkAtoms::ul)) { *aUL = true; } else if (parent->IsHTMLElement(nsGkAtoms::ol)) { *aOL = true; } } - } else if (curElement->IsAnyOfHTMLElements(nsGkAtoms::dl, - nsGkAtoms::dt, - nsGkAtoms::dd)) { + } else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::dl, + nsGkAtoms::dt, + nsGkAtoms::dd)) { *aDL = true; } else { bNonList = true; @@ -743,29 +740,27 @@ nsHTMLEditRules::GetListItemState(bool *aMixed, bool *aLI, bool *aDT, bool *aDD) *aDD = false; bool bNonList = false; - nsCOMArray arrayOfNodes; - nsresult res = GetListActionNodes(arrayOfNodes, false, true); + nsTArray> arrayOfNodes; + nsresult res = GetListActionNodes(arrayOfNodes, EntireList::no, + TouchContent::no); NS_ENSURE_SUCCESS(res, res); // examine list type for nodes in selection - int32_t listCount = arrayOfNodes.Count(); - for (int32_t i = listCount - 1; i >= 0; --i) { - nsIDOMNode* curNode = arrayOfNodes[i]; - nsCOMPtr element = do_QueryInterface(curNode); - if (!element) { + for (const auto& node : arrayOfNodes) { + if (!node->IsElement()) { bNonList = true; - } else if (element->IsAnyOfHTMLElements(nsGkAtoms::ul, - nsGkAtoms::ol, - nsGkAtoms::li)) { + } else if (node->IsAnyOfHTMLElements(nsGkAtoms::ul, + nsGkAtoms::ol, + nsGkAtoms::li)) { *aLI = true; - } else if (element->IsHTMLElement(nsGkAtoms::dt)) { + } else if (node->IsHTMLElement(nsGkAtoms::dt)) { *aDT = true; - } else if (element->IsHTMLElement(nsGkAtoms::dd)) { + } else if (node->IsHTMLElement(nsGkAtoms::dd)) { *aDD = true; - } else if (element->IsHTMLElement(nsGkAtoms::dl)) { + } else if (node->IsHTMLElement(nsGkAtoms::dl)) { // need to look inside dl and see which types of items it has bool bDT, bDD; - GetDefinitionListItemTypes(element, &bDT, &bDD); + GetDefinitionListItemTypes(node->AsElement(), &bDT, &bDD); *aDT |= bDT; *aDD |= bDD; } else { @@ -3085,18 +3080,17 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); - nsCOMArray arrayOfDOMNodes; - res = GetListActionNodes(arrayOfDOMNodes, aEntireList); + nsTArray> arrayOfNodes; + res = GetListActionNodes(arrayOfNodes, + aEntireList ? EntireList::yes : EntireList::no); NS_ENSURE_SUCCESS(res, res); - int32_t listCount = arrayOfDOMNodes.Count(); - // check if all our nodes are
    s, or empty inlines bool bOnlyBreaks = true; - for (int32_t j = 0; j < listCount; j++) { - nsIDOMNode* curNode = arrayOfDOMNodes[j]; + for (auto& curNode : arrayOfNodes) { // if curNode is not a Break or empty inline, we're done - if (!nsTextEditUtils::IsBreak(curNode) && !IsEmptyInline(curNode)) { + if (!nsTextEditUtils::IsBreak(curNode) && + !IsEmptyInline(GetAsDOMNode(curNode))) { bOnlyBreaks = false; break; } @@ -3104,12 +3098,12 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, // if no nodes, we make empty list. Ditto if the user tried to make a list // of some # of breaks. - if (!listCount || bOnlyBreaks) { + if (!arrayOfNodes.Length() || bOnlyBreaks) { // if only breaks, delete them if (bOnlyBreaks) { - for (int32_t j = 0; j < (int32_t)listCount; j++) { + for (auto& node : arrayOfNodes) { NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->DeleteNode(arrayOfDOMNodes[j]); + res = mHTMLEditor->DeleteNode(node); NS_ENSURE_SUCCESS(res, res); } } @@ -3151,22 +3145,16 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, // if there is only one node in the array, and it is a list, div, or // blockquote, then look inside of it until we find inner list or content. - nsTArray> arrayOfNodes; - for (int32_t i = 0; i < arrayOfDOMNodes.Count(); i++) { - nsCOMPtr node = do_QueryInterface(arrayOfDOMNodes[i]); - NS_ENSURE_STATE(node); - arrayOfNodes.AppendElement(node); - } LookInsideDivBQandList(arrayOfNodes); // Ok, now go through all the nodes and put then in the list, // or whatever is approriate. Wohoo! - listCount = arrayOfNodes.Length(); + uint32_t listCount = arrayOfNodes.Length(); nsCOMPtr curParent; nsCOMPtr curList, prevListItem; - for (int32_t i = 0; i < listCount; i++) { + for (uint32_t i = 0; i < listCount; i++) { // here's where we actually figure out what to do nsCOMPtr newBlock; NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); @@ -3375,47 +3363,41 @@ nsHTMLEditRules::WillRemoveList(Selection* aSelection, GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::makeList); // use these ranges to contruct a list of nodes to act on. - nsCOMArray arrayOfNodes; - res = GetListActionNodes(arrayOfNodes, false); + nsTArray> arrayOfNodes; + res = GetListActionNodes(arrayOfNodes, EntireList::no); NS_ENSURE_SUCCESS(res, res); // Remove all non-editable nodes. Leave them be. - int32_t listCount = arrayOfNodes.Count(); + int32_t listCount = arrayOfNodes.Length(); int32_t i; for (i=listCount-1; i>=0; i--) { - nsIDOMNode* testNode = arrayOfNodes[i]; + nsCOMPtr& testNode = arrayOfNodes[i]; NS_ENSURE_STATE(mHTMLEditor); if (!mHTMLEditor->IsEditable(testNode)) { - arrayOfNodes.RemoveObjectAt(i); + arrayOfNodes.RemoveElementAt(i); } } // reset list count - listCount = arrayOfNodes.Count(); + listCount = arrayOfNodes.Length(); // Only act on lists or list items in the array - nsCOMPtr curParent; - for (i=0; i &outArrayOfNodes, - bool aEntireList, - bool aDontTouchContent) +nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNodes, + EntireList aEntireList, + TouchContent aTouchContent) { - nsresult res = NS_OK; - NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); + nsRefPtr selection = mHTMLEditor->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE); - // added this in so that ui code can ask to change an entire list, even if selection - // is only in part of it. used by list item dialog. - if (aEntireList) - { + + // Added this in so that ui code can ask to change an entire list, even if + // selection is only in part of it. used by list item dialog. + if (aEntireList == EntireList::yes) { uint32_t rangeCount = selection->RangeCount(); for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) { nsRefPtr range = selection->GetRangeAt(rangeIdx); - nsCOMPtr commonParent, parent, tmp; - range->GetCommonAncestorContainer(getter_AddRefs(commonParent)); - if (commonParent) - { - parent = commonParent; - while (parent) - { - if (nsHTMLEditUtils::IsList(parent)) - { - outArrayOfNodes.AppendObject(parent); - break; - } - parent->GetParentNode(getter_AddRefs(tmp)); - parent = tmp; + for (nsCOMPtr parent = range->GetCommonAncestor(); + parent; parent = parent->GetParentNode()) { + if (nsHTMLEditUtils::IsList(parent)) { + aOutArrayOfNodes.AppendElement(parent); + break; } } } - // if we didn't find any nodes this way, then try the normal way. perhaps the - // selection spans multiple lists but with no common list parent. - if (outArrayOfNodes.Count()) return NS_OK; - } - - nsTArray> arrayOfNodes; - for (int32_t i = 0; i < outArrayOfNodes.Count(); i++) { - nsCOMPtr node = do_QueryInterface(outArrayOfNodes[i]); - NS_ENSURE_STATE(node || !outArrayOfNodes[i]); - arrayOfNodes.AppendElement(node); + // If we didn't find any nodes this way, then try the normal way. Perhaps + // the selection spans multiple lists but with no common list parent. + if (aOutArrayOfNodes.Length()) { + return NS_OK; + } } { // We don't like other people messing with our selection! - NS_ENSURE_STATE(mHTMLEditor); nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor); // contruct a list of nodes to act on. - res = GetNodesFromSelection(*selection, EditAction::makeList, - arrayOfNodes, aDontTouchContent ? - TouchContent::no : TouchContent::yes); + nsresult res = GetNodesFromSelection(*selection, EditAction::makeList, + aOutArrayOfNodes, aTouchContent); NS_ENSURE_SUCCESS(res, res); } - // pre process our list of nodes... - int32_t listCount = arrayOfNodes.Length(); - int32_t i; - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr testNode = arrayOfNodes[i]; + // Pre-process our list of nodes + for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { + nsCOMPtr testNode = aOutArrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. - NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsEditable(testNode)) - { - arrayOfNodes.RemoveElementAt(i); + if (!mHTMLEditor->IsEditable(testNode)) { + aOutArrayOfNodes.RemoveElementAt(i); continue; } - // scan for table elements and divs. If we find table elements other than table, - // replace it with a list of any editable non-table content. - if (nsHTMLEditUtils::IsTableElementButNotTable(testNode)) - { - int32_t j=i; - arrayOfNodes.RemoveElementAt(i); - GetInnerContent(*testNode, arrayOfNodes, &j, Lists::no); + // Scan for table elements and divs. If we find table elements other than + // table, replace it with a list of any editable non-table content. + if (nsHTMLEditUtils::IsTableElementButNotTable(testNode)) { + int32_t j = i; + aOutArrayOfNodes.RemoveElementAt(i); + GetInnerContent(*testNode, aOutArrayOfNodes, &j, Lists::no); } } - // if there is only one node in the array, and it is a list, div, or blockquote, - // then look inside of it until we find inner list or content. - LookInsideDivBQandList(arrayOfNodes); - outArrayOfNodes.Clear(); - for (auto& node : arrayOfNodes) { - outArrayOfNodes.AppendObject(GetAsDOMNode(node)); - } + // If there is only one node in the array, and it is a list, div, or + // blockquote, then look inside of it until we find inner list or content. + LookInsideDivBQandList(aOutArrayOfNodes); + return NS_OK; } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index ef114ecce2c1..7c3131c1acb9 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -287,7 +287,10 @@ protected: EditAction aOperation, nsTArray>& outArrayOfNodes, TouchContent aTouchContent = TouchContent::yes); - nsresult GetListActionNodes(nsCOMArray &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false); + enum class EntireList { no, yes }; + nsresult GetListActionNodes(nsTArray>& aOutArrayOfNodes, + EntireList aEntireList, + TouchContent aTouchContent = TouchContent::yes); void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD); nsresult GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, bool aDontTouchContent=false); void LookInsideDivBQandList(nsTArray>& aNodeArray); From c209027f9633d94b0aa7996eaad61eaac6d0f77d Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 125/241] Bug 1153629 part 2 - Clean up nsHTMLEditRules::GetParagraphFormatNodes; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 107 ++++++++++----------------- editor/libeditor/nsHTMLEditRules.h | 8 +- 2 files changed, 42 insertions(+), 73 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 90f2e8b2e7b8..9caf7661f08a 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -1061,22 +1061,19 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) // using "x" as an uninitialized value, since "" is meaningful nsAutoString formatStr(NS_LITERAL_STRING("x")); - nsCOMArray arrayOfNodes; - nsresult res = GetParagraphFormatNodes(arrayOfNodes, true); + nsTArray> arrayOfNodes; + nsresult res = GetParagraphFormatNodes(arrayOfNodes, TouchContent::no); NS_ENSURE_SUCCESS(res, res); // post process list. We need to replace any block nodes that are not format // nodes with their content. This is so we only have to look "up" the hierarchy // to find format nodes, instead of both up and down. - int32_t listCount = arrayOfNodes.Count(); - int32_t i; - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr curNode = arrayOfNodes[i]; + for (int32_t i = arrayOfNodes.Length() - 1; i >= 0; i--) { + auto& curNode = arrayOfNodes[i]; nsAutoString format; // if it is a known format node we have it easy - if (IsBlockNode(curNode) && !nsHTMLEditUtils::IsFormatNode(curNode)) - { + if (IsBlockNode(GetAsDOMNode(curNode)) && + !nsHTMLEditUtils::IsFormatNode(curNode)) { // arrayOfNodes.RemoveObject(curNode); res = AppendInnerFormatNodes(arrayOfNodes, curNode); NS_ENSURE_SUCCESS(res, res); @@ -1085,10 +1082,8 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) // we might have an empty node list. if so, find selection parent // and put that on the list - listCount = arrayOfNodes.Count(); - if (!listCount) - { - nsCOMPtr selNode; + if (!arrayOfNodes.Length()) { + nsCOMPtr selNode; int32_t selOffset; NS_ENSURE_STATE(mHTMLEditor); nsRefPtr selection = mHTMLEditor->GetSelection(); @@ -1097,8 +1092,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) res = mHTMLEditor->GetStartNodeAndOffset(selection, getter_AddRefs(selNode), &selOffset); NS_ENSURE_SUCCESS(res, res); NS_ENSURE_TRUE(selNode, NS_ERROR_NULL_POINTER); - arrayOfNodes.AppendObject(selNode); - listCount = 1; + arrayOfNodes.AppendElement(selNode); } // remember root node @@ -1107,15 +1101,12 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) NS_ENSURE_TRUE(rootElem, NS_ERROR_NULL_POINTER); // loop through the nodes in selection and examine their paragraph format - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr curNode = arrayOfNodes[i]; + for (auto& curNode : Reversed(arrayOfNodes)) { nsAutoString format; // if it is a known format node we have it easy - if (nsHTMLEditUtils::IsFormatNode(curNode)) - GetFormatString(curNode, format); - else if (IsBlockNode(curNode)) - { + if (nsHTMLEditUtils::IsFormatNode(curNode)) { + GetFormatString(GetAsDOMNode(curNode), format); + } else if (IsBlockNode(GetAsDOMNode(curNode))) { // this is a div or some other non-format block. // we should ignore it. Its children were appended to this list // by AppendInnerFormatNodes() call above. We will get needed @@ -1124,7 +1115,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) } else { - nsCOMPtr node, tmp = curNode; + nsCOMPtr node, tmp = GetAsDOMNode(curNode); tmp->GetParentNode(getter_AddRefs(node)); while (node) { @@ -1161,17 +1152,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) } nsresult -nsHTMLEditRules::AppendInnerFormatNodes(nsCOMArray& aArray, - nsIDOMNode *aNode) -{ - nsCOMPtr node = do_QueryInterface(aNode); - NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); - - return AppendInnerFormatNodes(aArray, node); -} - -nsresult -nsHTMLEditRules::AppendInnerFormatNodes(nsCOMArray& aArray, +nsHTMLEditRules::AppendInnerFormatNodes(nsTArray>& aArray, nsINode* aNode) { MOZ_ASSERT(aNode); @@ -1190,11 +1171,11 @@ nsHTMLEditRules::AppendInnerFormatNodes(nsCOMArray& aArray, // if it's a div, etc, recurse AppendInnerFormatNodes(aArray, child); } else if (isFormat) { - aArray.AppendObject(child->AsDOMNode()); + aArray.AppendElement(child); } else if (!foundInline) { // if this is the first inline we've found, use it foundInline = true; - aArray.AppendObject(child->AsDOMNode()); + aArray.AppendElement(child); } } return NS_OK; @@ -6104,54 +6085,42 @@ nsHTMLEditRules::GetDefinitionListItemTypes(dom::Element* aElement, bool* aDT, b } } -/////////////////////////////////////////////////////////////////////////// -// GetParagraphFormatNodes: -// -nsresult -nsHTMLEditRules::GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, - bool aDontTouchContent) -{ +nsresult +nsHTMLEditRules::GetParagraphFormatNodes(nsTArray>& outArrayOfNodes, + TouchContent aTouchContent) +{ NS_ENSURE_STATE(mHTMLEditor); nsCOMPtr kungFuDeathGrip(mHTMLEditor); nsRefPtr selection = mHTMLEditor->GetSelection(); NS_ENSURE_STATE(selection); - // contruct a list of nodes to act on. - nsTArray> arrayOfNodes; + // Contruct a list of nodes to act on. nsresult res = GetNodesFromSelection(*selection, EditAction::makeBasicBlock, - arrayOfNodes, aDontTouchContent ? - TouchContent::no : TouchContent::yes); + outArrayOfNodes, aTouchContent); NS_ENSURE_SUCCESS(res, res); - // pre process our list of nodes... - int32_t listCount = arrayOfNodes.Length(); - int32_t i; - for (i=listCount-1; i>=0; i--) - { - nsCOMPtr testNode = arrayOfNodes[i]; + // Pre-process our list of nodes + for (int32_t i = outArrayOfNodes.Length() - 1; i >= 0; i--) { + nsCOMPtr testNode = outArrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. - if (!mHTMLEditor->IsEditable(testNode)) - { - arrayOfNodes.RemoveElementAt(i); + if (!mHTMLEditor->IsEditable(testNode)) { + outArrayOfNodes.RemoveElementAt(i); } - - // scan for table elements. If we find table elements other than table, - // replace it with a list of any editable non-table content. Ditto for list elements. + + // Scan for table elements. If we find table elements other than table, + // replace it with a list of any editable non-table content. Ditto for + // list elements. if (nsHTMLEditUtils::IsTableElement(testNode) || - nsHTMLEditUtils::IsList(testNode) || - nsHTMLEditUtils::IsListItem(testNode) ) - { - int32_t j=i; - arrayOfNodes.RemoveElementAt(i); - GetInnerContent(*testNode, arrayOfNodes, &j); + nsHTMLEditUtils::IsList(testNode) || + nsHTMLEditUtils::IsListItem(testNode)) { + int32_t j = i; + outArrayOfNodes.RemoveElementAt(i); + GetInnerContent(*testNode, outArrayOfNodes, &j); } } - for (auto& node : arrayOfNodes) { - outArrayOfNodes.AppendObject(GetAsDOMNode(node)); - } - return res; + return NS_OK; } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 7c3131c1acb9..7f0a1e5cd1a5 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -193,10 +193,8 @@ protected: nsresult DidAbsolutePosition(); nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType); nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType); - nsresult AppendInnerFormatNodes(nsCOMArray& aArray, + nsresult AppendInnerFormatNodes(nsTArray>& aArray, nsINode* aNode); - nsresult AppendInnerFormatNodes(nsCOMArray& aArray, - nsIDOMNode *aNode); nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat); enum class Lists { no, yes }; enum class Tables { no, yes }; @@ -292,7 +290,9 @@ protected: EntireList aEntireList, TouchContent aTouchContent = TouchContent::yes); void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD); - nsresult GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, bool aDontTouchContent=false); + nsresult GetParagraphFormatNodes( + nsTArray>& outArrayOfNodes, + TouchContent aTouchContent = TouchContent::yes); void LookInsideDivBQandList(nsTArray>& aNodeArray); nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange); nsresult BustUpInlinesAtBRs(nsINode& aNode, From 46ef2fe868b2f726d1f56c105e7d426fa588e0a1 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 126/241] Bug 1153629 part 3 - Clean up nsHTMLEditRules::GetNodesFromPoint; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 75 +++++++++++++--------------- editor/libeditor/nsHTMLEditRules.h | 8 +-- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 9caf7661f08a..38216b3319ca 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -2862,22 +2862,17 @@ nsHTMLEditRules::JoinBlocks(nsIDOMNode *aLeftNode, nsresult nsHTMLEditRules::MoveBlock(nsIDOMNode *aLeftBlock, nsIDOMNode *aRightBlock, int32_t aLeftOffset, int32_t aRightOffset) { - nsCOMArray arrayOfNodes; - nsCOMPtr isupports; + nsTArray> arrayOfNodes; // GetNodesFromPoint is the workhorse that figures out what we wnat to move. nsresult res = GetNodesFromPoint(::DOMPoint(aRightBlock,aRightOffset), - EditAction::makeList, arrayOfNodes, true); + EditAction::makeList, arrayOfNodes, + TouchContent::no); NS_ENSURE_SUCCESS(res, res); - int32_t listCount = arrayOfNodes.Count(); - int32_t i; - for (i=0; iDeleteNode(curNode); @@ -2885,7 +2880,7 @@ nsHTMLEditRules::MoveBlock(nsIDOMNode *aLeftBlock, nsIDOMNode *aRightBlock, int3 else { // otherwise move the content as is, checking against the dtd. - res = MoveNodeSmart(curNode, aLeftBlock, &aLeftOffset); + res = MoveNodeSmart(GetAsDOMNode(curNode), aLeftBlock, &aLeftOffset); } } return res; @@ -6254,38 +6249,36 @@ nsHTMLEditRules::GetHighestInlineParent(nsIDOMNode* aNode) } -/////////////////////////////////////////////////////////////////////////// -// GetNodesFromPoint: given a particular operation, construct a list -// of nodes from a point that will be operated on. -// -nsresult -nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point, - EditAction operation, - nsCOMArray &arrayOfNodes, - bool dontTouchContent) +/////////////////////////////////////////////////////////////////////////////// +// GetNodesFromPoint: Given a particular operation, construct a list of nodes +// from a point that will be operated on. +// +nsresult +nsHTMLEditRules::GetNodesFromPoint(::DOMPoint aPoint, + EditAction aOperation, + nsTArray>& outArrayOfNodes, + TouchContent aTouchContent) { - NS_ENSURE_STATE(point.node); - nsRefPtr range = new nsRange(point.node); - nsresult res = range->SetStart(point.node, point.offset); - NS_ENSURE_SUCCESS(res, res); - - // expand the range to include adjacent inlines - PromoteRange(*range, operation); - - // make array of ranges + NS_ENSURE_STATE(aPoint.node); + nsRefPtr range = new nsRange(aPoint.node); + nsresult res = range->SetStart(aPoint.node, aPoint.offset); + MOZ_ASSERT(NS_SUCCEEDED(res)); + + // Expand the range to include adjacent inlines + PromoteRange(*range, aOperation); + + // Make array of ranges nsTArray> arrayOfRanges; - - // stuff new opRange into array + + // Stuff new opRange into array arrayOfRanges.AppendElement(range); - - // use these ranges to contruct a list of nodes to act on. - nsTArray> array; - res = GetNodesForOperation(arrayOfRanges, array, operation, dontTouchContent - ? TouchContent::no : TouchContent::yes); - for (auto& node : array) { - arrayOfNodes.AppendObject(GetAsDOMNode(node)); - } - return res; + + // Use these ranges to contruct a list of nodes to act on + res = GetNodesForOperation(arrayOfRanges, outArrayOfNodes, aOperation, + aTouchContent); + NS_ENSURE_SUCCESS(res, res); + + return NS_OK; } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 7f0a1e5cd1a5..b1c13945b15d 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -277,10 +277,10 @@ protected: TouchContent aTouchContent = TouchContent::yes); nsresult GetChildNodesForOperation(nsIDOMNode *inNode, nsCOMArray& outArrayOfNodes); - nsresult GetNodesFromPoint(::DOMPoint point, - EditAction operation, - nsCOMArray& arrayOfNodes, - bool dontTouchContent); + nsresult GetNodesFromPoint(::DOMPoint aPoint, + EditAction aOperation, + nsTArray>& outArrayOfNodes, + TouchContent aTouchContent); nsresult GetNodesFromSelection(mozilla::dom::Selection& aSelection, EditAction aOperation, nsTArray>& outArrayOfNodes, From a97a88e485b434ec4fd3d8b5ae99487e4ff065f1 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:57 +0300 Subject: [PATCH 127/241] Bug 1153629 part 4 - Clean up nsHTMLEditRules::ListIsEmptyLine; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 161 ++++++++++++--------------- editor/libeditor/nsHTMLEditRules.h | 2 +- 2 files changed, 70 insertions(+), 93 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 38216b3319ca..df628dcfe801 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -3420,29 +3420,24 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, nsString tString(*aBlockType); // contruct a list of nodes to act on. - nsTArray> array; + nsTArray> arrayOfNodes; res = GetNodesFromSelection(*aSelection, EditAction::makeBasicBlock, - array); + arrayOfNodes); NS_ENSURE_SUCCESS(res, res); // Remove all non-editable nodes. Leave them be. - int32_t listCount = array.Length(); + int32_t listCount = arrayOfNodes.Length(); int32_t i; for (i=listCount-1; i>=0; i--) { NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsEditable(array[i])) { - array.RemoveElementAt(i); + if (!mHTMLEditor->IsEditable(arrayOfNodes[i])) { + arrayOfNodes.RemoveElementAt(i); } } - nsCOMArray arrayOfNodes; - for (auto& node : array) { - arrayOfNodes.AppendObject(GetAsDOMNode(node)); - } - // reset list count - listCount = arrayOfNodes.Count(); + listCount = arrayOfNodes.Length(); // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) @@ -3500,10 +3495,9 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, else // we are making a block { // consume a br, if needed - nsCOMPtr brNode; NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->GetNextHTMLNode(parent->AsDOMNode(), offset, - address_of(brNode), true); + nsCOMPtr brNode = + mHTMLEditor->GetNextHTMLNode(parent, offset, true); NS_ENSURE_SUCCESS(res, res); if (brNode && nsTextEditUtils::IsBreak(brNode)) { @@ -3511,7 +3505,7 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, res = mHTMLEditor->DeleteNode(brNode); NS_ENSURE_SUCCESS(res, res); // we don't need to act on this node any more - arrayOfNodes.RemoveObject(brNode); + arrayOfNodes.RemoveElement(brNode); } // make sure we can put a block here res = SplitAsNeeded(blockType, parent, offset); @@ -3523,13 +3517,12 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, // remember our new block for postprocessing mNewBlock = theBlock; // delete anything that was in the list of nodes - for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) - { - nsCOMPtr curNode = arrayOfNodes[0]; + while (!arrayOfNodes.IsEmpty()) { + nsCOMPtr curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveObjectAt(0); + arrayOfNodes.RemoveElementAt(0); } // put selection in new block res = aSelection->Collapse(theBlock,0); @@ -3543,13 +3536,17 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, // Ok, now go through all the nodes and make the right kind of blocks, // or whatever is approriate. Wohoo! // Note: blockquote is handled a little differently + nsCOMArray arrayOfDOMNodes; + for (auto& node : arrayOfNodes) { + arrayOfDOMNodes.AppendObject(GetAsDOMNode(node)); + } if (tString.EqualsLiteral("blockquote")) - res = MakeBlockquote(arrayOfNodes); + res = MakeBlockquote(arrayOfDOMNodes); else if (tString.EqualsLiteral("normal") || tString.IsEmpty() ) - res = RemoveBlockStyle(arrayOfNodes); + res = RemoveBlockStyle(arrayOfDOMNodes); else - res = ApplyBlockStyle(arrayOfNodes, aBlockType); + res = ApplyBlockStyle(arrayOfDOMNodes, aBlockType); return res; } return res; @@ -3607,7 +3604,7 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); nsTArray> arrayOfRanges; - nsTArray> array; + nsTArray> arrayOfNodes; // short circuit: detect case of collapsed selection inside an
  • . // just sublist that
  • . This prevents bug 97797. @@ -3632,7 +3629,7 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, if (liNode) { - array.AppendElement(liNode); + arrayOfNodes.AppendElement(liNode); } else { @@ -3640,15 +3637,10 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, // this basically just expands the range to include the immediate // block parent, and then further expands to include any ancestors // whose children are all in the range - res = GetNodesFromSelection(*aSelection, EditAction::indent, array); + res = GetNodesFromSelection(*aSelection, EditAction::indent, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); } - nsCOMArray arrayOfNodes; - for (auto& node : array) { - arrayOfNodes.AppendObject(GetAsDOMNode(node)); - } - // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { @@ -3669,13 +3661,12 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, mNewBlock = theBlock->AsDOMNode(); RelativeChangeIndentationOfElementNode(theBlock->AsDOMNode(), +1); // delete anything that was in the list of nodes - for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) - { - nsCOMPtr curNode = arrayOfNodes[0]; + while (!arrayOfNodes.IsEmpty()) { + nsCOMPtr curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveObjectAt(0); + arrayOfNodes.RemoveElementAt(0); } // put selection in new block res = aSelection->Collapse(theBlock,0); @@ -3690,12 +3681,12 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, nsCOMPtr curParent; nsCOMPtr curList, curQuote; nsCOMPtr sibling; - int32_t listCount = arrayOfNodes.Count(); + int32_t listCount = arrayOfNodes.Length(); for (i=0; i curNode = do_QueryInterface(arrayOfNodes[i]); - NS_ENSURE_STATE(!arrayOfNodes[i] || curNode); + NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); + nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); // Ignore all non-editable nodes. Leave them be. NS_ENSURE_STATE(mHTMLEditor); @@ -3832,15 +3823,10 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::indent); // use these ranges to contruct a list of nodes to act on. - nsTArray> array; - res = GetNodesForOperation(arrayOfRanges, array, EditAction::indent); + nsTArray> arrayOfNodes; + res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::indent); NS_ENSURE_SUCCESS(res, res); - nsCOMArray arrayOfNodes; - for (auto& node : array) { - arrayOfNodes.AppendObject(GetAsDOMNode(node)); - } - // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { @@ -3860,13 +3846,12 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, // remember our new block for postprocessing mNewBlock = theBlock->AsDOMNode(); // delete anything that was in the list of nodes - for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) - { - nsCOMPtr curNode = arrayOfNodes[0]; + while (!arrayOfNodes.IsEmpty()) { + nsCOMPtr curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveObjectAt(0); + arrayOfNodes.RemoveElementAt(0); } // put selection in new block res = aSelection->Collapse(theBlock,0); @@ -3881,12 +3866,12 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, nsCOMPtr curParent; nsCOMPtr sibling; nsCOMPtr curList, curQuote, indentedLI; - int32_t listCount = arrayOfNodes.Count(); + int32_t listCount = arrayOfNodes.Length(); for (i=0; i curNode = do_QueryInterface(arrayOfNodes[i]); - NS_ENSURE_STATE(!arrayOfNodes[i] || curNode); + NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); + nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); // Ignore all non-editable nodes. Leave them be. NS_ENSURE_STATE(mHTMLEditor); @@ -8088,33 +8073,33 @@ nsHTMLEditRules::IsEmptyInline(nsIDOMNode *aNode) } -bool -nsHTMLEditRules::ListIsEmptyLine(nsCOMArray &arrayOfNodes) +bool +nsHTMLEditRules::ListIsEmptyLine(nsTArray>& aArrayOfNodes) { - // we have a list of nodes which we are candidates for being moved - // into a new block. Determine if it's anything more than a blank line. - // Look for editable content above and beyond one single BR. - int32_t listCount = arrayOfNodes.Count(); - NS_ENSURE_TRUE(listCount, true); - nsCOMPtr somenode; - int32_t j, brCount=0; - for (j = 0; j < listCount; j++) - { - somenode = arrayOfNodes[j]; - NS_ENSURE_TRUE(mHTMLEditor, false); - if (somenode && mHTMLEditor->IsEditable(somenode)) - { - if (nsTextEditUtils::IsBreak(somenode)) - { - // first break doesn't count - if (brCount) return false; - brCount++; + // We have a list of nodes which we are candidates for being moved into a new + // block. Determine if it's anything more than a blank line. Look for + // editable content above and beyond one single BR. + NS_ENSURE_TRUE(aArrayOfNodes.Length(), true); + + NS_ENSURE_TRUE(mHTMLEditor, false); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); + + int32_t brCount = 0; + + for (auto& node : aArrayOfNodes) { + if (!node || !mHTMLEditor->IsEditable(node)) { + continue; + } + if (nsTextEditUtils::IsBreak(node)) { + // First break doesn't count + if (brCount) { + return false; } - else if (IsEmptyInline(somenode)) - { - // empty inline, keep looking - } - else return false; + brCount++; + } else if (IsEmptyInline(GetAsDOMNode(node))) { + // Empty inline, keep looking + } else { + return false; } } return true; @@ -8921,15 +8906,11 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection, EditAction::setAbsolutePosition); // use these ranges to contruct a list of nodes to act on. - nsTArray> array; - res = GetNodesForOperation(arrayOfRanges, array, + nsTArray> arrayOfNodes; + res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::setAbsolutePosition); NS_ENSURE_SUCCESS(res, res); - nsCOMArray arrayOfNodes; - for (auto& node : array) { - arrayOfNodes.AppendObject(GetAsDOMNode(node)); - } // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { @@ -8949,13 +8930,12 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection, // remember our new block for postprocessing mNewBlock = thePositionedDiv->AsDOMNode(); // delete anything that was in the list of nodes - for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) - { - nsCOMPtr curNode = arrayOfNodes[0]; + while (!arrayOfNodes.IsEmpty()) { + nsCOMPtr curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveObjectAt(0); + arrayOfNodes.RemoveElementAt(0); } // put selection in new block res = aSelection->Collapse(thePositionedDiv,0); @@ -8966,16 +8946,13 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection, // Ok, now go through all the nodes and put them in a blockquote, // or whatever is appropriate. Wohoo! - int32_t i; nsCOMPtr curParent; nsCOMPtr indentedLI, sibling; nsCOMPtr curList, curPositionedDiv; - int32_t listCount = arrayOfNodes.Count(); - for (i=0; i curNode = do_QueryInterface(arrayOfNodes[i]); - NS_ENSURE_STATE(curNode); + NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); + nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); // Ignore all non-editable nodes. Leave them be. NS_ENSURE_STATE(mHTMLEditor); diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index b1c13945b15d..967b58a0c9ee 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -338,7 +338,7 @@ protected: nsresult ConfirmSelectionInBody(); nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode); bool IsEmptyInline(nsIDOMNode *aNode); - bool ListIsEmptyLine(nsCOMArray &arrayOfNodes); + bool ListIsEmptyLine(nsTArray>& arrayOfNodes); nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly); nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts); nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly); From 098aeb275f57991d5d5e9db14162810ea65eef22 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:58 +0300 Subject: [PATCH 128/241] Bug 1153629 part 5 - Clean up nsHTMLEditRules::GetChildNodesForOperation; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 64 +++++++++++++--------------- editor/libeditor/nsHTMLEditRules.h | 4 +- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index df628dcfe801..87c59d6132d8 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -5899,30 +5899,17 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange } - -/////////////////////////////////////////////////////////////////////////// -// GetChildNodesForOperation: -// -nsresult -nsHTMLEditRules::GetChildNodesForOperation(nsIDOMNode *inNode, - nsCOMArray& outArrayOfNodes) +void +nsHTMLEditRules::GetChildNodesForOperation(nsINode& aNode, + nsTArray>& outArrayOfNodes) { - nsCOMPtr node = do_QueryInterface(inNode); - NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); - - for (nsIContent* child = node->GetFirstChild(); - child; - child = child->GetNextSibling()) { - nsIDOMNode* childNode = child->AsDOMNode(); - if (!outArrayOfNodes.AppendObject(childNode)) { - return NS_ERROR_FAILURE; - } + for (nsCOMPtr child = aNode.GetFirstChild(); + child; child = child->GetNextSibling()) { + outArrayOfNodes.AppendElement(child); } - return NS_OK; } - nsresult nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNodes, EntireList aEntireList, @@ -6852,10 +6839,15 @@ nsHTMLEditRules::MakeBlockquote(nsCOMArray& arrayOfNodes) { curBlock = 0; // forget any previous block // recursion time - nsCOMArray childArray; - res = GetChildNodesForOperation(curNode, childArray); - NS_ENSURE_SUCCESS(res, res); - res = MakeBlockquote(childArray); + nsTArray> childArray; + nsCOMPtr node = do_QueryInterface(curNode); + NS_ENSURE_STATE(node || !curNode); + GetChildNodesForOperation(*node, childArray); + nsCOMArray childArrayDOM; + for (auto& child : childArray) { + childArrayDOM.AppendObject(GetAsDOMNode(child)); + } + res = MakeBlockquote(childArrayDOM); NS_ENSURE_SUCCESS(res, res); } @@ -6950,10 +6942,13 @@ nsHTMLEditRules::RemoveBlockStyle(nsCOMArray& arrayOfNodes) curBlock = 0; firstNode = 0; lastNode = 0; } // recursion time - nsCOMArray childArray; - res = GetChildNodesForOperation(curNode, childArray); - NS_ENSURE_SUCCESS(res, res); - res = RemoveBlockStyle(childArray); + nsTArray> childArray; + GetChildNodesForOperation(*curElement, childArray); + nsCOMArray childArrayDOM; + for (auto& child : childArray) { + childArrayDOM.AppendObject(GetAsDOMNode(child)); + } + res = RemoveBlockStyle(childArrayDOM); NS_ENSURE_SUCCESS(res, res); } else if (IsInlineNode(curNode)) @@ -7087,13 +7082,14 @@ nsHTMLEditRules::ApplyBlockStyle(nsCOMArray& arrayOfNodes, const nsA nsGkAtoms::div)) { curBlock = 0; // forget any previous block used for previous inline nodes // recursion time - nsCOMArray childArray; - res = GetChildNodesForOperation(GetAsDOMNode(curNode), childArray); - NS_ENSURE_SUCCESS(res, res); - int32_t childCount = childArray.Count(); - if (childCount) - { - res = ApplyBlockStyle(childArray, aBlockTag); + nsTArray> childArray; + GetChildNodesForOperation(*curNode, childArray); + if (childArray.Length()) { + nsCOMArray childArrayDOM; + for (auto& child : childArray) { + childArrayDOM.AppendObject(GetAsDOMNode(child)); + } + res = ApplyBlockStyle(childArrayDOM, aBlockTag); NS_ENSURE_SUCCESS(res, res); } else diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 967b58a0c9ee..9da3f9a1559f 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -275,8 +275,8 @@ protected: nsTArray>& aOutArrayOfNodes, EditAction aOperationType, TouchContent aTouchContent = TouchContent::yes); - nsresult GetChildNodesForOperation(nsIDOMNode *inNode, - nsCOMArray& outArrayOfNodes); + void GetChildNodesForOperation(nsINode& aNode, + nsTArray>& outArrayOfNodes); nsresult GetNodesFromPoint(::DOMPoint aPoint, EditAction aOperation, nsTArray>& outArrayOfNodes, From 3e919338b5da20ac07724ae42d52c6bbdd0b6592 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:58 +0300 Subject: [PATCH 129/241] Bug 1153629 part 6 - Clean up nsHTMLEditRules::MakeBlockquote; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 109 +++++++++++---------------- editor/libeditor/nsHTMLEditRules.h | 2 +- 2 files changed, 43 insertions(+), 68 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 87c59d6132d8..4af92c3b8fd0 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -3541,7 +3541,7 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, arrayOfDOMNodes.AppendObject(GetAsDOMNode(node)); } if (tString.EqualsLiteral("blockquote")) - res = MakeBlockquote(arrayOfDOMNodes); + res = MakeBlockquote(arrayOfNodes); else if (tString.EqualsLiteral("normal") || tString.IsEmpty() ) res = RemoveBlockStyle(arrayOfDOMNodes); @@ -6802,76 +6802,52 @@ nsHTMLEditRules::ReturnInListItem(Selection* aSelection, } -/////////////////////////////////////////////////////////////////////////// -// MakeBlockquote: put the list of nodes into one or more blockquotes. -// -nsresult -nsHTMLEditRules::MakeBlockquote(nsCOMArray& arrayOfNodes) +/////////////////////////////////////////////////////////////////////////////// +// MakeBlockquote: Put the list of nodes into one or more blockquotes. +// +nsresult +nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) { - // the idea here is to put the nodes into a minimal number of - // blockquotes. When the user blockquotes something, they expect - // one blockquote. That may not be possible (for instance, if they - // have two table cells selected, you need two blockquotes inside the cells). - - nsresult res = NS_OK; - - nsCOMPtr curNode, newBlock; - nsCOMPtr curParent; + // The idea here is to put the nodes into a minimal number of blockquotes. + // When the user blockquotes something, they expect one blockquote. That may + // not be possible (for instance, if they have two table cells selected, you + // need two blockquotes inside the cells). + nsresult res; nsCOMPtr curBlock; - int32_t offset; - int32_t listCount = arrayOfNodes.Count(); - - nsCOMPtr prevParent; - - int32_t i; - for (i=0; i curContent = do_QueryInterface(curNode); - NS_ENSURE_STATE(curContent); - curParent = curContent->GetParentNode(); - offset = curParent ? curParent->IndexOf(curContent) : -1; + nsCOMPtr prevParent; - // if the node is a table element or list item, dive inside - if (nsHTMLEditUtils::IsTableElementButNotTable(curNode) || - nsHTMLEditUtils::IsListItem(curNode)) - { - curBlock = 0; // forget any previous block - // recursion time + for (auto& curNode : aNodeArray) { + // Get the node to act on, and its location + NS_ENSURE_STATE(curNode->IsContent()); + + // If the node is a table element or list item, dive inside + if (nsHTMLEditUtils::IsTableElementButNotTable(curNode) || + nsHTMLEditUtils::IsListItem(curNode)) { + // Forget any previous block + curBlock = nullptr; + // Recursion time nsTArray> childArray; - nsCOMPtr node = do_QueryInterface(curNode); - NS_ENSURE_STATE(node || !curNode); - GetChildNodesForOperation(*node, childArray); - nsCOMArray childArrayDOM; - for (auto& child : childArray) { - childArrayDOM.AppendObject(GetAsDOMNode(child)); - } - res = MakeBlockquote(childArrayDOM); + GetChildNodesForOperation(*curNode, childArray); + res = MakeBlockquote(childArray); NS_ENSURE_SUCCESS(res, res); } - - // if the node has different parent than previous node, - // further nodes in a new parent - if (prevParent) - { - nsCOMPtr temp; - curNode->GetParentNode(getter_AddRefs(temp)); - if (temp != prevParent) - { - curBlock = 0; // forget any previous blockquote node we were using - prevParent = temp; - } - } - else - { - curNode->GetParentNode(getter_AddRefs(prevParent)); + // If the node has different parent than previous node, further nodes in a + // new parent + if (prevParent) { + if (prevParent != curNode->GetParentNode()) { + // Forget any previous blockquote node we were using + curBlock = nullptr; + prevParent = curNode->GetParentNode(); + } + } else { + prevParent = curNode->GetParentNode(); } - - // if no curBlock, make one - if (!curBlock) - { + + // If no curBlock, make one + if (!curBlock) { + nsCOMPtr curParent = curNode->GetParentNode(); + int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; res = SplitAsNeeded(*nsGkAtoms::blockquote, curParent, offset); NS_ENSURE_SUCCESS(res, res); NS_ENSURE_STATE(mHTMLEditor); @@ -6882,16 +6858,15 @@ nsHTMLEditRules::MakeBlockquote(nsCOMArray& arrayOfNodes) mNewBlock = curBlock->AsDOMNode(); // note: doesn't matter if we set mNewBlock multiple times. } - + NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->MoveNode(curContent, curBlock, -1); + res = mHTMLEditor->MoveNode(curNode->AsContent(), curBlock, -1); NS_ENSURE_SUCCESS(res, res); } - return res; + return NS_OK; } - /////////////////////////////////////////////////////////////////////////// // RemoveBlockStyle: make the nodes have no special block type. // diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 9da3f9a1559f..fbc48c3a1320 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -302,7 +302,7 @@ protected: nsTArray &inTransitionArray); nsresult RemoveBlockStyle(nsCOMArray& arrayOfNodes); nsresult ApplyBlockStyle(nsCOMArray& arrayOfNodes, const nsAString *aBlockTag); - nsresult MakeBlockquote(nsCOMArray& arrayOfNodes); + nsresult MakeBlockquote(nsTArray>& aNodeArray); nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr& inOutParent, int32_t& inOutOffset); nsresult AddTerminatingBR(nsIDOMNode *aBlock); From 3b37a005e23cf0689a3c0f26df39c277685ba44a Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:58 +0300 Subject: [PATCH 130/241] Bug 1153629 part 7 - Clean up nsHTMLEditRules::RemoveBlockStyle, RemovePartOfBlock; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 200 ++++++++++++--------------- editor/libeditor/nsHTMLEditRules.h | 10 +- 2 files changed, 89 insertions(+), 121 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 4af92c3b8fd0..435e3c525f31 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -3536,17 +3536,17 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, // Ok, now go through all the nodes and make the right kind of blocks, // or whatever is approriate. Wohoo! // Note: blockquote is handled a little differently - nsCOMArray arrayOfDOMNodes; - for (auto& node : arrayOfNodes) { - arrayOfDOMNodes.AppendObject(GetAsDOMNode(node)); - } - if (tString.EqualsLiteral("blockquote")) + if (tString.EqualsLiteral("blockquote")) { res = MakeBlockquote(arrayOfNodes); - else if (tString.EqualsLiteral("normal") || - tString.IsEmpty() ) - res = RemoveBlockStyle(arrayOfDOMNodes); - else + } else if (tString.EqualsLiteral("normal") || tString.IsEmpty()) { + res = RemoveBlockStyle(arrayOfNodes); + } else { + nsCOMArray arrayOfDOMNodes; + for (auto& node : arrayOfNodes) { + arrayOfDOMNodes.AppendObject(GetAsDOMNode(node)); + } res = ApplyBlockStyle(arrayOfDOMNodes, aBlockType); + } return res; } return res; @@ -4308,28 +4308,21 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, } -/////////////////////////////////////////////////////////////////////////// -// RemovePartOfBlock: split aBlock and move aStartChild to aEndChild out -// of aBlock. return left side of block (if any) in -// aLeftNode. return right side of block (if any) in -// aRightNode. -// -nsresult -nsHTMLEditRules::RemovePartOfBlock(nsIDOMNode *aBlock, - nsIDOMNode *aStartChild, - nsIDOMNode *aEndChild, - nsCOMPtr *aLeftNode, - nsCOMPtr *aRightNode) +/////////////////////////////////////////////////////////////////////////////// +// RemovePartOfBlock: Split aBlock and move aStartChild to aEndChild out of +// aBlock. +nsresult +nsHTMLEditRules::RemovePartOfBlock(Element& aBlock, + nsIContent& aStartChild, + nsIContent& aEndChild) { - nsCOMPtr middleNode; - nsresult res = SplitBlock(aBlock, aStartChild, aEndChild, - aLeftNode, aRightNode, - address_of(middleNode)); + nsresult res = SplitBlock(aBlock.AsDOMNode(), aStartChild.AsDOMNode(), + aEndChild.AsDOMNode()); NS_ENSURE_SUCCESS(res, res); - // get rid of part of blockquote we are outdenting + // Get rid of part of blockquote we are outdenting NS_ENSURE_STATE(mHTMLEditor); - return mHTMLEditor->RemoveBlockContainer(aBlock); + return mHTMLEditor->RemoveBlockContainer(aBlock.AsDOMNode()); } nsresult @@ -6867,114 +6860,91 @@ nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) } -/////////////////////////////////////////////////////////////////////////// -// RemoveBlockStyle: make the nodes have no special block type. -// -nsresult -nsHTMLEditRules::RemoveBlockStyle(nsCOMArray& arrayOfNodes) +/////////////////////////////////////////////////////////////////////////////// +// RemoveBlockStyle: Make the nodes have no special block type. +nsresult +nsHTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray) { - // intent of this routine is to be used for converting to/from - // headers, paragraphs, pre, and address. Those blocks - // that pretty much just contain inline things... - - nsresult res = NS_OK; - - nsCOMPtr curBlock, firstNode, lastNode; - int32_t listCount = arrayOfNodes.Count(); - for (int32_t i = 0; i < listCount; ++i) { - // get the node to act on, and its location - nsCOMPtr curNode = arrayOfNodes[i]; + NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); - nsCOMPtr curElement = do_QueryInterface(curNode); + // Intent of this routine is to be used for converting to/from headers, + // paragraphs, pre, and address. Those blocks that pretty much just contain + // inline things... + nsresult res; - // if curNode is a address, p, header, address, or pre, remove it - if (curElement && nsHTMLEditUtils::IsFormatNode(curElement)) { - // process any partial progress saved - if (curBlock) - { - res = RemovePartOfBlock(curBlock, firstNode, lastNode); + nsCOMPtr curBlock; + nsCOMPtr firstNode, lastNode; + for (auto& curNode : aNodeArray) { + // If curNode is a address, p, header, address, or pre, remove it + if (nsHTMLEditUtils::IsFormatNode(curNode)) { + // Process any partial progress saved + if (curBlock) { + res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); NS_ENSURE_SUCCESS(res, res); - curBlock = 0; firstNode = 0; lastNode = 0; + firstNode = lastNode = curBlock = nullptr; } - // remove curent block - NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->RemoveBlockContainer(curNode); + // Remove current block + res = mHTMLEditor->RemoveBlockContainer(curNode->AsDOMNode()); NS_ENSURE_SUCCESS(res, res); - } else if (curElement && - (curElement->IsAnyOfHTMLElements(nsGkAtoms::table, - nsGkAtoms::tr, - nsGkAtoms::tbody, - nsGkAtoms::td, - nsGkAtoms::li, - nsGkAtoms::blockquote, - nsGkAtoms::div) || - nsHTMLEditUtils::IsList(curElement))) { - // process any partial progress saved - if (curBlock) - { - res = RemovePartOfBlock(curBlock, firstNode, lastNode); + } else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table, + nsGkAtoms::tr, + nsGkAtoms::tbody, + nsGkAtoms::td, + nsGkAtoms::li, + nsGkAtoms::blockquote, + nsGkAtoms::div) || + nsHTMLEditUtils::IsList(curNode)) { + // Process any partial progress saved + if (curBlock) { + res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); NS_ENSURE_SUCCESS(res, res); - curBlock = 0; firstNode = 0; lastNode = 0; + firstNode = lastNode = curBlock = nullptr; } - // recursion time + // Recursion time nsTArray> childArray; - GetChildNodesForOperation(*curElement, childArray); - nsCOMArray childArrayDOM; - for (auto& child : childArray) { - childArrayDOM.AppendObject(GetAsDOMNode(child)); - } - res = RemoveBlockStyle(childArrayDOM); + GetChildNodesForOperation(*curNode, childArray); + res = RemoveBlockStyle(childArray); NS_ENSURE_SUCCESS(res, res); - } - else if (IsInlineNode(curNode)) - { - if (curBlock) - { - // if so, is this node a descendant? - if (nsEditorUtils::IsDescendantOf(curNode, curBlock)) - { - lastNode = curNode; - continue; // then we don't need to do anything different for this node - } - else - { - // otherwise, we have progressed beyond end of curBlock, - // so lets handle it now. We need to remove the portion of - // curBlock that contains [firstNode - lastNode]. - res = RemovePartOfBlock(curBlock, firstNode, lastNode); + } else if (IsInlineNode(GetAsDOMNode(curNode))) { + if (curBlock) { + // If so, is this node a descendant? + if (nsEditorUtils::IsDescendantOf(curNode, curBlock)) { + // Then we don't need to do anything different for this node + lastNode = curNode->AsContent(); + continue; + } else { + // Otherwise, we have progressed beyond end of curBlock, so let's + // handle it now. We need to remove the portion of curBlock that + // contains [firstNode - lastNode]. + res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); NS_ENSURE_SUCCESS(res, res); - curBlock = 0; firstNode = 0; lastNode = 0; - // fall out and handle curNode + firstNode = lastNode = curBlock = nullptr; + // Fall out and handle curNode } } - NS_ENSURE_STATE(mHTMLEditor); curBlock = mHTMLEditor->GetBlockNodeParent(curNode); if (curBlock && nsHTMLEditUtils::IsFormatNode(curBlock)) { - firstNode = curNode; - lastNode = curNode; - } - else - curBlock = 0; // not a block kind that we care about. - } - else - { // some node that is already sans block style. skip over it and - // process any partial progress saved - if (curBlock) - { - res = RemovePartOfBlock(curBlock, firstNode, lastNode); - NS_ENSURE_SUCCESS(res, res); - curBlock = 0; firstNode = 0; lastNode = 0; + firstNode = lastNode = curNode->AsContent(); + } else { + // Not a block kind that we care about. + curBlock = nullptr; } + } else if (curBlock) { + // Some node that is already sans block style. Skip over it and process + // any partial progress saved. + res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); + NS_ENSURE_SUCCESS(res, res); + firstNode = lastNode = curBlock = nullptr; } } - // process any partial progress saved - if (curBlock) - { - res = RemovePartOfBlock(curBlock, firstNode, lastNode); + // Process any partial progress saved + if (curBlock) { + res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); NS_ENSURE_SUCCESS(res, res); - curBlock = 0; firstNode = 0; lastNode = 0; + firstNode = lastNode = curBlock = nullptr; } - return res; + return NS_OK; } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index fbc48c3a1320..1f94648d70de 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -220,11 +220,9 @@ protected: int32_t aOffset); nsresult AfterEditInner(EditAction action, nsIEditor::EDirection aDirection); - nsresult RemovePartOfBlock(nsIDOMNode *aBlock, - nsIDOMNode *aStartChild, - nsIDOMNode *aEndChild, - nsCOMPtr *aLeftNode = 0, - nsCOMPtr *aRightNode = 0); + nsresult RemovePartOfBlock(mozilla::dom::Element& aBlock, + nsIContent& aStartChild, + nsIContent& aEndChild); nsresult SplitBlock(nsIDOMNode *aBlock, nsIDOMNode *aStartChild, nsIDOMNode *aEndChild, @@ -300,7 +298,7 @@ protected: nsCOMPtr GetHighestInlineParent(nsIDOMNode* aNode); nsresult MakeTransitionList(nsCOMArray& inArrayOfNodes, nsTArray &inTransitionArray); - nsresult RemoveBlockStyle(nsCOMArray& arrayOfNodes); + nsresult RemoveBlockStyle(nsTArray>& aNodeArray); nsresult ApplyBlockStyle(nsCOMArray& arrayOfNodes, const nsAString *aBlockTag); nsresult MakeBlockquote(nsTArray>& aNodeArray); nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr& inOutParent, From c899a3d7e4a36b25e8f900fec9ea73fff3adf674 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:58 +0300 Subject: [PATCH 131/241] Bug 1153629 part 8 - Clean up nsHTMLEditRules::ApplyBlockStyle; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 243 +++++++++++---------------- editor/libeditor/nsHTMLEditRules.h | 3 +- 2 files changed, 101 insertions(+), 145 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 435e3c525f31..19d43aa6c6e6 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -3541,11 +3541,7 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, } else if (tString.EqualsLiteral("normal") || tString.IsEmpty()) { res = RemoveBlockStyle(arrayOfNodes); } else { - nsCOMArray arrayOfDOMNodes; - for (auto& node : arrayOfNodes) { - arrayOfDOMNodes.AppendObject(GetAsDOMNode(node)); - } - res = ApplyBlockStyle(arrayOfDOMNodes, aBlockType); + res = ApplyBlockStyle(arrayOfNodes, *blockType); } return res; } @@ -6948,175 +6944,134 @@ nsHTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray) } -/////////////////////////////////////////////////////////////////////////// -// ApplyBlockStyle: do whatever it takes to make the list of nodes into -// one or more blocks of type blockTag. -// -nsresult -nsHTMLEditRules::ApplyBlockStyle(nsCOMArray& arrayOfNodes, const nsAString *aBlockTag) +/////////////////////////////////////////////////////////////////////////////// +// ApplyBlockStyle: Do whatever it takes to make the list of nodes into one or +// more blocks of type aBlockTag. +nsresult +nsHTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, + nsIAtom& aBlockTag) { - // intent of this routine is to be used for converting to/from - // headers, paragraphs, pre, and address. Those blocks - // that pretty much just contain inline things... - - NS_ENSURE_TRUE(aBlockTag, NS_ERROR_NULL_POINTER); - nsCOMPtr blockTag = do_GetAtom(*aBlockTag); - nsresult res = NS_OK; - - nsCOMPtr curParent; - nsCOMPtr newBlock; - int32_t offset; - int32_t listCount = arrayOfNodes.Count(); - nsString tString(*aBlockTag);////MJUDGE SCC NEED HELP + // Intent of this routine is to be used for converting to/from headers, + // paragraphs, pre, and address. Those blocks that pretty much just contain + // inline things... + NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); + + nsresult res; // Remove all non-editable nodes. Leave them be. - int32_t j; - for (j=listCount-1; j>=0; j--) - { - NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsEditable(arrayOfNodes[j])) - { - arrayOfNodes.RemoveObjectAt(j); + for (int32_t i = aNodeArray.Length() - 1; i >= 0; i--) { + if (!mHTMLEditor->IsEditable(aNodeArray[i])) { + aNodeArray.RemoveElementAt(i); } } - - // reset list count - listCount = arrayOfNodes.Count(); - + + nsCOMPtr newBlock; + nsCOMPtr curBlock; - int32_t i; - for (i=0; i curNode = do_QueryInterface(arrayOfNodes[i]); - NS_ENSURE_STATE(curNode); - curParent = curNode->GetParentNode(); - offset = curParent ? curParent->IndexOf(curNode) : -1; - nsAutoString curNodeTag; - curNode->NodeInfo()->NameAtom()->ToString(curNodeTag); - ToLowerCase(curNodeTag); - - // is it already the right kind of block? - if (curNodeTag == *aBlockTag) - { - curBlock = 0; // forget any previous block used for previous inline nodes - continue; // do nothing to this block + for (auto& curNode : aNodeArray) { + nsCOMPtr curParent = curNode->GetParentNode(); + int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; + + // Is it already the right kind of block? + if (curNode->IsHTMLElement(&aBlockTag)) { + // Forget any previous block used for previous inline nodes + curBlock = nullptr; + // Do nothing to this block + continue; } - - // if curNode is a address, p, header, address, or pre, replace - // it with a new block of correct type. - // xxx floppy moose: pre can't hold everything the others can - if (nsHTMLEditUtils::IsMozDiv(curNode) || - nsHTMLEditUtils::IsFormatNode(curNode)) - { - curBlock = 0; // forget any previous block used for previous inline nodes - NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr element = curNode->AsElement(); - newBlock = dont_AddRef(GetAsDOMNode( - mHTMLEditor->ReplaceContainer(element, blockTag, nullptr, nullptr, - nsEditor::eCloneAttributes).take())); + + // If curNode is a address, p, header, address, or pre, replace it with a + // new block of correct type. + // XXX: pre can't hold everything the others can + if (nsHTMLEditUtils::IsMozDiv(curNode) || + nsHTMLEditUtils::IsFormatNode(curNode)) { + // Forget any previous block used for previous inline nodes + curBlock = nullptr; + newBlock = mHTMLEditor->ReplaceContainer(curNode->AsElement(), + &aBlockTag, nullptr, nullptr, + nsEditor::eCloneAttributes); NS_ENSURE_STATE(newBlock); - } - else if (nsHTMLEditUtils::IsTable(curNode) || - (curNodeTag.EqualsLiteral("tbody")) || - (curNodeTag.EqualsLiteral("tr")) || - (curNodeTag.EqualsLiteral("td")) || - nsHTMLEditUtils::IsList(curNode) || - (curNodeTag.EqualsLiteral("li")) || - curNode->IsAnyOfHTMLElements(nsGkAtoms::blockquote, - nsGkAtoms::div)) { - curBlock = 0; // forget any previous block used for previous inline nodes - // recursion time + } else if (nsHTMLEditUtils::IsTable(curNode) || + nsHTMLEditUtils::IsList(curNode) || + curNode->IsAnyOfHTMLElements(nsGkAtoms::tbody, + nsGkAtoms::tr, + nsGkAtoms::td, + nsGkAtoms::li, + nsGkAtoms::blockquote, + nsGkAtoms::div)) { + // Forget any previous block used for previous inline nodes + curBlock = nullptr; + // Recursion time nsTArray> childArray; GetChildNodesForOperation(*curNode, childArray); if (childArray.Length()) { - nsCOMArray childArrayDOM; - for (auto& child : childArray) { - childArrayDOM.AppendObject(GetAsDOMNode(child)); - } - res = ApplyBlockStyle(childArrayDOM, aBlockTag); + res = ApplyBlockStyle(childArray, aBlockTag); NS_ENSURE_SUCCESS(res, res); - } - else - { - // make sure we can put a block here - res = SplitAsNeeded(*blockTag, curParent, offset); + } else { + // Make sure we can put a block here + res = SplitAsNeeded(aBlockTag, curParent, offset); NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_STATE(mHTMLEditor); nsCOMPtr theBlock = - mHTMLEditor->CreateNode(blockTag, curParent, offset); + mHTMLEditor->CreateNode(&aBlockTag, curParent, offset); NS_ENSURE_STATE(theBlock); - // remember our new block for postprocessing + // Remember our new block for postprocessing mNewBlock = theBlock->AsDOMNode(); } - } - - // if the node is a break, we honor it by putting further nodes in a new parent - else if (curNodeTag.EqualsLiteral("br")) - { - if (curBlock) - { - curBlock = 0; // forget any previous block used for previous inline nodes - NS_ENSURE_STATE(mHTMLEditor); + } else if (curNode->IsHTMLElement(nsGkAtoms::br)) { + // If the node is a break, we honor it by putting further nodes in a new + // parent + if (curBlock) { + // Forget any previous block used for previous inline nodes + curBlock = nullptr; res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - } - else - { - // the break is the first (or even only) node we encountered. Create a + } else { + // The break is the first (or even only) node we encountered. Create a // block for it. - res = SplitAsNeeded(*blockTag, curParent, offset); + res = SplitAsNeeded(aBlockTag, curParent, offset); NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_STATE(mHTMLEditor); - curBlock = mHTMLEditor->CreateNode(blockTag, curParent, offset); + curBlock = mHTMLEditor->CreateNode(&aBlockTag, curParent, offset); NS_ENSURE_STATE(curBlock); - // remember our new block for postprocessing + // Remember our new block for postprocessing mNewBlock = curBlock->AsDOMNode(); - // note: doesn't matter if we set mNewBlock multiple times. - NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->MoveNode(curNode, curBlock, -1); + // Note: doesn't matter if we set mNewBlock multiple times. + res = mHTMLEditor->MoveNode(curNode->AsContent(), curBlock, -1); NS_ENSURE_SUCCESS(res, res); } - - - // if curNode is inline, pull it into curBlock - // note: it's assumed that consecutive inline nodes in the - // arrayOfNodes are actually members of the same block parent. - // this happens to be true now as a side effect of how - // arrayOfNodes is contructed, but some additional logic should - // be added here if that should change - } else if (IsInlineNode(GetAsDOMNode(curNode))) { - // if curNode is a non editable, drop it if we are going to
    -      NS_ENSURE_STATE(mHTMLEditor);
    -      if (tString.LowerCaseEqualsLiteral("pre") 
    -        && (!mHTMLEditor->IsEditable(curNode)))
    -        continue; // do nothing to this block
    -      
    -      // if no curBlock, make one
    -      if (!curBlock)
    -      {
    -        res = SplitAsNeeded(*blockTag, curParent, offset);
    -        NS_ENSURE_SUCCESS(res, res);
    -        NS_ENSURE_STATE(mHTMLEditor);
    -        curBlock = mHTMLEditor->CreateNode(blockTag, curParent, offset);
    -        NS_ENSURE_STATE(curBlock);
    -        // remember our new block for postprocessing
    -        mNewBlock = curBlock->AsDOMNode();
    -        // note: doesn't matter if we set mNewBlock multiple times.
    +      // If curNode is inline, pull it into curBlock.  Note: it's assumed that
    +      // consecutive inline nodes in aNodeArray are actually members of the
    +      // same block parent.  This happens to be true now as a side effect of
    +      // how aNodeArray is contructed, but some additional logic should be
    +      // added here if that should change
    +      //
    +      // If curNode is a non editable, drop it if we are going to 
    .
    +      if (&aBlockTag == nsGkAtoms::pre && !mHTMLEditor->IsEditable(curNode)) {
    +        // Do nothing to this block
    +        continue;
           }
    -      
    -      // if curNode is a Break, replace it with a return if we are going to 
    -      // xxx floppy moose
    - 
    -      // this is a continuation of some inline nodes that belong together in
    -      // the same block item.  use curBlock
    -      NS_ENSURE_STATE(mHTMLEditor);
    -      res = mHTMLEditor->MoveNode(curNode, curBlock, -1);
    +
    +      // If no curBlock, make one
    +      if (!curBlock) {
    +        res = SplitAsNeeded(aBlockTag, curParent, offset);
    +        NS_ENSURE_SUCCESS(res, res);
    +        curBlock = mHTMLEditor->CreateNode(&aBlockTag, curParent, offset);
    +        NS_ENSURE_STATE(curBlock);
    +        // Remember our new block for postprocessing
    +        mNewBlock = curBlock->AsDOMNode();
    +        // Note: doesn't matter if we set mNewBlock multiple times.
    +      }
    +
    +      // XXX If curNode is a br, replace it with a return if going to 
    +
    +      // This is a continuation of some inline nodes that belong together in
    +      // the same block item.  Use curBlock.
    +      res = mHTMLEditor->MoveNode(curNode->AsContent(), curBlock, -1);
           NS_ENSURE_SUCCESS(res, res);
         }
       }
    -  return res;
    +  return NS_OK;
     }
     
     
    diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h
    index 1f94648d70de..ee4cbe57c494 100644
    --- a/editor/libeditor/nsHTMLEditRules.h
    +++ b/editor/libeditor/nsHTMLEditRules.h
    @@ -299,7 +299,8 @@ protected:
       nsresult MakeTransitionList(nsCOMArray& inArrayOfNodes, 
                                   nsTArray &inTransitionArray);
       nsresult RemoveBlockStyle(nsTArray>& aNodeArray);
    -  nsresult ApplyBlockStyle(nsCOMArray& arrayOfNodes, const nsAString *aBlockTag);
    +  nsresult ApplyBlockStyle(nsTArray>& aNodeArray,
    +                           nsIAtom& aBlockTag);
       nsresult MakeBlockquote(nsTArray>& aNodeArray);
       nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr& inOutParent,
                              int32_t& inOutOffset);
    
    From 313a21ad79469c74b23a548f560a9ec20e0c9afd Mon Sep 17 00:00:00 2001
    From: Aryeh Gregor 
    Date: Wed, 22 Apr 2015 14:26:58 +0300
    Subject: [PATCH 132/241] Bug 1153629 part 9 - Clean up
     nsHTMLEditRules::MakeTransitionList; r=ehsan
    
    ---
     editor/libeditor/nsHTMLEditRules.cpp | 69 +++++++++++-----------------
     editor/libeditor/nsHTMLEditRules.h   |  4 +-
     2 files changed, 28 insertions(+), 45 deletions(-)
    
    diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp
    index 19d43aa6c6e6..1d365cbccfa5 100644
    --- a/editor/libeditor/nsHTMLEditRules.cpp
    +++ b/editor/libeditor/nsHTMLEditRules.cpp
    @@ -4636,18 +4636,18 @@ nsHTMLEditRules::WillAlign(Selection* aSelection,
       // block parent, and then further expands to include any ancestors
       // whose children are all in the range
       *aHandled = true;
    -  nsTArray> array;
    -  res = GetNodesFromSelection(*aSelection, EditAction::align, array);
    +  nsTArray> nodeArray;
    +  res = GetNodesFromSelection(*aSelection, EditAction::align, nodeArray);
       NS_ENSURE_SUCCESS(res, res);
     
       // if we don't have any nodes, or we have only a single br, then we are
       // creating an empty alignment div.  We have to do some different things for these.
       bool emptyDiv = false;
    -  int32_t listCount = array.Length();
    +  int32_t listCount = nodeArray.Length();
       if (!listCount) emptyDiv = true;
       if (listCount == 1)
       {
    -    nsCOMPtr theNode = array[0];
    +    nsCOMPtr theNode = nodeArray[0];
     
         if (nsHTMLEditUtils::SupportsAlignAttr(GetAsDOMNode(theNode))) {
           // the node is a table element, an horiz rule, a paragraph, a div
    @@ -4670,9 +4670,9 @@ nsHTMLEditRules::WillAlign(Selection* aSelection,
           //
           // XXX: It seems a little error prone for the emptyDiv special
           //      case code to assume that the start node of the selection
    -      //      is the parent of the single node in the arrayOfNodes, as
    +      //      is the parent of the single node in the nodeArray, as
           //      the paragraph above points out. Do we rely on the selection
    -      //      start node because of the fact that arrayOfNodes can be empty?
    +      //      start node because of the fact that nodeArray can be empty?
           //      We should probably revisit this issue. - kin
     
           nsCOMPtr parent;
    @@ -4740,14 +4740,8 @@ nsHTMLEditRules::WillAlign(Selection* aSelection,
       // Next we detect all the transitions in the array, where a transition
       // means that adjacent nodes in the array don't have the same parent.
     
    -  nsCOMArray arrayOfNodes;
    -  for (auto& node : array) {
    -    arrayOfNodes.AppendObject(GetAsDOMNode(node));
    -  }
    -
       nsTArray transitionList;
    -  res = MakeTransitionList(arrayOfNodes, transitionList);
    -  NS_ENSURE_SUCCESS(res, res);                                 
    +  MakeTransitionList(nodeArray, transitionList);
     
       // Ok, now go through all the nodes and give them an align attrib or put them in a div, 
       // or whatever is appropriate.  Wohoo!
    @@ -4757,7 +4751,7 @@ nsHTMLEditRules::WillAlign(Selection* aSelection,
       bool useCSS = mHTMLEditor->IsCSSEnabled();
       for (int32_t i = 0; i < listCount; ++i) {
         // here's where we actually figure out what to do
    -    nsCOMPtr curNode = arrayOfNodes[i];
    +    nsCOMPtr curNode = nodeArray[i]->AsDOMNode();
         nsCOMPtr curContent = do_QueryInterface(curNode);
         NS_ENSURE_STATE(curContent);
     
    @@ -6266,38 +6260,27 @@ nsHTMLEditRules::GetNodesFromSelection(Selection& aSelection,
     }
     
     
    -///////////////////////////////////////////////////////////////////////////
    -// MakeTransitionList: detect all the transitions in the array, where a 
    -//                     transition means that adjacent nodes in the array 
    -//                     don't have the same parent.
    -//                       
    -nsresult 
    -nsHTMLEditRules::MakeTransitionList(nsCOMArray& inArrayOfNodes, 
    -                                    nsTArray &inTransitionArray)
    +///////////////////////////////////////////////////////////////////////////////
    +// MakeTransitionList: Detect all the transitions in the array, where a
    +//                     transition means that adjacent nodes in the array don't
    +//                     have the same parent.
    +void
    +nsHTMLEditRules::MakeTransitionList(nsTArray>& aNodeArray,
    +                                    nsTArray& aTransitionArray)
     {
    -  uint32_t listCount = inArrayOfNodes.Count();
    -  inTransitionArray.EnsureLengthAtLeast(listCount);
    -  uint32_t i;
    -  nsCOMPtr prevElementParent;
    -  nsCOMPtr curElementParent;
    -  
    -  for (i=0; iGetParentNode(getter_AddRefs(curElementParent));
    -    if (curElementParent != prevElementParent)
    -    {
    -      // different parents, or separated by 
    : transition point - inTransitionArray[i] = true; + nsCOMPtr prevParent; + + aTransitionArray.EnsureLengthAtLeast(aNodeArray.Length()); + for (uint32_t i = 0; i < aNodeArray.Length(); i++) { + if (aNodeArray[i]->GetParentNode() != prevParent) { + // Different parents: transition point + aTransitionArray[i] = true; + } else { + // Same parents: these nodes grew up together + aTransitionArray[i] = false; } - else - { - // same parents: these nodes grew up together - inTransitionArray[i] = false; - } - prevElementParent = curElementParent; + prevParent = aNodeArray[i]->GetParentNode(); } - return NS_OK; } diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index ee4cbe57c494..e8f412100ba9 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -296,8 +296,8 @@ protected: nsresult BustUpInlinesAtBRs(nsINode& aNode, nsTArray>& aOutArrayOfNodes); nsCOMPtr GetHighestInlineParent(nsIDOMNode* aNode); - nsresult MakeTransitionList(nsCOMArray& inArrayOfNodes, - nsTArray &inTransitionArray); + void MakeTransitionList(nsTArray>& aNodeArray, + nsTArray& aTransitionArray); nsresult RemoveBlockStyle(nsTArray>& aNodeArray); nsresult ApplyBlockStyle(nsTArray>& aNodeArray, nsIAtom& aBlockTag); From 64e8f10ae73d2ff20479c7cb7053a624b3674f9d Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:58 +0300 Subject: [PATCH 133/241] Bug 1153629 part 10 - Clean up nsHTMLEditRules::AlignInnerBlocks; r=ehsan --- editor/libeditor/nsEditorUtils.cpp | 6 ++-- editor/libeditor/nsEditorUtils.h | 2 +- editor/libeditor/nsHTMLEditRules.cpp | 41 ++++++++++++---------------- editor/libeditor/nsHTMLEditRules.h | 2 +- 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/editor/libeditor/nsEditorUtils.cpp b/editor/libeditor/nsEditorUtils.cpp index b0047a518e46..68939856bd66 100644 --- a/editor/libeditor/nsEditorUtils.cpp +++ b/editor/libeditor/nsEditorUtils.cpp @@ -74,12 +74,10 @@ nsDOMIterator::nsDOMIterator(nsRange& aRange) MOZ_ASSERT(NS_SUCCEEDED(res)); } -nsDOMIterator::nsDOMIterator(nsIDOMNode& aNode) +nsDOMIterator::nsDOMIterator(nsINode& aNode) { mIter = NS_NewContentIterator(); - nsCOMPtr node = do_QueryInterface(&aNode); - NS_ENSURE_TRUE(node, ); - DebugOnly res = mIter->Init(node); + DebugOnly res = mIter->Init(&aNode); MOZ_ASSERT(NS_SUCCEEDED(res)); } diff --git a/editor/libeditor/nsEditorUtils.h b/editor/libeditor/nsEditorUtils.h index c35287c0a1df..340970c3cec1 100644 --- a/editor/libeditor/nsEditorUtils.h +++ b/editor/libeditor/nsEditorUtils.h @@ -178,7 +178,7 @@ class MOZ_STACK_CLASS nsDOMIterator { public: explicit nsDOMIterator(nsRange& aRange); - explicit nsDOMIterator(nsIDOMNode& aNode); + explicit nsDOMIterator(nsINode& aNode); virtual ~nsDOMIterator(); void AppendList(const nsBoolDomIterFunctor& functor, diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 1d365cbccfa5..b97eb7ea6b2f 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -4806,7 +4806,7 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, else if (nsHTMLEditUtils::IsList(curParent)) { // if we don't use CSS, add a contraint to list element : they have // to be inside another list, ie >= second level of nesting - res = AlignInnerBlocks(curNode, alignType); + res = AlignInnerBlocks(*curContent, alignType); NS_ENSURE_SUCCESS(res, res); curDiv = 0; continue; @@ -4849,34 +4849,27 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, } -/////////////////////////////////////////////////////////////////////////// -// AlignInnerBlocks: align inside table cells or list items -// +/////////////////////////////////////////////////////////////////////////////// +// AlignInnerBlocks: Align inside table cells or list items +// nsresult -nsHTMLEditRules::AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType) +nsHTMLEditRules::AlignInnerBlocks(nsINode& aNode, const nsAString* alignType) { - NS_ENSURE_TRUE(aNode && alignType, NS_ERROR_NULL_POINTER); - nsresult res; - - // gather list of table cells or list items - nsCOMArray arrayOfNodes; - nsTableCellAndListItemFunctor functor; - nsDOMIterator iter(*aNode); - iter.AppendList(functor, arrayOfNodes); - - // now that we have the list, align their contents as requested - int32_t listCount = arrayOfNodes.Count(); - int32_t j; + NS_ENSURE_TRUE(alignType, NS_ERROR_NULL_POINTER); - for (j = 0; j < listCount; j++) - { - nsIDOMNode* node = arrayOfNodes[0]; - res = AlignBlockContents(node, alignType); + // Gather list of table cells or list items + nsTArray> nodeArray; + nsTableCellAndListItemFunctor functor; + nsDOMIterator iter(aNode); + iter.AppendList(functor, nodeArray); + + // Now that we have the list, align their contents as requested + for (auto& node : nodeArray) { + nsresult res = AlignBlockContents(node->AsDOMNode(), alignType); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveObjectAt(0); } - return res; + return NS_OK; } @@ -6134,7 +6127,7 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsINode& aNode, // First build up a list of all the break nodes inside the inline container. nsTArray> arrayOfBreaks; nsBRNodeFunctor functor; - nsDOMIterator iter(*GetAsDOMNode(&aNode)); + nsDOMIterator iter(aNode); iter.AppendList(functor, arrayOfBreaks); // If there aren't any breaks, just put inNode itself in the array diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index e8f412100ba9..64ec7974a7de 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -191,7 +191,7 @@ protected: nsresult DidMakeBasicBlock(mozilla::dom::Selection* aSelection, nsRulesInfo* aInfo, nsresult aResult); nsresult DidAbsolutePosition(); - nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType); + nsresult AlignInnerBlocks(nsINode& aNode, const nsAString* alignType); nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType); nsresult AppendInnerFormatNodes(nsTArray>& aArray, nsINode* aNode); From 51fddd30eee80b1afd48a7277b2b904f17a05a36 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:58 +0300 Subject: [PATCH 134/241] Bug 1153629 part 11 - Clean up nsHTMLEditRules::AdjustSpecialBreaks; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 47 ++++++++++------------------ editor/libeditor/nsHTMLEditRules.h | 2 +- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index b97eb7ea6b2f..221a23a580a0 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -276,8 +276,7 @@ nsHTMLEditRules::Init(nsPlaintextEditor *aEditor) if (node->IsElement()) { ErrorResult rv; mDocChangeRange->SelectNode(*node, rv); - res = AdjustSpecialBreaks(node); - NS_ENSURE_SUCCESS(res, res); + AdjustSpecialBreaks(); } // add ourselves as a listener to edit actions @@ -461,8 +460,7 @@ nsHTMLEditRules::AfterEditInner(EditAction action, } // add in any needed
    s, and remove any unneeded ones. - res = AdjustSpecialBreaks(); - NS_ENSURE_SUCCESS(res, res); + AdjustSpecialBreaks(); // merge any adjacent text nodes if ( (action != EditAction::insertText && @@ -7295,37 +7293,26 @@ nsHTMLEditRules::ClearCachedStyles() } -nsresult -nsHTMLEditRules::AdjustSpecialBreaks(bool aSafeToAskFrames) +void +nsHTMLEditRules::AdjustSpecialBreaks() { - nsCOMArray arrayOfNodes; - nsCOMPtr isupports; - int32_t nodeCount,j; - - // gather list of empty nodes - NS_ENSURE_STATE(mHTMLEditor); + NS_ENSURE_TRUE(mHTMLEditor, ); + + // Gather list of empty nodes + nsTArray> nodeArray; nsEmptyEditableFunctor functor(mHTMLEditor); nsDOMIterator iter(*mDocChangeRange); - iter.AppendList(functor, arrayOfNodes); + iter.AppendList(functor, nodeArray); - // put moz-br's into these empty li's and td's - nodeCount = arrayOfNodes.Count(); - for (j = 0; j < nodeCount; j++) - { - // need to put br at END of node. It may have - // empty containers in it and still pass the "IsEmptynode" test, - // and we want the br's to be after them. Also, we want the br - // to be after the selection if the selection is in this node. - uint32_t len; - nsCOMPtr theNode = arrayOfNodes[0]; - arrayOfNodes.RemoveObjectAt(0); - nsresult res = nsEditor::GetLengthOfDOMNode(theNode, len); - NS_ENSURE_SUCCESS(res, res); - res = CreateMozBR(theNode, (int32_t)len); - NS_ENSURE_SUCCESS(res, res); + // Put moz-br's into these empty li's and td's + for (auto& node : nodeArray) { + // Need to put br at END of node. It may have empty containers in it and + // still pass the "IsEmptyNode" test, and we want the br's to be after + // them. Also, we want the br to be after the selection if the selection + // is in this node. + nsresult res = CreateMozBR(node->AsDOMNode(), (int32_t)node->Length()); + NS_ENSURE_SUCCESS(res, ); } - - return NS_OK; } nsresult diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 64ec7974a7de..6094a5f0e43b 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -312,7 +312,7 @@ protected: nsresult CacheInlineStyles(nsIDOMNode *aNode); nsresult ReapplyCachedStyles(); void ClearCachedStyles(); - nsresult AdjustSpecialBreaks(bool aSafeToAskFrames = false); + void AdjustSpecialBreaks(); nsresult AdjustWhitespace(mozilla::dom::Selection* aSelection); nsresult PinSelectionToNewBlock(mozilla::dom::Selection* aSelection); nsresult CheckInterlinePosition(mozilla::dom::Selection* aSelection); From 7106d0b1753d3f33d139d32121c697d2dde47a33 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:26:58 +0300 Subject: [PATCH 135/241] Bug 1153629 part 12 - Clean up nsHTMLEditRules::RemoveEmptyNodes; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 160 ++++++++++++--------------- 1 file changed, 73 insertions(+), 87 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 221a23a580a0..7c3ee99eb6ed 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -17,7 +17,6 @@ #include "mozilla/mozalloc.h" #include "nsAString.h" #include "nsAlgorithm.h" -#include "nsCOMArray.h" #include "nsCRT.h" #include "nsCRTGlue.h" #include "nsComponentManagerUtils.h" @@ -7718,53 +7717,57 @@ nsHTMLEditRules::InDifferentTableElements(nsINode* aNode1, nsINode* aNode2) } -nsresult +nsresult nsHTMLEditRules::RemoveEmptyNodes() { - // some general notes on the algorithm used here: the goal is to examine all the - // nodes in mDocChangeRange, and remove the empty ones. We do this by using a - // content iterator to traverse all the nodes in the range, and placing the empty - // nodes into an array. After finishing the iteration, we delete the empty nodes - // in the array. (they cannot be deleted as we find them becasue that would - // invalidate the iterator.) + NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr kungFuDeathGrip(mHTMLEditor); + + // Some general notes on the algorithm used here: the goal is to examine all + // the nodes in mDocChangeRange, and remove the empty ones. We do this by + // using a content iterator to traverse all the nodes in the range, and + // placing the empty nodes into an array. After finishing the iteration, we + // delete the empty nodes in the array. (They cannot be deleted as we find + // them because that would invalidate the iterator.) + // // Since checking to see if a node is empty can be costly for nodes with many - // descendants, there are some optimizations made. I rely on the fact that the - // iterator is post-order: it will visit children of a node before visiting the - // parent node. So if I find that a child node is not empty, I know that its - // parent is not empty without even checking. So I put the parent on a "skipList" - // which is just a voidArray of nodes I can skip the empty check on. If I - // encounter a node on the skiplist, i skip the processing for that node and replace - // its slot in the skiplist with that node's parent. - // An interseting idea is to go ahead and regard parent nodes that are NOT on the - // skiplist as being empty (without even doing the IsEmptyNode check) on the theory - // that if they weren't empty, we would have encountered a non-empty child earlier - // and thus put this parent node on the skiplist. - // Unfortunately I can't use that strategy here, because the range may include - // some children of a node while excluding others. Thus I could find all the - // _examined_ children empty, but still not have an empty parent. - + // descendants, there are some optimizations made. I rely on the fact that + // the iterator is post-order: it will visit children of a node before + // visiting the parent node. So if I find that a child node is not empty, I + // know that its parent is not empty without even checking. So I put the + // parent on a "skipList" which is just a voidArray of nodes I can skip the + // empty check on. If I encounter a node on the skiplist, i skip the + // processing for that node and replace its slot in the skiplist with that + // node's parent. + // + // An interesting idea is to go ahead and regard parent nodes that are NOT on + // the skiplist as being empty (without even doing the IsEmptyNode check) on + // the theory that if they weren't empty, we would have encountered a + // non-empty child earlier and thus put this parent node on the skiplist. + // + // Unfortunately I can't use that strategy here, because the range may + // include some children of a node while excluding others. Thus I could find + // all the _examined_ children empty, but still not have an empty parent. + // need an iterator - nsCOMPtr iter = - do_CreateInstance("@mozilla.org/content/post-content-iterator;1"); - NS_ENSURE_TRUE(iter, NS_ERROR_NULL_POINTER); - + nsCOMPtr iter = NS_NewContentIterator(); + nsresult res = iter->Init(mDocChangeRange); NS_ENSURE_SUCCESS(res, res); - - nsCOMArray arrayOfEmptyNodes, arrayOfEmptyCites; - nsTArray > skipList; - // check for empty nodes + nsTArray> arrayOfEmptyNodes, arrayOfEmptyCites, skipList; + + // Check for empty nodes while (!iter->IsDone()) { - nsINode* node = iter->GetCurrentNode(); + nsCOMPtr node = iter->GetCurrentNode(); NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); - nsINode* parent = node->GetParentNode(); + nsCOMPtr parent = node->GetParentNode(); size_t idx = skipList.IndexOf(node); if (idx != skipList.NoIndex) { - // this node is on our skip list. Skip processing for this node, - // and replace its value in the skip list with the value of its parent + // This node is on our skip list. Skip processing for this node, and + // replace its value in the skip list with the value of its parent skipList[idx] = parent; } else { bool bIsCandidate = false; @@ -7772,50 +7775,46 @@ nsHTMLEditRules::RemoveEmptyNodes() bool bIsMailCite = false; if (node->IsElement()) { - dom::Element* element = node->AsElement(); - if (element->IsHTMLElement(nsGkAtoms::body)) { - // don't delete the body - } else if ((bIsMailCite = nsHTMLEditUtils::IsMailCite(element)) || - element->IsHTMLElement(nsGkAtoms::a) || - nsHTMLEditUtils::IsInlineStyle(element) || - nsHTMLEditUtils::IsList(element) || - element->IsHTMLElement(nsGkAtoms::div)) { - // only consider certain nodes to be empty for purposes of removal + if (node->IsHTMLElement(nsGkAtoms::body)) { + // Don't delete the body + } else if ((bIsMailCite = nsHTMLEditUtils::IsMailCite(node)) || + node->IsHTMLElement(nsGkAtoms::a) || + nsHTMLEditUtils::IsInlineStyle(node) || + nsHTMLEditUtils::IsList(node) || + node->IsHTMLElement(nsGkAtoms::div)) { + // Only consider certain nodes to be empty for purposes of removal bIsCandidate = true; - } else if (nsHTMLEditUtils::IsFormatNode(element) || - nsHTMLEditUtils::IsListItem(element) || - element->IsHTMLElement(nsGkAtoms::blockquote)) { - // these node types are candidates if selection is not in them - // if it is one of these, don't delete if selection inside. - // this is so we can create empty headings, etc, for the - // user to type into. + } else if (nsHTMLEditUtils::IsFormatNode(node) || + nsHTMLEditUtils::IsListItem(node) || + node->IsHTMLElement(nsGkAtoms::blockquote)) { + // These node types are candidates if selection is not in them. If + // it is one of these, don't delete if selection inside. This is so + // we can create empty headings, etc., for the user to type into. bool bIsSelInNode; res = SelectionEndpointInNode(node, &bIsSelInNode); NS_ENSURE_SUCCESS(res, res); - if (!bIsSelInNode) - { + if (!bIsSelInNode) { bIsCandidate = true; } } } - + if (bIsCandidate) { - // we delete mailcites even if they have a solo br in them - // other nodes we require to be empty - NS_ENSURE_STATE(mHTMLEditor); + // We delete mailcites even if they have a solo br in them. Other + // nodes we require to be empty. res = mHTMLEditor->IsEmptyNode(node->AsDOMNode(), &bIsEmptyNode, bIsMailCite, true); NS_ENSURE_SUCCESS(res, res); if (bIsEmptyNode) { if (bIsMailCite) { // mailcites go on a separate list from other empty nodes - arrayOfEmptyCites.AppendObject(node); + arrayOfEmptyCites.AppendElement(node); } else { - arrayOfEmptyNodes.AppendObject(node); + arrayOfEmptyNodes.AppendElement(node); } } } - + if (!bIsEmptyNode) { // put parent on skip list skipList.AppendElement(parent); @@ -7824,47 +7823,34 @@ nsHTMLEditRules::RemoveEmptyNodes() iter->Next(); } - + // now delete the empty nodes - int32_t nodeCount = arrayOfEmptyNodes.Count(); - for (int32_t j = 0; j < nodeCount; j++) { - nsCOMPtr delNode = arrayOfEmptyNodes[0]->AsDOMNode(); - arrayOfEmptyNodes.RemoveObjectAt(0); - NS_ENSURE_STATE(mHTMLEditor); + for (auto& delNode : arrayOfEmptyNodes) { if (mHTMLEditor->IsModifiableNode(delNode)) { - NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(delNode); NS_ENSURE_SUCCESS(res, res); } } - - // now delete the empty mailcites - // this is a separate step because we want to pull out any br's and preserve them. - nodeCount = arrayOfEmptyCites.Count(); - for (int32_t j = 0; j < nodeCount; j++) { - nsCOMPtr delNode = arrayOfEmptyCites[0]->AsDOMNode(); - arrayOfEmptyCites.RemoveObjectAt(0); + + // Now delete the empty mailcites. This is a separate step because we want + // to pull out any br's and preserve them. + for (auto& delNode : arrayOfEmptyCites) { bool bIsEmptyNode; - NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->IsEmptyNode(delNode, &bIsEmptyNode, false, true); NS_ENSURE_SUCCESS(res, res); - if (!bIsEmptyNode) - { - // we are deleting a cite that has just a br. We want to delete cite, + if (!bIsEmptyNode) { + // We are deleting a cite that has just a br. We want to delete cite, // but preserve br. - nsCOMPtr parent, brNode; - int32_t offset; - parent = nsEditor::GetNodeLocation(delNode, &offset); - NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->CreateBR(parent, offset, address_of(brNode)); - NS_ENSURE_SUCCESS(res, res); + nsCOMPtr parent = delNode->GetParentNode(); + int32_t offset = parent ? parent->IndexOf(delNode) : -1; + nsCOMPtr br = mHTMLEditor->CreateBR(parent, offset); + NS_ENSURE_STATE(br); } - NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(delNode); NS_ENSURE_SUCCESS(res, res); } - - return res; + + return NS_OK; } nsresult From 5bfecf04db0ee1fbe821a0465449c86908bb897f Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:13 +0300 Subject: [PATCH 136/241] Bug 1154701 part 1 - Clean up nsHTMLEditor::CreateListOfNodesToPaste; r=ehsan --- editor/libeditor/nsEditorUtils.cpp | 15 ++++ editor/libeditor/nsEditorUtils.h | 3 + editor/libeditor/nsHTMLDataTransfer.cpp | 91 +++++++++++++------------ editor/libeditor/nsHTMLEditor.h | 12 ++-- 4 files changed, 75 insertions(+), 46 deletions(-) diff --git a/editor/libeditor/nsEditorUtils.cpp b/editor/libeditor/nsEditorUtils.cpp index 68939856bd66..5ea03829c327 100644 --- a/editor/libeditor/nsEditorUtils.cpp +++ b/editor/libeditor/nsEditorUtils.cpp @@ -5,6 +5,7 @@ #include "nsEditorUtils.h" +#include "mozilla/dom/OwningNonNull.h" #include "mozilla/dom/Selection.h" #include "nsCOMArray.h" #include "nsComponentManagerUtils.h" @@ -89,6 +90,20 @@ nsDOMIterator::~nsDOMIterator() { } +void +nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, + nsTArray>& arrayOfNodes) const +{ + // Iterate through dom and build list + for (; !mIter->IsDone(); mIter->Next()) { + nsCOMPtr node = mIter->GetCurrentNode(); + + if (functor(node)) { + arrayOfNodes.AppendElement(*node); + } + } +} + void nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, nsTArray>& arrayOfNodes) const diff --git a/editor/libeditor/nsEditorUtils.h b/editor/libeditor/nsEditorUtils.h index 340970c3cec1..6f44f5a95ec0 100644 --- a/editor/libeditor/nsEditorUtils.h +++ b/editor/libeditor/nsEditorUtils.h @@ -22,6 +22,7 @@ class nsRange; template class nsCOMArray; namespace mozilla { namespace dom { +template class OwningNonNull; class Selection; } } @@ -181,6 +182,8 @@ class MOZ_STACK_CLASS nsDOMIterator explicit nsDOMIterator(nsINode& aNode); virtual ~nsDOMIterator(); + void AppendList(const nsBoolDomIterFunctor& functor, + nsTArray>& arrayOfNodes) const; void AppendList(const nsBoolDomIterFunctor& functor, nsTArray>& arrayOfNodes) const; void AppendList(const nsBoolDomIterFunctor& functor, diff --git a/editor/libeditor/nsHTMLDataTransfer.cpp b/editor/libeditor/nsHTMLDataTransfer.cpp index 72918fa0c173..42b41a8c313a 100644 --- a/editor/libeditor/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/nsHTMLDataTransfer.cpp @@ -7,6 +7,7 @@ #include #include "mozilla/dom/DocumentFragment.h" +#include "mozilla/dom/OwningNonNull.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Base64.h" #include "mozilla/BasicEvents.h" @@ -321,13 +322,21 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // this is work to be completed at a later date (probably by jfrancis) // make a list of what nodes in docFrag we need to move - nsCOMArray nodeList; - rv = CreateListOfNodesToPaste(fragmentAsNode, nodeList, - streamStartParent, streamStartOffset, - streamEndParent, streamEndOffset); - NS_ENSURE_SUCCESS(rv, rv); + nsTArray> nodeList; + nsCOMPtr fragmentAsNodeNode = do_QueryInterface(fragmentAsNode); + NS_ENSURE_STATE(fragmentAsNodeNode || !fragmentAsNode); + nsCOMPtr streamStartParentNode = + do_QueryInterface(streamStartParent); + NS_ENSURE_STATE(streamStartParentNode || !streamStartParent); + nsCOMPtr streamEndParentNode = + do_QueryInterface(streamEndParent); + NS_ENSURE_STATE(streamEndParentNode || !streamEndParent); + CreateListOfNodesToPaste(*static_cast(fragmentAsNodeNode.get()), + nodeList, + streamStartParentNode, streamStartOffset, + streamEndParentNode, streamEndOffset); - if (nodeList.Count() == 0) { + if (nodeList.Length() == 0) { return NS_OK; } @@ -352,9 +361,9 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // but if not we want to delete _contents_ of cells and replace // with non-table elements. Use cellSelectionMode bool to // indicate results. - nsIDOMNode* firstNode = nodeList[0]; - if (!nsHTMLEditUtils::IsTableElement(firstNode)) + if (!nsHTMLEditUtils::IsTableElement(nodeList[0])) { cellSelectionMode = false; + } } if (!cellSelectionMode) @@ -395,6 +404,11 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, if (!handled) { + nsCOMArray nodeListDOM; + for (auto& node : nodeList) { + nodeListDOM.AppendObject(GetAsDOMNode(node)); + } + // The rules code (WillDoAction above) might have changed the selection. // refresh our memory... rv = GetStartNodeAndOffset(selection, getter_AddRefs(parentNode), &offsetOfNewNode); @@ -402,7 +416,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, NS_ENSURE_TRUE(parentNode, NS_ERROR_FAILURE); // Adjust position based on the first node we are going to insert. - NormalizeEOLInsertPosition(nodeList[0], address_of(parentNode), &offsetOfNewNode); + NormalizeEOLInsertPosition(nodeListDOM[0], address_of(parentNode), &offsetOfNewNode); // if there are any invisible br's after our insertion point, remove them. // this is because if there is a br at end of what we paste, it will make @@ -432,14 +446,14 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // build up list of parents of first node in list that are either // lists or tables. First examine front of paste node list. nsCOMArray startListAndTableArray; - rv = GetListAndTableParents(false, nodeList, startListAndTableArray); + rv = GetListAndTableParents(false, nodeListDOM, startListAndTableArray); NS_ENSURE_SUCCESS(rv, rv); // remember number of lists and tables above us int32_t highWaterMark = -1; if (startListAndTableArray.Count() > 0) { - rv = DiscoverPartialListsAndTables(nodeList, startListAndTableArray, &highWaterMark); + rv = DiscoverPartialListsAndTables(nodeListDOM, startListAndTableArray, &highWaterMark); NS_ENSURE_SUCCESS(rv, rv); } @@ -448,33 +462,33 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // table or list contents outside the table or list. if (highWaterMark >= 0) { - rv = ReplaceOrphanedStructure(false, nodeList, startListAndTableArray, highWaterMark); + rv = ReplaceOrphanedStructure(false, nodeListDOM, startListAndTableArray, highWaterMark); NS_ENSURE_SUCCESS(rv, rv); } // Now go through the same process again for the end of the paste node list. nsCOMArray endListAndTableArray; - rv = GetListAndTableParents(true, nodeList, endListAndTableArray); + rv = GetListAndTableParents(true, nodeListDOM, endListAndTableArray); NS_ENSURE_SUCCESS(rv, rv); highWaterMark = -1; // remember number of lists and tables above us if (endListAndTableArray.Count() > 0) { - rv = DiscoverPartialListsAndTables(nodeList, endListAndTableArray, &highWaterMark); + rv = DiscoverPartialListsAndTables(nodeListDOM, endListAndTableArray, &highWaterMark); NS_ENSURE_SUCCESS(rv, rv); } // don't orphan partial list or table structure if (highWaterMark >= 0) { - rv = ReplaceOrphanedStructure(true, nodeList, endListAndTableArray, highWaterMark); + rv = ReplaceOrphanedStructure(true, nodeListDOM, endListAndTableArray, highWaterMark); NS_ENSURE_SUCCESS(rv, rv); } // Loop over the node list and paste the nodes: nsCOMPtr parentBlock, lastInsertNode, insertedContextParent; - int32_t listCount = nodeList.Count(); + int32_t listCount = nodeListDOM.Count(); int32_t j; if (IsBlockNode(parentNode)) parentBlock = parentNode; @@ -484,7 +498,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, for (j=0; j curNode = nodeList[j]; + nsCOMPtr curNode = nodeListDOM[j]; NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE); NS_ENSURE_TRUE(curNode != fragmentAsNode, NS_ERROR_FAILURE); @@ -2166,41 +2180,34 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr, return rv; } -nsresult nsHTMLEditor::CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode, - nsCOMArray& outNodeList, - nsIDOMNode *aStartNode, - int32_t aStartOffset, - nsIDOMNode *aEndNode, - int32_t aEndOffset) +void +nsHTMLEditor::CreateListOfNodesToPaste(DocumentFragment& aFragment, + nsTArray>& outNodeList, + nsINode* aStartNode, + int32_t aStartOffset, + nsINode* aEndNode, + int32_t aEndOffset) { - NS_ENSURE_TRUE(aFragmentAsNode, NS_ERROR_NULL_POINTER); - - nsresult rv; - - // if no info was provided about the boundary between context and stream, + // If no info was provided about the boundary between context and stream, // then assume all is stream. - if (!aStartNode) - { - int32_t fragLen; - rv = GetLengthOfDOMNode(aFragmentAsNode, (uint32_t&)fragLen); - NS_ENSURE_SUCCESS(rv, rv); - - aStartNode = aFragmentAsNode; + if (!aStartNode) { + aStartNode = &aFragment; aStartOffset = 0; - aEndNode = aFragmentAsNode; - aEndOffset = fragLen; + aEndNode = &aFragment; + aEndOffset = aFragment.Length(); } nsRefPtr docFragRange; - rv = nsRange::CreateRange(aStartNode, aStartOffset, aEndNode, aEndOffset, getter_AddRefs(docFragRange)); - NS_ENSURE_SUCCESS(rv, rv); + nsresult rv = nsRange::CreateRange(aStartNode, aStartOffset, + aEndNode, aEndOffset, + getter_AddRefs(docFragRange)); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + NS_ENSURE_SUCCESS(rv, ); - // now use a subtree iterator over the range to create a list of nodes + // Now use a subtree iterator over the range to create a list of nodes nsTrivialFunctor functor; nsDOMSubtreeIterator iter(*docFragRange); iter.AppendList(functor, outNodeList); - - return NS_OK; } nsresult diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index 3fc3765b41b5..2807f3f836ef 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -41,6 +41,7 @@ #include "mozilla/Attributes.h" #include "mozilla/dom/Element.h" +class nsDocumentFragment; class nsIDOMKeyEvent; class nsITransferable; class nsIClipboard; @@ -53,6 +54,9 @@ class nsRange; struct PropItem; namespace mozilla { +namespace dom { +template class OwningNonNull; +} namespace widget { struct IMEState; } // namespace widget @@ -591,11 +595,11 @@ protected: nsIDocument* aTargetDoc, nsCOMPtr *outNode, bool aTrustedInput); - nsresult CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode, - nsCOMArray& outNodeList, - nsIDOMNode *aStartNode, + void CreateListOfNodesToPaste(mozilla::dom::DocumentFragment& aFragment, + nsTArray>& outNodeList, + nsINode* aStartNode, int32_t aStartOffset, - nsIDOMNode *aEndNode, + nsINode* aEndNode, int32_t aEndOffset); nsresult CreateTagStack(nsTArray &aTagStack, nsIDOMNode *aNode); From 663dfbbd65f713b55794784316468cd642dd69cf Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:17 +0300 Subject: [PATCH 137/241] Bug 1154701 part 2 - Use more OwningNonNull in editor; r=ehsan --- editor/libeditor/nsEditorUtils.cpp | 14 -- editor/libeditor/nsEditorUtils.h | 2 - editor/libeditor/nsHTMLEditRules.cpp | 185 +++++++++++++-------------- editor/libeditor/nsHTMLEditRules.h | 30 ++--- 4 files changed, 104 insertions(+), 127 deletions(-) diff --git a/editor/libeditor/nsEditorUtils.cpp b/editor/libeditor/nsEditorUtils.cpp index 5ea03829c327..64e1be3b67b4 100644 --- a/editor/libeditor/nsEditorUtils.cpp +++ b/editor/libeditor/nsEditorUtils.cpp @@ -104,20 +104,6 @@ nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, } } -void -nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, - nsTArray>& arrayOfNodes) const -{ - // Iterate through dom and build list - for (; !mIter->IsDone(); mIter->Next()) { - nsCOMPtr node = mIter->GetCurrentNode(); - - if (functor(node)) { - arrayOfNodes.AppendElement(node); - } - } -} - void nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, nsCOMArray& arrayOfNodes) const diff --git a/editor/libeditor/nsEditorUtils.h b/editor/libeditor/nsEditorUtils.h index 6f44f5a95ec0..82eb266a75db 100644 --- a/editor/libeditor/nsEditorUtils.h +++ b/editor/libeditor/nsEditorUtils.h @@ -184,8 +184,6 @@ class MOZ_STACK_CLASS nsDOMIterator void AppendList(const nsBoolDomIterFunctor& functor, nsTArray>& arrayOfNodes) const; - void AppendList(const nsBoolDomIterFunctor& functor, - nsTArray>& arrayOfNodes) const; void AppendList(const nsBoolDomIterFunctor& functor, nsCOMArray& arrayOfNodes) const; protected: diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 7c3ee99eb6ed..d9cc2b96f351 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -689,7 +689,7 @@ nsHTMLEditRules::GetListState(bool *aMixed, bool *aOL, bool *aUL, bool *aDL) *aDL = false; bool bNonList = false; - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; nsresult res = GetListActionNodes(arrayOfNodes, EntireList::no, TouchContent::no); NS_ENSURE_SUCCESS(res, res); @@ -737,7 +737,7 @@ nsHTMLEditRules::GetListItemState(bool *aMixed, bool *aLI, bool *aDT, bool *aDD) *aDD = false; bool bNonList = false; - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; nsresult res = GetListActionNodes(arrayOfNodes, EntireList::no, TouchContent::no); NS_ENSURE_SUCCESS(res, res); @@ -806,11 +806,11 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) NS_ENSURE_SUCCESS(res, res); // is the selection collapsed? - nsCOMPtr nodeToExamine; + nsCOMPtr nodeToExamine; if (selection->Collapsed()) { // if it is, we want to look at 'parent' and its ancestors // for divs with alignment on them - nodeToExamine = GetAsDOMNode(parent); + nodeToExamine = parent; } else if (!mHTMLEditor) { return NS_ERROR_UNEXPECTED; @@ -818,12 +818,11 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) else if (mHTMLEditor->IsTextNode(parent)) { // if we are in a text node, then that is the node of interest - nodeToExamine = GetAsDOMNode(parent); + nodeToExamine = parent; } else if (parent->IsHTMLElement(nsGkAtoms::html) && offset == rootOffset) { // if we have selected the body, let's look at the first editable node NS_ENSURE_STATE(mHTMLEditor); - nodeToExamine = - GetAsDOMNode(mHTMLEditor->GetNextNode(parent, offset, true)); + nodeToExamine = mHTMLEditor->GetNextNode(parent, offset, true); } else { @@ -831,21 +830,21 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) GetPromotedRanges(*selection, arrayOfRanges, EditAction::align); // use these ranges to construct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::align, TouchContent::no); NS_ENSURE_SUCCESS(res, res); - nodeToExamine = GetAsDOMNode(arrayOfNodes.SafeElementAt(0)); + nodeToExamine = arrayOfNodes.SafeElementAt(0); } NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER); NS_NAMED_LITERAL_STRING(typeAttrName, "align"); nsIAtom *dummyProperty = nullptr; - nsCOMPtr blockParent; + nsCOMPtr blockParent; NS_ENSURE_STATE(mHTMLEditor); if (mHTMLEditor->IsBlockNode(nodeToExamine)) - blockParent = nodeToExamine; + blockParent = nodeToExamine->AsElement(); else { NS_ENSURE_STATE(mHTMLEditor); blockParent = mHTMLEditor->GetBlockNodeParent(nodeToExamine); @@ -856,17 +855,16 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) NS_ENSURE_STATE(mHTMLEditor); if (mHTMLEditor->IsCSSEnabled()) { - nsCOMPtr blockParentContent = do_QueryInterface(blockParent); NS_ENSURE_STATE(mHTMLEditor); - if (blockParentContent && - mHTMLEditor->mHTMLCSSUtils->IsCSSEditableProperty(blockParentContent, dummyProperty, &typeAttrName)) - { + if (mHTMLEditor->mHTMLCSSUtils->IsCSSEditableProperty(blockParent, + dummyProperty, + &typeAttrName)) { // we are in CSS mode and we know how to align this element with CSS nsAutoString value; // let's get the value(s) of text-align or margin-left/margin-right NS_ENSURE_STATE(mHTMLEditor); mHTMLEditor->mHTMLCSSUtils->GetCSSEquivalentToHTMLInlineStyleSet( - blockParentContent, dummyProperty, &typeAttrName, value, + blockParent, dummyProperty, &typeAttrName, value, nsHTMLCSSUtils::eComputed); if (value.EqualsLiteral("center") || value.EqualsLiteral("-moz-center") || @@ -893,7 +891,6 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) } // check up the ladder for divs with alignment - nsCOMPtr temp = nodeToExamine; bool isFirstNodeToExamine = true; while (nodeToExamine) { @@ -904,8 +901,7 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) // behaviour of html tables regarding to text alignment return NS_OK; } - if (nsHTMLEditUtils::SupportsAlignAttr(nodeToExamine)) - { + if (nsHTMLEditUtils::SupportsAlignAttr(GetAsDOMNode(nodeToExamine))) { // check for alignment nsCOMPtr elem = do_QueryInterface(nodeToExamine); if (elem) @@ -928,9 +924,7 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) } } isFirstNodeToExamine = false; - res = nodeToExamine->GetParentNode(getter_AddRefs(temp)); - if (NS_FAILED(res)) temp = nullptr; - nodeToExamine = temp; + nodeToExamine = nodeToExamine->GetParentNode(); } return NS_OK; } @@ -957,7 +951,7 @@ nsHTMLEditRules::GetIndentState(bool *aCanIndent, bool *aCanOutdent) OwningNonNull selection = *mHTMLEditor->GetSelection(); // contruct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; nsresult res = GetNodesFromSelection(*selection, EditAction::indent, arrayOfNodes, TouchContent::no); NS_ENSURE_SUCCESS(res, res); @@ -1058,7 +1052,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) // using "x" as an uninitialized value, since "" is meaningful nsAutoString formatStr(NS_LITERAL_STRING("x")); - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; nsresult res = GetParagraphFormatNodes(arrayOfNodes, TouchContent::no); NS_ENSURE_SUCCESS(res, res); @@ -1089,7 +1083,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) res = mHTMLEditor->GetStartNodeAndOffset(selection, getter_AddRefs(selNode), &selOffset); NS_ENSURE_SUCCESS(res, res); NS_ENSURE_TRUE(selNode, NS_ERROR_NULL_POINTER); - arrayOfNodes.AppendElement(selNode); + arrayOfNodes.AppendElement(*selNode); } // remember root node @@ -1149,7 +1143,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) } nsresult -nsHTMLEditRules::AppendInnerFormatNodes(nsTArray>& aArray, +nsHTMLEditRules::AppendInnerFormatNodes(nsTArray>& aArray, nsINode* aNode) { MOZ_ASSERT(aNode); @@ -1168,11 +1162,11 @@ nsHTMLEditRules::AppendInnerFormatNodes(nsTArray>& aArray, // if it's a div, etc, recurse AppendInnerFormatNodes(aArray, child); } else if (isFormat) { - aArray.AppendElement(child); + aArray.AppendElement(*child); } else if (!foundInline) { // if this is the first inline we've found, use it foundInline = true; - aArray.AppendElement(child); + aArray.AppendElement(*child); } } return NS_OK; @@ -2404,7 +2398,7 @@ nsHTMLEditRules::WillDeleteSelection(Selection* aSelection, OwningNonNull range = *aSelection->GetRangeAt(rangeIdx); // Build a list of nodes in the range - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; nsTrivialFunctor functor; nsDOMSubtreeIterator iter(*range); iter.AppendList(functor, arrayOfNodes); @@ -2859,7 +2853,7 @@ nsHTMLEditRules::JoinBlocks(nsIDOMNode *aLeftNode, nsresult nsHTMLEditRules::MoveBlock(nsIDOMNode *aLeftBlock, nsIDOMNode *aRightBlock, int32_t aLeftOffset, int32_t aRightOffset) { - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; // GetNodesFromPoint is the workhorse that figures out what we wnat to move. nsresult res = GetNodesFromPoint(::DOMPoint(aRightBlock,aRightOffset), EditAction::makeList, arrayOfNodes, @@ -3053,7 +3047,7 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; res = GetListActionNodes(arrayOfNodes, aEntireList ? EntireList::yes : EntireList::no); NS_ENSURE_SUCCESS(res, res); @@ -3336,7 +3330,7 @@ nsHTMLEditRules::WillRemoveList(Selection* aSelection, GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::makeList); // use these ranges to contruct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; res = GetListActionNodes(arrayOfNodes, EntireList::no); NS_ENSURE_SUCCESS(res, res); @@ -3345,7 +3339,7 @@ nsHTMLEditRules::WillRemoveList(Selection* aSelection, int32_t i; for (i=listCount-1; i>=0; i--) { - nsCOMPtr& testNode = arrayOfNodes[i]; + OwningNonNull testNode = arrayOfNodes[i]; NS_ENSURE_STATE(mHTMLEditor); if (!mHTMLEditor->IsEditable(testNode)) { @@ -3417,7 +3411,7 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, nsString tString(*aBlockType); // contruct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; res = GetNodesFromSelection(*aSelection, EditAction::makeBasicBlock, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); @@ -3515,7 +3509,7 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, mNewBlock = theBlock; // delete anything that was in the list of nodes while (!arrayOfNodes.IsEmpty()) { - nsCOMPtr curNode = arrayOfNodes[0]; + OwningNonNull curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); @@ -3596,8 +3590,8 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, NS_ENSURE_SUCCESS(res, res); NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); - nsTArray> arrayOfRanges; - nsTArray> arrayOfNodes; + nsTArray> arrayOfRanges; + nsTArray> arrayOfNodes; // short circuit: detect case of collapsed selection inside an
  • . // just sublist that
  • . This prevents bug 97797. @@ -3622,7 +3616,7 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, if (liNode) { - arrayOfNodes.AppendElement(liNode); + arrayOfNodes.AppendElement(*liNode); } else { @@ -3655,7 +3649,7 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, RelativeChangeIndentationOfElementNode(theBlock->AsDOMNode(), +1); // delete anything that was in the list of nodes while (!arrayOfNodes.IsEmpty()) { - nsCOMPtr curNode = arrayOfNodes[0]; + OwningNonNull curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); @@ -3816,7 +3810,7 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::indent); // use these ranges to contruct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::indent); NS_ENSURE_SUCCESS(res, res); @@ -3840,7 +3834,7 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, mNewBlock = theBlock->AsDOMNode(); // delete anything that was in the list of nodes while (!arrayOfNodes.IsEmpty()) { - nsCOMPtr curNode = arrayOfNodes[0]; + OwningNonNull curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); @@ -4045,7 +4039,7 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, // this basically just expands the range to include the immediate // block parent, and then further expands to include any ancestors // whose children are all in the range - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; res = GetNodesFromSelection(*aSelection, EditAction::outdent, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); @@ -4633,7 +4627,7 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, // block parent, and then further expands to include any ancestors // whose children are all in the range *aHandled = true; - nsTArray> nodeArray; + nsTArray> nodeArray; res = GetNodesFromSelection(*aSelection, EditAction::align, nodeArray); NS_ENSURE_SUCCESS(res, res); @@ -4644,7 +4638,7 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, if (!listCount) emptyDiv = true; if (listCount == 1) { - nsCOMPtr theNode = nodeArray[0]; + OwningNonNull theNode = nodeArray[0]; if (nsHTMLEditUtils::SupportsAlignAttr(GetAsDOMNode(theNode))) { // the node is a table element, an horiz rule, a paragraph, a div @@ -4855,7 +4849,7 @@ nsHTMLEditRules::AlignInnerBlocks(nsINode& aNode, const nsAString* alignType) NS_ENSURE_TRUE(alignType, NS_ERROR_NULL_POINTER); // Gather list of table cells or list items - nsTArray> nodeArray; + nsTArray> nodeArray; nsTableCellAndListItemFunctor functor; nsDOMIterator iter(aNode); iter.AppendList(functor, nodeArray); @@ -5084,7 +5078,7 @@ nsHTMLEditRules::CheckForInvisibleBR(nsIDOMNode *aBlock, // void nsHTMLEditRules::GetInnerContent(nsINode& aNode, - nsTArray>& aOutArrayOfNodes, + nsTArray>& aOutArrayOfNodes, int32_t* aIndex, Lists aLists, Tables aTables) { MOZ_ASSERT(aIndex); @@ -5096,7 +5090,7 @@ nsHTMLEditRules::GetInnerContent(nsINode& aNode, (aTables == Tables::yes && nsHTMLEditUtils::IsTableElement(node))) { GetInnerContent(*node, aOutArrayOfNodes, aIndex, aLists, aTables); } else { - aOutArrayOfNodes.InsertElementAt(*aIndex, node); + aOutArrayOfNodes.InsertElementAt(*aIndex, *node); (*aIndex)++; } } @@ -5734,7 +5728,7 @@ class NodeComparator class nsUniqueFunctor : public nsBoolDomIterFunctor { public: - explicit nsUniqueFunctor(nsTArray> &aArray) : mArray(aArray) + explicit nsUniqueFunctor(nsTArray> &aArray) : mArray(aArray) { } // used to build list of all nodes iterator covers @@ -5744,7 +5738,7 @@ public: } private: - nsTArray>& mArray; + nsTArray>& mArray; }; /////////////////////////////////////////////////////////////////////////////// @@ -5753,7 +5747,7 @@ private: // nsresult nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRanges, - nsTArray>& aOutArrayOfNodes, + nsTArray>& aOutArrayOfNodes, EditAction aOperationType, TouchContent aTouchContent) { @@ -5767,7 +5761,7 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange // allowed to touch content. if (aTouchContent == TouchContent::yes) { - nsTArray> rangeItemArray; + nsTArray> rangeItemArray; rangeItemArray.AppendElements(rangeCount); // First register ranges for special editor gravity @@ -5800,7 +5794,7 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange // We don't want duplicates in aOutArrayOfNodes, so we use an // iterator/functor that only return nodes that are not already in // aOutArrayOfNodes. - nsTArray> nodes; + nsTArray> nodes; iter.AppendList(nsUniqueFunctor(aOutArrayOfNodes), nodes); aOutArrayOfNodes.AppendElements(nodes); } @@ -5810,7 +5804,7 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange // them. Alter the list as needed. if (aOperationType == EditAction::makeBasicBlock) { for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - nsCOMPtr node = aOutArrayOfNodes[i]; + OwningNonNull node = aOutArrayOfNodes[i]; if (nsHTMLEditUtils::IsListItem(node)) { int32_t j = i; aOutArrayOfNodes.RemoveElementAt(i); @@ -5823,7 +5817,7 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange aOperationType == EditAction::indent || aOperationType == EditAction::setAbsolutePosition) { for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - nsCOMPtr node = aOutArrayOfNodes[i]; + OwningNonNull node = aOutArrayOfNodes[i]; if (nsHTMLEditUtils::IsTableElementButNotTable(node)) { int32_t j = i; aOutArrayOfNodes.RemoveElementAt(i); @@ -5835,7 +5829,7 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange if (aOperationType == EditAction::outdent && !mHTMLEditor->IsCSSEnabled()) { for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - nsCOMPtr node = aOutArrayOfNodes[i]; + OwningNonNull node = aOutArrayOfNodes[i]; if (node->IsHTMLElement(nsGkAtoms::div)) { int32_t j = i; aOutArrayOfNodes.RemoveElementAt(i); @@ -5854,11 +5848,11 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange aOperationType == EditAction::indent || aOperationType == EditAction::outdent) { for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - nsCOMPtr node = aOutArrayOfNodes[i]; + OwningNonNull node = aOutArrayOfNodes[i]; if (aTouchContent == TouchContent::yes && IsInlineNode(GetAsDOMNode(node)) && mHTMLEditor->IsContainer(node) && !mHTMLEditor->IsTextNode(node)) { - nsTArray> arrayOfInlines; + nsTArray> arrayOfInlines; res = BustUpInlinesAtBRs(*node, arrayOfInlines); NS_ENSURE_SUCCESS(res, res); @@ -5874,17 +5868,17 @@ nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRange void nsHTMLEditRules::GetChildNodesForOperation(nsINode& aNode, - nsTArray>& outArrayOfNodes) + nsTArray>& outArrayOfNodes) { for (nsCOMPtr child = aNode.GetFirstChild(); child; child = child->GetNextSibling()) { - outArrayOfNodes.AppendElement(child); + outArrayOfNodes.AppendElement(*child); } } nsresult -nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNodes, +nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNodes, EntireList aEntireList, TouchContent aTouchContent) { @@ -5903,7 +5897,7 @@ nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNode for (nsCOMPtr parent = range->GetCommonAncestor(); parent; parent = parent->GetParentNode()) { if (nsHTMLEditUtils::IsList(parent)) { - aOutArrayOfNodes.AppendElement(parent); + aOutArrayOfNodes.AppendElement(*parent); break; } } @@ -5927,7 +5921,7 @@ nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNode // Pre-process our list of nodes for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - nsCOMPtr testNode = aOutArrayOfNodes[i]; + OwningNonNull testNode = aOutArrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. if (!mHTMLEditor->IsEditable(testNode)) { @@ -5953,7 +5947,7 @@ nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNode void -nsHTMLEditRules::LookInsideDivBQandList(nsTArray>& aNodeArray) +nsHTMLEditRules::LookInsideDivBQandList(nsTArray>& aNodeArray) { NS_ENSURE_TRUE(mHTMLEditor, ); nsCOMPtr kungFuDeathGrip(mHTMLEditor); @@ -5965,7 +5959,7 @@ nsHTMLEditRules::LookInsideDivBQandList(nsTArray>& aNodeArray) return; } - nsCOMPtr curNode = aNodeArray[0]; + OwningNonNull curNode = aNodeArray[0]; while (curNode->IsHTMLElement(nsGkAtoms::div) || nsHTMLEditUtils::IsList(curNode) || @@ -5998,7 +5992,7 @@ nsHTMLEditRules::LookInsideDivBQandList(nsTArray>& aNodeArray) return; } - aNodeArray.AppendElement(curNode); + aNodeArray.AppendElement(*curNode); } @@ -6026,7 +6020,7 @@ nsHTMLEditRules::GetDefinitionListItemTypes(dom::Element* aElement, bool* aDT, b } nsresult -nsHTMLEditRules::GetParagraphFormatNodes(nsTArray>& outArrayOfNodes, +nsHTMLEditRules::GetParagraphFormatNodes(nsTArray>& outArrayOfNodes, TouchContent aTouchContent) { NS_ENSURE_STATE(mHTMLEditor); @@ -6042,7 +6036,7 @@ nsHTMLEditRules::GetParagraphFormatNodes(nsTArray>& outArrayOf // Pre-process our list of nodes for (int32_t i = outArrayOfNodes.Length() - 1; i >= 0; i--) { - nsCOMPtr testNode = outArrayOfNodes[i]; + OwningNonNull testNode = outArrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. if (!mHTMLEditor->IsEditable(testNode)) { @@ -6057,7 +6051,7 @@ nsHTMLEditRules::GetParagraphFormatNodes(nsTArray>& outArrayOf nsHTMLEditUtils::IsListItem(testNode)) { int32_t j = i; outArrayOfNodes.RemoveElementAt(i); - GetInnerContent(*testNode, outArrayOfNodes, &j); + GetInnerContent(testNode, outArrayOfNodes, &j); } } return NS_OK; @@ -6116,20 +6110,20 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item) nsresult nsHTMLEditRules::BustUpInlinesAtBRs(nsINode& aNode, - nsTArray>& aOutArrayOfNodes) + nsTArray>& aOutArrayOfNodes) { NS_ENSURE_STATE(mHTMLEditor); nsCOMPtr kungFuDeathGrip(mHTMLEditor); // First build up a list of all the break nodes inside the inline container. - nsTArray> arrayOfBreaks; + nsTArray> arrayOfBreaks; nsBRNodeFunctor functor; nsDOMIterator iter(aNode); iter.AppendList(functor, arrayOfBreaks); // If there aren't any breaks, just put inNode itself in the array - if (arrayOfBreaks.IsEmpty()) { - aOutArrayOfNodes.AppendElement(&aNode); + if (!arrayOfBreaks.Length()) { + aOutArrayOfNodes.AppendElement(aNode); return NS_OK; } @@ -6139,7 +6133,7 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsINode& aNode, nsCOMPtr leftDOMNode, rightDOMNode; for (uint32_t i = 0; i < arrayOfBreaks.Length(); i++) { - nsCOMPtr breakNode = arrayOfBreaks[i]->AsElement(); + OwningNonNull breakNode = *arrayOfBreaks[i]->AsElement(); NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER); nsCOMPtr splitParentNode = breakNode->GetParentNode(); int32_t splitOffset = splitParentNode ? @@ -6158,12 +6152,12 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsINode& aNode, // actually split anything nsCOMPtr leftNode = do_QueryInterface(leftDOMNode); NS_ENSURE_STATE(leftNode); - aOutArrayOfNodes.AppendElement(leftNode); + aOutArrayOfNodes.AppendElement(*leftNode); } // Move break outside of container and also put in node list res = mHTMLEditor->MoveNode(breakNode, inlineParentNode, resultOffset); NS_ENSURE_SUCCESS(res, res); - aOutArrayOfNodes.AppendElement(breakNode); + aOutArrayOfNodes.AppendElement(*breakNode); // Now rightNode becomes the new node to split splitDeepNode = rightDOMNode; @@ -6172,7 +6166,7 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsINode& aNode, if (rightDOMNode) { nsCOMPtr rightNode = do_QueryInterface(rightDOMNode); NS_ENSURE_STATE(rightNode); - aOutArrayOfNodes.AppendElement(rightNode); + aOutArrayOfNodes.AppendElement(*rightNode); } return NS_OK; } @@ -6201,7 +6195,7 @@ nsHTMLEditRules::GetHighestInlineParent(nsIDOMNode* aNode) nsresult nsHTMLEditRules::GetNodesFromPoint(::DOMPoint aPoint, EditAction aOperation, - nsTArray>& outArrayOfNodes, + nsTArray>& outArrayOfNodes, TouchContent aTouchContent) { NS_ENSURE_STATE(aPoint.node); @@ -6234,7 +6228,7 @@ nsHTMLEditRules::GetNodesFromPoint(::DOMPoint aPoint, nsresult nsHTMLEditRules::GetNodesFromSelection(Selection& aSelection, EditAction aOperation, - nsTArray>& outArrayOfNodes, + nsTArray>& outArrayOfNodes, TouchContent aTouchContent) { // Promote selection ranges @@ -6255,7 +6249,7 @@ nsHTMLEditRules::GetNodesFromSelection(Selection& aSelection, // transition means that adjacent nodes in the array don't // have the same parent. void -nsHTMLEditRules::MakeTransitionList(nsTArray>& aNodeArray, +nsHTMLEditRules::MakeTransitionList(nsTArray>& aNodeArray, nsTArray& aTransitionArray) { nsCOMPtr prevParent; @@ -6768,7 +6762,7 @@ nsHTMLEditRules::ReturnInListItem(Selection* aSelection, // MakeBlockquote: Put the list of nodes into one or more blockquotes. // nsresult -nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) +nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) { // The idea here is to put the nodes into a minimal number of blockquotes. // When the user blockquotes something, they expect one blockquote. That may @@ -6788,7 +6782,7 @@ nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) // Forget any previous block curBlock = nullptr; // Recursion time - nsTArray> childArray; + nsTArray> childArray; GetChildNodesForOperation(*curNode, childArray); res = MakeBlockquote(childArray); NS_ENSURE_SUCCESS(res, res); @@ -6832,7 +6826,7 @@ nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) /////////////////////////////////////////////////////////////////////////////// // RemoveBlockStyle: Make the nodes have no special block type. nsresult -nsHTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray) +nsHTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray) { NS_ENSURE_STATE(mHTMLEditor); nsCOMPtr kungFuDeathGrip(mHTMLEditor); @@ -6871,7 +6865,7 @@ nsHTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray) firstNode = lastNode = curBlock = nullptr; } // Recursion time - nsTArray> childArray; + nsTArray> childArray; GetChildNodesForOperation(*curNode, childArray); res = RemoveBlockStyle(childArray); NS_ENSURE_SUCCESS(res, res); @@ -6921,7 +6915,7 @@ nsHTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray) // ApplyBlockStyle: Do whatever it takes to make the list of nodes into one or // more blocks of type aBlockTag. nsresult -nsHTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, +nsHTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, nsIAtom& aBlockTag) { // Intent of this routine is to be used for converting to/from headers, @@ -6976,7 +6970,7 @@ nsHTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, // Forget any previous block used for previous inline nodes curBlock = nullptr; // Recursion time - nsTArray> childArray; + nsTArray> childArray; GetChildNodesForOperation(*curNode, childArray); if (childArray.Length()) { res = ApplyBlockStyle(childArray, aBlockTag); @@ -7298,7 +7292,7 @@ nsHTMLEditRules::AdjustSpecialBreaks() NS_ENSURE_TRUE(mHTMLEditor, ); // Gather list of empty nodes - nsTArray> nodeArray; + nsTArray> nodeArray; nsEmptyEditableFunctor functor(mHTMLEditor); nsDOMIterator iter(*mDocChangeRange); iter.AppendList(functor, nodeArray); @@ -7755,12 +7749,11 @@ nsHTMLEditRules::RemoveEmptyNodes() nsresult res = iter->Init(mDocChangeRange); NS_ENSURE_SUCCESS(res, res); - nsTArray> arrayOfEmptyNodes, arrayOfEmptyCites, skipList; + nsTArray> arrayOfEmptyNodes, arrayOfEmptyCites, skipList; // Check for empty nodes while (!iter->IsDone()) { - nsCOMPtr node = iter->GetCurrentNode(); - NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + OwningNonNull node = *iter->GetCurrentNode(); nsCOMPtr parent = node->GetParentNode(); @@ -7808,16 +7801,16 @@ nsHTMLEditRules::RemoveEmptyNodes() if (bIsEmptyNode) { if (bIsMailCite) { // mailcites go on a separate list from other empty nodes - arrayOfEmptyCites.AppendElement(node); + arrayOfEmptyCites.AppendElement(*node); } else { - arrayOfEmptyNodes.AppendElement(node); + arrayOfEmptyNodes.AppendElement(*node); } } } if (!bIsEmptyNode) { // put parent on skip list - skipList.AppendElement(parent); + skipList.AppendElement(*parent); } } @@ -7919,7 +7912,7 @@ nsHTMLEditRules::IsEmptyInline(nsIDOMNode *aNode) bool -nsHTMLEditRules::ListIsEmptyLine(nsTArray>& aArrayOfNodes) +nsHTMLEditRules::ListIsEmptyLine(nsTArray>& aArrayOfNodes) { // We have a list of nodes which we are candidates for being moved into a new // block. Determine if it's anything more than a blank line. Look for @@ -7932,7 +7925,7 @@ nsHTMLEditRules::ListIsEmptyLine(nsTArray>& aArrayOfNodes) int32_t brCount = 0; for (auto& node : aArrayOfNodes) { - if (!node || !mHTMLEditor->IsEditable(node)) { + if (!mHTMLEditor->IsEditable(node)) { continue; } if (nsTextEditUtils::IsBreak(node)) { @@ -8751,7 +8744,7 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection, EditAction::setAbsolutePosition); // use these ranges to contruct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::setAbsolutePosition); NS_ENSURE_SUCCESS(res, res); @@ -8776,7 +8769,7 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection, mNewBlock = thePositionedDiv->AsDOMNode(); // delete anything that was in the list of nodes while (!arrayOfNodes.IsEmpty()) { - nsCOMPtr curNode = arrayOfNodes[0]; + OwningNonNull curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 6094a5f0e43b..585ca49a07ca 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -193,13 +193,13 @@ protected: nsresult DidAbsolutePosition(); nsresult AlignInnerBlocks(nsINode& aNode, const nsAString* alignType); nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType); - nsresult AppendInnerFormatNodes(nsTArray>& aArray, + nsresult AppendInnerFormatNodes(nsTArray>& aArray, nsINode* aNode); nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat); enum class Lists { no, yes }; enum class Tables { no, yes }; void GetInnerContent(nsINode& aNode, - nsTArray>& aOutArrayOfNodes, + nsTArray>& aOutArrayOfNodes, int32_t* aIndex, Lists aLists = Lists::yes, Tables aTables = Tables::yes); already_AddRefed IsInListItem(nsIDOMNode* aNode); @@ -270,38 +270,38 @@ protected: void PromoteRange(nsRange& aRange, EditAction inOperationType); enum class TouchContent { no, yes }; nsresult GetNodesForOperation(nsTArray>& aArrayOfRanges, - nsTArray>& aOutArrayOfNodes, + nsTArray>& aOutArrayOfNodes, EditAction aOperationType, TouchContent aTouchContent = TouchContent::yes); void GetChildNodesForOperation(nsINode& aNode, - nsTArray>& outArrayOfNodes); + nsTArray>& outArrayOfNodes); nsresult GetNodesFromPoint(::DOMPoint aPoint, EditAction aOperation, - nsTArray>& outArrayOfNodes, + nsTArray>& outArrayOfNodes, TouchContent aTouchContent); nsresult GetNodesFromSelection(mozilla::dom::Selection& aSelection, EditAction aOperation, - nsTArray>& outArrayOfNodes, + nsTArray>& outArrayOfNodes, TouchContent aTouchContent = TouchContent::yes); enum class EntireList { no, yes }; - nsresult GetListActionNodes(nsTArray>& aOutArrayOfNodes, + nsresult GetListActionNodes(nsTArray>& aOutArrayOfNodes, EntireList aEntireList, TouchContent aTouchContent = TouchContent::yes); void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD); nsresult GetParagraphFormatNodes( - nsTArray>& outArrayOfNodes, + nsTArray>& outArrayOfNodes, TouchContent aTouchContent = TouchContent::yes); - void LookInsideDivBQandList(nsTArray>& aNodeArray); + void LookInsideDivBQandList(nsTArray>& aNodeArray); nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange); nsresult BustUpInlinesAtBRs(nsINode& aNode, - nsTArray>& aOutArrayOfNodes); + nsTArray>& aOutArrayOfNodes); nsCOMPtr GetHighestInlineParent(nsIDOMNode* aNode); - void MakeTransitionList(nsTArray>& aNodeArray, + void MakeTransitionList(nsTArray>& aNodeArray, nsTArray& aTransitionArray); - nsresult RemoveBlockStyle(nsTArray>& aNodeArray); - nsresult ApplyBlockStyle(nsTArray>& aNodeArray, + nsresult RemoveBlockStyle(nsTArray>& aNodeArray); + nsresult ApplyBlockStyle(nsTArray>& aNodeArray, nsIAtom& aBlockTag); - nsresult MakeBlockquote(nsTArray>& aNodeArray); + nsresult MakeBlockquote(nsTArray>& aNodeArray); nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr& inOutParent, int32_t& inOutOffset); nsresult AddTerminatingBR(nsIDOMNode *aBlock); @@ -337,7 +337,7 @@ protected: nsresult ConfirmSelectionInBody(); nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode); bool IsEmptyInline(nsIDOMNode *aNode); - bool ListIsEmptyLine(nsTArray>& arrayOfNodes); + bool ListIsEmptyLine(nsTArray>& arrayOfNodes); nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly); nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts); nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly); From 30ee50d5a43009683f59412e090a9b55bd8da68e Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:17 +0300 Subject: [PATCH 138/241] Bug 1154701 part 3 - Clean up nsHTMLEditor::GetListAndTableParents, DiscoverPartialListsAndTables, ScanForListAndTableStructure, ReplaceOrphanedStructure; r=ehsan --- editor/libeditor/nsHTMLDataTransfer.cpp | 328 +++++++++--------------- editor/libeditor/nsHTMLEditor.h | 28 +- 2 files changed, 136 insertions(+), 220 deletions(-) diff --git a/editor/libeditor/nsHTMLDataTransfer.cpp b/editor/libeditor/nsHTMLDataTransfer.cpp index 42b41a8c313a..2a93cc613403 100644 --- a/editor/libeditor/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/nsHTMLDataTransfer.cpp @@ -15,7 +15,6 @@ #include "mozilla/dom/Selection.h" #include "nsAString.h" #include "nsAutoPtr.h" -#include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsCRT.h" #include "nsCRTGlue.h" @@ -103,39 +102,6 @@ static nsresult RemoveFragComments(nsCString &theStr); static void RemoveBodyAndHead(nsIDOMNode *aNode); static nsresult FindTargetNode(nsIDOMNode *aStart, nsCOMPtr &aResult); -static nsCOMPtr GetListParent(nsIDOMNode* aNode) -{ - NS_ENSURE_TRUE(aNode, nullptr); - nsCOMPtr parent, tmp; - aNode->GetParentNode(getter_AddRefs(parent)); - while (parent) - { - if (nsHTMLEditUtils::IsList(parent)) { - return parent; - } - parent->GetParentNode(getter_AddRefs(tmp)); - parent = tmp; - } - return nullptr; -} - -static nsCOMPtr GetTableParent(nsIDOMNode* aNode) -{ - NS_ENSURE_TRUE(aNode, nullptr); - nsCOMPtr parent, tmp; - aNode->GetParentNode(getter_AddRefs(parent)); - while (parent) - { - if (nsHTMLEditUtils::IsTable(parent)) { - return parent; - } - parent->GetParentNode(getter_AddRefs(tmp)); - parent = tmp; - } - return nullptr; -} - - nsresult nsHTMLEditor::LoadHTML(const nsAString & aInputString) { @@ -404,11 +370,6 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, if (!handled) { - nsCOMArray nodeListDOM; - for (auto& node : nodeList) { - nodeListDOM.AppendObject(GetAsDOMNode(node)); - } - // The rules code (WillDoAction above) might have changed the selection. // refresh our memory... rv = GetStartNodeAndOffset(selection, getter_AddRefs(parentNode), &offsetOfNewNode); @@ -416,7 +377,8 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, NS_ENSURE_TRUE(parentNode, NS_ERROR_FAILURE); // Adjust position based on the first node we are going to insert. - NormalizeEOLInsertPosition(nodeListDOM[0], address_of(parentNode), &offsetOfNewNode); + NormalizeEOLInsertPosition(GetAsDOMNode(nodeList[0]), + address_of(parentNode), &offsetOfNewNode); // if there are any invisible br's after our insertion point, remove them. // this is because if there is a br at end of what we paste, it will make @@ -445,16 +407,15 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // build up list of parents of first node in list that are either // lists or tables. First examine front of paste node list. - nsCOMArray startListAndTableArray; - rv = GetListAndTableParents(false, nodeListDOM, startListAndTableArray); - NS_ENSURE_SUCCESS(rv, rv); + nsTArray> startListAndTableArray; + GetListAndTableParents(StartOrEnd::start, nodeList, + startListAndTableArray); // remember number of lists and tables above us int32_t highWaterMark = -1; - if (startListAndTableArray.Count() > 0) - { - rv = DiscoverPartialListsAndTables(nodeListDOM, startListAndTableArray, &highWaterMark); - NS_ENSURE_SUCCESS(rv, rv); + if (startListAndTableArray.Length() > 0) { + highWaterMark = DiscoverPartialListsAndTables(nodeList, + startListAndTableArray); } // if we have pieces of tables or lists to be inserted, let's force the paste @@ -462,33 +423,31 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // table or list contents outside the table or list. if (highWaterMark >= 0) { - rv = ReplaceOrphanedStructure(false, nodeListDOM, startListAndTableArray, highWaterMark); - NS_ENSURE_SUCCESS(rv, rv); + ReplaceOrphanedStructure(StartOrEnd::start, nodeList, + startListAndTableArray, highWaterMark); } // Now go through the same process again for the end of the paste node list. - nsCOMArray endListAndTableArray; - rv = GetListAndTableParents(true, nodeListDOM, endListAndTableArray); - NS_ENSURE_SUCCESS(rv, rv); + nsTArray> endListAndTableArray; + GetListAndTableParents(StartOrEnd::end, nodeList, endListAndTableArray); highWaterMark = -1; // remember number of lists and tables above us - if (endListAndTableArray.Count() > 0) - { - rv = DiscoverPartialListsAndTables(nodeListDOM, endListAndTableArray, &highWaterMark); - NS_ENSURE_SUCCESS(rv, rv); + if (endListAndTableArray.Length() > 0) { + highWaterMark = DiscoverPartialListsAndTables(nodeList, + endListAndTableArray); } // don't orphan partial list or table structure if (highWaterMark >= 0) { - rv = ReplaceOrphanedStructure(true, nodeListDOM, endListAndTableArray, highWaterMark); - NS_ENSURE_SUCCESS(rv, rv); + ReplaceOrphanedStructure(StartOrEnd::end, nodeList, + endListAndTableArray, highWaterMark); } // Loop over the node list and paste the nodes: nsCOMPtr parentBlock, lastInsertNode, insertedContextParent; - int32_t listCount = nodeListDOM.Count(); + int32_t listCount = nodeList.Length(); int32_t j; if (IsBlockNode(parentNode)) parentBlock = parentNode; @@ -498,7 +457,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, for (j=0; j curNode = nodeListDOM[j]; + nsCOMPtr curNode = nodeList[j]->AsDOMNode(); NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE); NS_ENSURE_TRUE(curNode != fragmentAsNode, NS_ERROR_FAILURE); @@ -2210,181 +2169,140 @@ nsHTMLEditor::CreateListOfNodesToPaste(DocumentFragment& aFragment, iter.AppendList(functor, outNodeList); } -nsresult -nsHTMLEditor::GetListAndTableParents(bool aEnd, - nsCOMArray& aListOfNodes, - nsCOMArray& outArray) +void +nsHTMLEditor::GetListAndTableParents(StartOrEnd aStartOrEnd, + nsTArray>& aNodeList, + nsTArray>& outArray) { - int32_t listCount = aListOfNodes.Count(); - NS_ENSURE_TRUE(listCount > 0, NS_ERROR_FAILURE); // no empty lists, please + MOZ_ASSERT(aNodeList.Length()); - // build up list of parents of first (or last) node in list - // that are either lists, or tables. - int32_t idx = 0; - if (aEnd) idx = listCount-1; + // Build up list of parents of first (or last) node in list that are either + // lists, or tables. + int32_t idx = aStartOrEnd == StartOrEnd::end ? aNodeList.Length() - 1 : 0; - nsCOMPtr pNode = aListOfNodes[idx]; - while (pNode) - { - if (nsHTMLEditUtils::IsList(pNode) || nsHTMLEditUtils::IsTable(pNode)) - { - NS_ENSURE_TRUE(outArray.AppendObject(pNode), NS_ERROR_FAILURE); + for (nsCOMPtr node = aNodeList[idx]; node; + node = node->GetParentNode()) { + if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsTable(node)) { + outArray.AppendElement(*node->AsElement()); } - nsCOMPtr parent; - pNode->GetParentNode(getter_AddRefs(parent)); - pNode = parent; } - return NS_OK; } -nsresult -nsHTMLEditor::DiscoverPartialListsAndTables(nsCOMArray& aPasteNodes, - nsCOMArray& aListsAndTables, - int32_t *outHighWaterMark) +int32_t +nsHTMLEditor::DiscoverPartialListsAndTables(nsTArray>& aPasteNodes, + nsTArray>& aListsAndTables) { - NS_ENSURE_TRUE(outHighWaterMark, NS_ERROR_NULL_POINTER); + int32_t ret = -1; + int32_t listAndTableParents = aListsAndTables.Length(); - *outHighWaterMark = -1; - int32_t listAndTableParents = aListsAndTables.Count(); - - // scan insertion list for table elements (other than table). - int32_t listCount = aPasteNodes.Count(); - int32_t j; - for (j=0; j curNode = aPasteNodes[j]; - - NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE); - if (nsHTMLEditUtils::IsTableElement(curNode) && !nsHTMLEditUtils::IsTable(curNode)) - { - nsCOMPtr theTable = GetTableParent(curNode); - if (theTable) - { - int32_t indexT = aListsAndTables.IndexOf(theTable); - if (indexT >= 0) - { - *outHighWaterMark = indexT; - if (*outHighWaterMark == listAndTableParents-1) break; + // Scan insertion list for table elements (other than table). + for (auto& curNode : aPasteNodes) { + if (nsHTMLEditUtils::IsTableElement(curNode) && + !curNode->IsHTMLElement(nsGkAtoms::table)) { + nsCOMPtr table = curNode->GetParentElement(); + while (table && !table->IsHTMLElement(nsGkAtoms::table)) { + table = table->GetParentElement(); + } + if (table) { + int32_t idx = aListsAndTables.IndexOf(table); + if (idx == -1) { + return ret; } - else - { - break; + ret = idx; + if (ret == listAndTableParents - 1) { + return ret; } } } - if (nsHTMLEditUtils::IsListItem(curNode)) - { - nsCOMPtr theList = GetListParent(curNode); - if (theList) - { - int32_t indexL = aListsAndTables.IndexOf(theList); - if (indexL >= 0) - { - *outHighWaterMark = indexL; - if (*outHighWaterMark == listAndTableParents-1) break; + if (nsHTMLEditUtils::IsListItem(curNode)) { + nsCOMPtr list = curNode->GetParentElement(); + while (list && !nsHTMLEditUtils::IsList(list)) { + list = list->GetParentElement(); + } + if (list) { + int32_t idx = aListsAndTables.IndexOf(list); + if (idx == -1) { + return ret; } - else - { - break; + ret = idx; + if (ret == listAndTableParents - 1) { + return ret; } } } } - return NS_OK; + return ret; } -nsresult -nsHTMLEditor::ScanForListAndTableStructure( bool aEnd, - nsCOMArray& aNodes, - nsIDOMNode *aListOrTable, - nsCOMPtr *outReplaceNode) +nsINode* +nsHTMLEditor::ScanForListAndTableStructure(StartOrEnd aStartOrEnd, + nsTArray>& aNodes, + Element& aListOrTable) { - NS_ENSURE_TRUE(aListOrTable, NS_ERROR_NULL_POINTER); - NS_ENSURE_TRUE(outReplaceNode, NS_ERROR_NULL_POINTER); - - *outReplaceNode = 0; + // Look upward from first/last paste node for a piece of this list/table + int32_t idx = aStartOrEnd == StartOrEnd::end ? aNodes.Length() - 1 : 0; + bool isList = nsHTMLEditUtils::IsList(&aListOrTable); - // look upward from first/last paste node for a piece of this list/table - int32_t listCount = aNodes.Count(), idx = 0; - if (aEnd) idx = listCount-1; - bool bList = nsHTMLEditUtils::IsList(aListOrTable); - - nsCOMPtr pNode = aNodes[idx]; - nsCOMPtr originalNode = pNode; - while (pNode) - { - if ((bList && nsHTMLEditUtils::IsListItem(pNode)) || - (!bList && (nsHTMLEditUtils::IsTableElement(pNode) && !nsHTMLEditUtils::IsTable(pNode)))) - { - nsCOMPtr structureNode; - if (bList) structureNode = GetListParent(pNode); - else structureNode = GetTableParent(pNode); - if (structureNode == aListOrTable) - { - if (bList) - *outReplaceNode = structureNode; - else - *outReplaceNode = pNode; - break; + for (nsCOMPtr node = aNodes[idx]; node; + node = node->GetParentNode()) { + if ((isList && nsHTMLEditUtils::IsListItem(node)) || + (!isList && nsHTMLEditUtils::IsTableElement(node) && + !node->IsHTMLElement(nsGkAtoms::table))) { + nsCOMPtr structureNode = node->GetParentElement(); + if (isList) { + while (structureNode && !nsHTMLEditUtils::IsList(structureNode)) { + structureNode = structureNode->GetParentElement(); + } + } else { + while (structureNode && + !structureNode->IsHTMLElement(nsGkAtoms::table)) { + structureNode = structureNode->GetParentElement(); + } + } + if (structureNode == &aListOrTable) { + if (isList) { + return structureNode; + } + return node; } } - nsCOMPtr parent; - pNode->GetParentNode(getter_AddRefs(parent)); - pNode = parent; } - return NS_OK; + return nullptr; } -nsresult -nsHTMLEditor::ReplaceOrphanedStructure(bool aEnd, - nsCOMArray& aNodeArray, - nsCOMArray& aListAndTableArray, +void +nsHTMLEditor::ReplaceOrphanedStructure(StartOrEnd aStartOrEnd, + nsTArray>& aNodeArray, + nsTArray>& aListAndTableArray, int32_t aHighWaterMark) { - nsCOMPtr curNode = aListAndTableArray[aHighWaterMark]; - NS_ENSURE_TRUE(curNode, NS_ERROR_NULL_POINTER); + OwningNonNull curNode = aListAndTableArray[aHighWaterMark]; - nsCOMPtr replaceNode, originalNode; + // Find substructure of list or table that must be included in paste. + nsCOMPtr replaceNode = + ScanForListAndTableStructure(aStartOrEnd, aNodeArray, curNode); - // find substructure of list or table that must be included in paste. - nsresult rv = ScanForListAndTableStructure(aEnd, aNodeArray, - curNode, address_of(replaceNode)); - NS_ENSURE_SUCCESS(rv, rv); - - // if we found substructure, paste it instead of its descendants - if (replaceNode) - { - // postprocess list to remove any descendants of this node - // so that we don't insert them twice. - nsCOMPtr endpoint; - do - { - endpoint = GetArrayEndpoint(aEnd, aNodeArray); - if (!endpoint) break; - if (nsEditorUtils::IsDescendantOf(endpoint, replaceNode)) - aNodeArray.RemoveObject(endpoint); - else - break; - } while(endpoint); - - // now replace the removed nodes with the structural parent - if (aEnd) aNodeArray.AppendObject(replaceNode); - else aNodeArray.InsertObjectAt(replaceNode, 0); + if (!replaceNode) { + return; + } + + // If we found substructure, paste it instead of its descendants. + // Postprocess list to remove any descendants of this node so that we don't + // insert them twice. + while (aNodeArray.Length()) { + int32_t idx = aStartOrEnd == StartOrEnd::start ? 0 + : aNodeArray.Length() - 1; + OwningNonNull endpoint = aNodeArray[idx]; + if (!nsEditorUtils::IsDescendantOf(endpoint, replaceNode)) { + break; + } + aNodeArray.RemoveElementAt(idx); + } + + // Now replace the removed nodes with the structural parent + if (aStartOrEnd == StartOrEnd::end) { + aNodeArray.AppendElement(*replaceNode); + } else { + aNodeArray.InsertElementAt(0, *replaceNode); } - return NS_OK; -} - -nsIDOMNode* nsHTMLEditor::GetArrayEndpoint(bool aEnd, - nsCOMArray& aNodeArray) -{ - int32_t listCount = aNodeArray.Count(); - if (listCount <= 0) { - return nullptr; - } - - if (aEnd) { - return aNodeArray[listCount-1]; - } - - return aNodeArray[0]; } diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index 2807f3f836ef..c4f4d0b692bd 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -603,21 +603,19 @@ protected: int32_t aEndOffset); nsresult CreateTagStack(nsTArray &aTagStack, nsIDOMNode *aNode); - nsresult GetListAndTableParents( bool aEnd, - nsCOMArray& aListOfNodes, - nsCOMArray& outArray); - nsresult DiscoverPartialListsAndTables(nsCOMArray& aPasteNodes, - nsCOMArray& aListsAndTables, - int32_t *outHighWaterMark); - nsresult ScanForListAndTableStructure(bool aEnd, - nsCOMArray& aNodes, - nsIDOMNode *aListOrTable, - nsCOMPtr *outReplaceNode); - nsresult ReplaceOrphanedStructure( bool aEnd, - nsCOMArray& aNodeArray, - nsCOMArray& aListAndTableArray, - int32_t aHighWaterMark); - nsIDOMNode* GetArrayEndpoint(bool aEnd, nsCOMArray& aNodeArray); + enum class StartOrEnd { start, end }; + void GetListAndTableParents(StartOrEnd aStartOrEnd, + nsTArray>& aNodeList, + nsTArray>& outArray); + int32_t DiscoverPartialListsAndTables(nsTArray>& aPasteNodes, + nsTArray>& aListsAndTables); + nsINode* ScanForListAndTableStructure(StartOrEnd aStartOrEnd, + nsTArray>& aNodes, + mozilla::dom::Element& aListOrTable); + void ReplaceOrphanedStructure(StartOrEnd aStartOrEnd, + nsTArray>& aNodeArray, + nsTArray>& aListAndTableArray, + int32_t aHighWaterMark); /* small utility routine to test if a break node is visible to user */ bool IsVisBreak(nsINode* aNode); From 5b43d87861d073c78cb25ad84997e2d2bbd36dfe Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:17 +0300 Subject: [PATCH 139/241] Bug 1154701 part 4 - Switch nsHTMLEditor::mContentFilters to nsTArray; r=ehsan --- editor/libeditor/nsHTMLDataTransfer.cpp | 31 +++++++++++-------------- editor/libeditor/nsHTMLEditor.h | 2 +- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/editor/libeditor/nsHTMLDataTransfer.cpp b/editor/libeditor/nsHTMLDataTransfer.cpp index 2a93cc613403..a72ecd0a7ab9 100644 --- a/editor/libeditor/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/nsHTMLDataTransfer.cpp @@ -694,26 +694,25 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, return mRules->DidDoAction(selection, &ruleInfo, rv); } -nsresult +NS_IMETHODIMP nsHTMLEditor::AddInsertionListener(nsIContentFilter *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); // don't let a listener be added more than once - if (mContentFilters.IndexOfObject(aListener) == -1) - { - NS_ENSURE_TRUE(mContentFilters.AppendObject(aListener), NS_ERROR_FAILURE); + if (!mContentFilters.Contains(aListener)) { + mContentFilters.AppendElement(*aListener); } return NS_OK; } -nsresult +NS_IMETHODIMP nsHTMLEditor::RemoveInsertionListener(nsIContentFilter *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE); - NS_ENSURE_TRUE(mContentFilters.RemoveObject(aListener), NS_ERROR_FAILURE); + mContentFilters.RemoveElement(aListener); return NS_OK; } @@ -733,17 +732,15 @@ nsHTMLEditor::DoContentFilterCallback(const nsAString &aFlavor, { *aDoContinue = true; - int32_t i; - nsIContentFilter *listener; - for (i=0; i < mContentFilters.Count() && *aDoContinue; i++) - { - listener = (nsIContentFilter *)mContentFilters[i]; - if (listener) - listener->NotifyOfInsertion(aFlavor, nullptr, sourceDoc, - aWillDeleteSelection, aFragmentAsNode, - aFragStartNode, aFragStartOffset, - aFragEndNode, aFragEndOffset, - aTargetNode, aTargetOffset, aDoContinue); + for (auto& listener : mContentFilters) { + if (!*aDoContinue) { + break; + } + listener->NotifyOfInsertion(aFlavor, nullptr, sourceDoc, + aWillDeleteSelection, aFragmentAsNode, + aFragStartNode, aFragStartOffset, + aFragEndNode, aFragEndOffset, aTargetNode, + aTargetOffset, aDoContinue); } return NS_OK; diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index c4f4d0b692bd..99d47abff1f7 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -760,7 +760,7 @@ protected: // Data members protected: - nsCOMArray mContentFilters; + nsTArray> mContentFilters; nsRefPtr mTypeInState; From 8dcd5863c0517e530e892cf0d07a9431ca889585 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:17 +0300 Subject: [PATCH 140/241] Bug 1154701 part 5 - Switch nsHTMLEditor::objectResizeEventListeners to nsTArray; r=ehsan --- editor/libeditor/nsHTMLEditor.cpp | 2 +- editor/libeditor/nsHTMLEditor.h | 3 +-- editor/libeditor/nsHTMLObjectResizer.cpp | 34 +++++++----------------- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/editor/libeditor/nsHTMLEditor.cpp b/editor/libeditor/nsHTMLEditor.cpp index c881907d2323..d732088b320e 100644 --- a/editor/libeditor/nsHTMLEditor.cpp +++ b/editor/libeditor/nsHTMLEditor.cpp @@ -195,7 +195,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLEditor, nsPlaintextEdito NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMouseMotionListenerP) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectionListenerP) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizeEventListenerP) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(objectResizeEventListeners) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObjectResizeEventListeners) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAbsolutelyPositionedObject) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGrabber) diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index 99d47abff1f7..d6b0636c4a00 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -7,7 +7,6 @@ #define nsHTMLEditor_h__ #include "nsCOMPtr.h" -#include "nsCOMArray.h" #include "nsPlaintextEditor.h" #include "nsIEditor.h" #include "nsIHTMLEditor.h" @@ -850,7 +849,7 @@ protected: nsCOMPtr mSelectionListenerP; nsCOMPtr mResizeEventListenerP; - nsCOMArray objectResizeEventListeners; + nsTArray> mObjectResizeEventListeners; int32_t mOriginalX; int32_t mOriginalY; diff --git a/editor/libeditor/nsHTMLObjectResizer.cpp b/editor/libeditor/nsHTMLObjectResizer.cpp index 96cca62f4d48..3948aec4d3aa 100644 --- a/editor/libeditor/nsHTMLObjectResizer.cpp +++ b/editor/libeditor/nsHTMLObjectResizer.cpp @@ -499,14 +499,8 @@ nsresult nsHTMLEditor::StartResizing(nsIDOMElement *aHandle) { // First notify the listeners if any - int32_t listenersCount = objectResizeEventListeners.Count(); - if (listenersCount) { - nsCOMPtr listener; - int32_t index; - for (index = 0; index < listenersCount; index++) { - listener = objectResizeEventListeners[index]; - listener->OnStartResizing(static_cast(GetAsDOMNode(mResizedObject))); - } + for (auto& listener : mObjectResizeEventListeners) { + listener->OnStartResizing(static_cast(GetAsDOMNode(mResizedObject))); } mIsResizing = true; @@ -976,16 +970,10 @@ nsHTMLEditor::SetFinalSize(int32_t aX, int32_t aY) EmptyString()); } // finally notify the listeners if any - int32_t listenersCount = objectResizeEventListeners.Count(); - if (listenersCount) { - nsCOMPtr listener; - int32_t index; - for (index = 0; index < listenersCount; index++) { - listener = objectResizeEventListeners[index]; - listener->OnEndResizing(static_cast(GetAsDOMNode(mResizedObject)), - mResizedObjectWidth, mResizedObjectHeight, - width, height); - } + for (auto& listener : mObjectResizeEventListeners) { + listener->OnEndResizing(static_cast(GetAsDOMNode(mResizedObject)), + mResizedObjectWidth, mResizedObjectHeight, width, + height); } // keep track of that size @@ -1021,14 +1009,13 @@ NS_IMETHODIMP nsHTMLEditor::AddObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener) { NS_ENSURE_ARG_POINTER(aListener); - if (objectResizeEventListeners.Count() && - objectResizeEventListeners.IndexOf(aListener) != -1) { + if (mObjectResizeEventListeners.Contains(aListener)) { /* listener already registered */ NS_ASSERTION(false, "trying to register an already registered object resize event listener"); return NS_OK; } - objectResizeEventListeners.AppendObject(aListener); + mObjectResizeEventListeners.AppendElement(*aListener); return NS_OK; } @@ -1036,14 +1023,13 @@ NS_IMETHODIMP nsHTMLEditor::RemoveObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener) { NS_ENSURE_ARG_POINTER(aListener); - if (!objectResizeEventListeners.Count() || - objectResizeEventListeners.IndexOf(aListener) == -1) { + if (!mObjectResizeEventListeners.Contains(aListener)) { /* listener was not registered */ NS_ASSERTION(false, "trying to remove an object resize event listener that was not already registered"); return NS_OK; } - objectResizeEventListeners.RemoveObject(aListener); + mObjectResizeEventListeners.RemoveElement(aListener); return NS_OK; } From 93ed436b483db5cda6f424209251e00c8b6782ed Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:17 +0300 Subject: [PATCH 141/241] Bug 1154701 part 6 - Clean up nsHTMLEditor::SetInlinePropertyOnNodeImpl; r=ehsan --- editor/libeditor/nsHTMLEditor.h | 6 +- editor/libeditor/nsHTMLEditorStyle.cpp | 82 ++++++++++++-------------- 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index d6b0636c4a00..510e67c7e37a 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -960,10 +960,10 @@ private: nsIAtom* aProperty, const nsAString* aAttribute, const nsAString* aValue); - nsresult SetInlinePropertyOnNodeImpl(nsIContent* aNode, - nsIAtom* aProperty, + nsresult SetInlinePropertyOnNodeImpl(nsIContent& aNode, + nsIAtom& aProperty, const nsAString* aAttribute, - const nsAString* aValue); + const nsAString& aValue); typedef enum { eInserted, eAppended } InsertedOrAppended; void DoContentInserted(nsIDocument* aDocument, nsIContent* aContainer, nsIContent* aChild, int32_t aIndexInContainer, diff --git a/editor/libeditor/nsHTMLEditorStyle.cpp b/editor/libeditor/nsHTMLEditorStyle.cpp index af8bd880aa05..21a1c976811e 100644 --- a/editor/libeditor/nsHTMLEditorStyle.cpp +++ b/editor/libeditor/nsHTMLEditorStyle.cpp @@ -381,36 +381,32 @@ nsHTMLEditor::SetInlinePropertyOnTextNode(Text& aText, nsresult -nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode, - nsIAtom* aProperty, +nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode, + nsIAtom& aProperty, const nsAString* aAttribute, - const nsAString* aValue) + const nsAString& aValue) { - MOZ_ASSERT(aNode && aProperty); - MOZ_ASSERT(aValue); - nsCOMPtr attrAtom = aAttribute ? do_GetAtom(*aAttribute) : nullptr; // If this is an element that can't be contained in a span, we have to // recurse to its children. - if (!TagCanContain(*nsGkAtoms::span, *aNode)) { - if (aNode->HasChildren()) { - nsCOMArray arrayOfNodes; + if (!TagCanContain(*nsGkAtoms::span, aNode)) { + if (aNode.HasChildren()) { + nsTArray> arrayOfNodes; // Populate the list. - for (nsIContent* child = aNode->GetFirstChild(); + for (nsCOMPtr child = aNode.GetFirstChild(); child; child = child->GetNextSibling()) { if (IsEditable(child) && !IsEmptyTextNode(this, child)) { - arrayOfNodes.AppendObject(child); + arrayOfNodes.AppendElement(*child); } } // Then loop through the list, set the property on each node. - int32_t listCount = arrayOfNodes.Count(); - for (int32_t j = 0; j < listCount; ++j) { - nsresult rv = SetInlinePropertyOnNode(arrayOfNodes[j], aProperty, - aAttribute, aValue); + for (auto& node : arrayOfNodes) { + nsresult rv = SetInlinePropertyOnNode(node, &aProperty, aAttribute, + &aValue); NS_ENSURE_SUCCESS(rv, rv); } } @@ -419,36 +415,36 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode, // First check if there's an adjacent sibling we can put our node into. nsresult res; - nsCOMPtr previousSibling = GetPriorHTMLSibling(aNode); - nsCOMPtr nextSibling = GetNextHTMLSibling(aNode); - if (IsSimpleModifiableNode(previousSibling, aProperty, aAttribute, aValue)) { - res = MoveNode(aNode, previousSibling, -1); + nsCOMPtr previousSibling = GetPriorHTMLSibling(&aNode); + nsCOMPtr nextSibling = GetNextHTMLSibling(&aNode); + if (IsSimpleModifiableNode(previousSibling, &aProperty, aAttribute, &aValue)) { + res = MoveNode(&aNode, previousSibling, -1); NS_ENSURE_SUCCESS(res, res); - if (IsSimpleModifiableNode(nextSibling, aProperty, aAttribute, aValue)) { + if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) { res = JoinNodes(*previousSibling, *nextSibling); NS_ENSURE_SUCCESS(res, res); } return NS_OK; } - if (IsSimpleModifiableNode(nextSibling, aProperty, aAttribute, aValue)) { - res = MoveNode(aNode, nextSibling, 0); + if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) { + res = MoveNode(&aNode, nextSibling, 0); NS_ENSURE_SUCCESS(res, res); return NS_OK; } - // don't need to do anything if property already set on node - if (mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty, aAttribute)) { + // Don't need to do anything if property already set on node + if (mHTMLCSSUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) { if (mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet( - aNode, aProperty, aAttribute, *aValue, nsHTMLCSSUtils::eComputed)) { + &aNode, &aProperty, aAttribute, aValue, nsHTMLCSSUtils::eComputed)) { return NS_OK; } - } else if (IsTextPropertySetByContent(aNode, aProperty, - aAttribute, aValue)) { + } else if (IsTextPropertySetByContent(&aNode, &aProperty, + aAttribute, &aValue)) { return NS_OK; } bool useCSS = (IsCSSEnabled() && - mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty, aAttribute)) || + mHTMLCSSUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) || // bgcolor is always done using CSS aAttribute->EqualsLiteral("bgcolor"); @@ -456,33 +452,33 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode, nsCOMPtr tmp; // We only add style="" to s with no attributes (bug 746515). If we // don't have one, we need to make one. - if (aNode->IsHTMLElement(nsGkAtoms::span) && - !aNode->AsElement()->GetAttrCount()) { - tmp = aNode->AsElement(); + if (aNode.IsHTMLElement(nsGkAtoms::span) && + !aNode.AsElement()->GetAttrCount()) { + tmp = aNode.AsElement(); } else { - tmp = InsertContainerAbove(aNode, nsGkAtoms::span); + tmp = InsertContainerAbove(&aNode, nsGkAtoms::span); NS_ENSURE_STATE(tmp); } // Add the CSS styles corresponding to the HTML style request int32_t count; res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(tmp->AsDOMNode(), - aProperty, aAttribute, - aValue, &count, false); + &aProperty, aAttribute, + &aValue, &count, false); NS_ENSURE_SUCCESS(res, res); return NS_OK; } // is it already the right kind of node, but with wrong attribute? - if (aNode->IsHTMLElement(aProperty)) { + if (aNode.IsHTMLElement(&aProperty)) { // Just set the attribute on it. - nsCOMPtr elem = do_QueryInterface(aNode); - return SetAttribute(elem, *aAttribute, *aValue); + nsCOMPtr elem = do_QueryInterface(&aNode); + return SetAttribute(elem, *aAttribute, aValue); } // ok, chuck it in its very own container - nsCOMPtr tmp = InsertContainerAbove(aNode, aProperty, attrAtom, - aValue); + nsCOMPtr tmp = InsertContainerAbove(&aNode, &aProperty, attrAtom, + &aValue); NS_ENSURE_STATE(tmp); return NS_OK; @@ -527,8 +523,8 @@ nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode, if (aNode->GetParentNode()) { // The node is still where it was - return SetInlinePropertyOnNodeImpl(aNode, aProperty, - aAttribute, aValue); + return SetInlinePropertyOnNodeImpl(*aNode, *aProperty, + aAttribute, *aValue); } // It's vanished. Use the old siblings for reference to construct a @@ -550,8 +546,8 @@ nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode, int32_t nodesToSetCount = nodesToSet.Count(); for (int32_t k = 0; k < nodesToSetCount; k++) { - res = SetInlinePropertyOnNodeImpl(nodesToSet[k], aProperty, - aAttribute, aValue); + res = SetInlinePropertyOnNodeImpl(*nodesToSet[k], *aProperty, + aAttribute, *aValue); NS_ENSURE_SUCCESS(res, res); } From 8aaf028d7515bdb51cf258045dc45384e61bc2e4 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 142/241] Bug 1154701 part 7 - Clean up nsHTMLEditor::SetInlineProperty; r=ehsan --- editor/libeditor/nsHTMLEditorStyle.cpp | 58 ++++++++++---------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/editor/libeditor/nsHTMLEditorStyle.cpp b/editor/libeditor/nsHTMLEditorStyle.cpp index 21a1c976811e..b7a768f3f09f 100644 --- a/editor/libeditor/nsHTMLEditorStyle.cpp +++ b/editor/libeditor/nsHTMLEditorStyle.cpp @@ -109,23 +109,20 @@ NS_IMETHODIMP nsHTMLEditor::RemoveAllDefaultProperties() NS_IMETHODIMP -nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty, +nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty, const nsAString& aAttribute, const nsAString& aValue) { - if (!aProperty) { - return NS_ERROR_NULL_POINTER; - } - if (!mRules) { - return NS_ERROR_NOT_INITIALIZED; - } + NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER); + NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED); + nsCOMPtr kungFuDeathGrip(mRules); ForceCompositionEnd(); nsRefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); if (selection->Collapsed()) { - // manipulating text attributes on a collapsed selection only sets state + // Manipulating text attributes on a collapsed selection only sets state // for the next text insertion mTypeInState->SetProp(aProperty, aAttribute, aValue); return NS_OK; @@ -139,21 +136,20 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty, bool cancel, handled; nsTextRulesInfo ruleInfo(EditAction::setTextProperty); // Protect the edit rules object from dying - nsCOMPtr kungFuDeathGrip(mRules); nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled); NS_ENSURE_SUCCESS(res, res); if (!cancel && !handled) { - // loop thru the ranges in the selection + // Loop through the ranges in the selection uint32_t rangeCount = selection->RangeCount(); - for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) { + for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; rangeIdx++) { nsRefPtr range = selection->GetRangeAt(rangeIdx); - // adjust range to include any ancestors whose children are entirely + // Adjust range to include any ancestors whose children are entirely // selected res = PromoteInlineRange(range); NS_ENSURE_SUCCESS(res, res); - // check for easy case: both range endpoints in same text node + // Check for easy case: both range endpoints in same text node nsCOMPtr startNode = range->GetStartParent(); nsCOMPtr endNode = range->GetEndParent(); if (startNode && startNode == endNode && startNode->GetAsText()) { @@ -176,31 +172,26 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty, // (since doing operations on the document during iteration would perturb // the iterator). - nsCOMPtr iter = - do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res); - NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE); + OwningNonNull iter = NS_NewContentSubtreeIterator(); - nsCOMArray arrayOfNodes; + nsTArray> arrayOfNodes; - // iterate range and build up array + // Iterate range and build up array res = iter->Init(range); // Init returns an error if there are no nodes in range. This can easily // happen with the subtree iterator if the selection doesn't contain any // *whole* nodes. if (NS_SUCCEEDED(res)) { - nsCOMPtr node; for (; !iter->IsDone(); iter->Next()) { - node = do_QueryInterface(iter->GetCurrentNode()); - NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); + OwningNonNull node = *iter->GetCurrentNode(); - if (IsEditable(node)) { - arrayOfNodes.AppendObject(node); + if (node->IsContent() && IsEditable(node)) { + arrayOfNodes.AppendElement(*node->AsContent()); } } } - // first check the start parent of the range to see if it needs to - // be separately handled (it does if it's a text node, due to how the + // First check the start parent of the range to see if it needs to be + // separately handled (it does if it's a text node, due to how the // subtree iterator works - it will not have reported it). if (startNode && startNode->GetAsText() && IsEditable(startNode)) { res = SetInlinePropertyOnTextNode(*startNode->GetAsText(), @@ -210,17 +201,14 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty, NS_ENSURE_SUCCESS(res, res); } - // then loop through the list, set the property on each node - int32_t listCount = arrayOfNodes.Count(); - int32_t j; - for (j = 0; j < listCount; j++) { - res = SetInlinePropertyOnNode(arrayOfNodes[j], aProperty, - &aAttribute, &aValue); + // Then loop through the list, set the property on each node + for (auto& node : arrayOfNodes) { + res = SetInlinePropertyOnNode(node, aProperty, &aAttribute, &aValue); NS_ENSURE_SUCCESS(res, res); } - // last check the end parent of the range to see if it needs to - // be separately handled (it does if it's a text node, due to how the + // Last check the end parent of the range to see if it needs to be + // separately handled (it does if it's a text node, due to how the // subtree iterator works - it will not have reported it). if (endNode && endNode->GetAsText() && IsEditable(endNode)) { res = SetInlinePropertyOnTextNode(*endNode->GetAsText(), 0, @@ -231,7 +219,7 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty, } } if (!cancel) { - // post-process + // Post-process return mRules->DidDoAction(selection, &ruleInfo, res); } return NS_OK; From 71efee461ee4b71aeb5130075374199448b074b7 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 143/241] Bug 1154701 part 8 - Clean up nsHTMLEditor::SetInlinePropertyOnNode; r=ehsan --- editor/libeditor/nsHTMLEditRules.cpp | 6 ++- editor/libeditor/nsHTMLEditor.h | 10 ++-- editor/libeditor/nsHTMLEditorStyle.cpp | 69 ++++++++------------------ 3 files changed, 29 insertions(+), 56 deletions(-) diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index d9cc2b96f351..a70ea5fe1581 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -4562,8 +4562,10 @@ nsHTMLEditRules::CreateStyleForInsertText(Selection* aSelection, while (item) { NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->SetInlinePropertyOnNode(node, item->tag, &item->attr, - &item->value); + nsCOMPtr content = do_QueryInterface(node); + NS_ENSURE_STATE(content || !node); + res = mHTMLEditor->SetInlinePropertyOnNode(*content, *item->tag, + &item->attr, item->value); NS_ENSURE_SUCCESS(res, res); item = mHTMLEditor->mTypeInState->TakeSetProperty(); } diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index 510e67c7e37a..06ef330c9c73 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -651,14 +651,10 @@ protected: nsIAtom& aProperty, const nsAString* aAttribute, const nsAString& aValue); - nsresult SetInlinePropertyOnNode( nsIDOMNode *aNode, - nsIAtom *aProperty, - const nsAString *aAttribute, - const nsAString *aValue); - nsresult SetInlinePropertyOnNode(nsIContent* aNode, - nsIAtom* aProperty, + nsresult SetInlinePropertyOnNode(nsIContent& aNode, + nsIAtom& aProperty, const nsAString* aAttribute, - const nsAString* aValue); + const nsAString& aValue); nsresult PromoteInlineRange(nsRange* aRange); nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange* aRange); diff --git a/editor/libeditor/nsHTMLEditorStyle.cpp b/editor/libeditor/nsHTMLEditorStyle.cpp index b7a768f3f09f..7aaf054e41d2 100644 --- a/editor/libeditor/nsHTMLEditorStyle.cpp +++ b/editor/libeditor/nsHTMLEditorStyle.cpp @@ -203,7 +203,7 @@ nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty, // Then loop through the list, set the property on each node for (auto& node : arrayOfNodes) { - res = SetInlinePropertyOnNode(node, aProperty, &aAttribute, &aValue); + res = SetInlinePropertyOnNode(*node, *aProperty, &aAttribute, aValue); NS_ENSURE_SUCCESS(res, res); } @@ -364,7 +364,7 @@ nsHTMLEditor::SetInlinePropertyOnTextNode(Text& aText, } // Reparent the node inside inline node with appropriate {attribute,value} - return SetInlinePropertyOnNode(text, &aProperty, aAttribute, &aValue); + return SetInlinePropertyOnNode(*text, aProperty, aAttribute, aValue); } @@ -393,8 +393,8 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode, // Then loop through the list, set the property on each node. for (auto& node : arrayOfNodes) { - nsresult rv = SetInlinePropertyOnNode(node, &aProperty, aAttribute, - &aValue); + nsresult rv = SetInlinePropertyOnNode(node, aProperty, aAttribute, + aValue); NS_ENSURE_SUCCESS(rv, rv); } } @@ -474,45 +474,23 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode, nsresult -nsHTMLEditor::SetInlinePropertyOnNode(nsIDOMNode *aNode, - nsIAtom *aProperty, - const nsAString *aAttribute, - const nsAString *aValue) -{ - // Before setting the property, we remove it if it's already set. - // RemoveStyleInside might remove the node we're looking at or some of its - // descendants, however, in which case we want to set the property on - // whatever wound up in its place. We have to save the original siblings and - // parent to figure this out. - NS_ENSURE_TRUE(aNode && aProperty, NS_ERROR_NULL_POINTER); - - nsCOMPtr node = do_QueryInterface(aNode); - NS_ENSURE_STATE(node); - - return SetInlinePropertyOnNode(node, aProperty, aAttribute, aValue); -} - -nsresult -nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode, - nsIAtom* aProperty, +nsHTMLEditor::SetInlinePropertyOnNode(nsIContent& aNode, + nsIAtom& aProperty, const nsAString* aAttribute, - const nsAString* aValue) + const nsAString& aValue) { - MOZ_ASSERT(aNode); - MOZ_ASSERT(aProperty); + nsCOMPtr previousSibling = aNode.GetPreviousSibling(), + nextSibling = aNode.GetNextSibling(); + NS_ENSURE_STATE(aNode.GetParentNode()); + OwningNonNull parent = *aNode.GetParentNode(); - nsCOMPtr previousSibling = aNode->GetPreviousSibling(), - nextSibling = aNode->GetNextSibling(); - nsCOMPtr parent = aNode->GetParentNode(); - NS_ENSURE_STATE(parent); - - nsresult res = RemoveStyleInside(aNode->AsDOMNode(), aProperty, aAttribute); + nsresult res = RemoveStyleInside(aNode.AsDOMNode(), &aProperty, aAttribute); NS_ENSURE_SUCCESS(res, res); - if (aNode->GetParentNode()) { + if (aNode.GetParentNode()) { // The node is still where it was - return SetInlinePropertyOnNodeImpl(*aNode, *aProperty, - aAttribute, *aValue); + return SetInlinePropertyOnNodeImpl(aNode, aProperty, + aAttribute, aValue); } // It's vanished. Use the old siblings for reference to construct a @@ -522,20 +500,17 @@ nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode, (nextSibling && nextSibling->GetParentNode() != parent)) { return NS_ERROR_UNEXPECTED; } - nsCOMArray nodesToSet; + nsTArray> nodesToSet; nsCOMPtr cur = previousSibling ? previousSibling->GetNextSibling() : parent->GetFirstChild(); - while (cur && cur != nextSibling) { + for (; cur && cur != nextSibling; cur = cur->GetNextSibling()) { if (IsEditable(cur)) { - nodesToSet.AppendObject(cur); + nodesToSet.AppendElement(*cur); } - cur = cur->GetNextSibling(); } - int32_t nodesToSetCount = nodesToSet.Count(); - for (int32_t k = 0; k < nodesToSetCount; k++) { - res = SetInlinePropertyOnNodeImpl(*nodesToSet[k], *aProperty, - aAttribute, *aValue); + for (auto& node : nodesToSet) { + res = SetInlinePropertyOnNodeImpl(node, aProperty, aAttribute, aValue); NS_ENSURE_SUCCESS(res, res); } @@ -1400,8 +1375,8 @@ nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty, // "inverting" the style mHTMLCSSUtils->IsCSSInvertible(*aProperty, aAttribute)) { NS_NAMED_LITERAL_STRING(value, "-moz-editor-invert-value"); - SetInlinePropertyOnNode(node->AsContent(), aProperty, - aAttribute, &value); + SetInlinePropertyOnNode(*node->AsContent(), *aProperty, + aAttribute, value); } } } From 62af180b5bd2729862a40102f5808540ae7970a8 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 144/241] Bug 1154701 part 9 - Clean up nsHTMLEditor::RelativeFontChange; r=ehsan --- editor/libeditor/nsHTMLEditor.h | 3 +- editor/libeditor/nsHTMLEditorStyle.cpp | 159 +++++++++++-------------- 2 files changed, 69 insertions(+), 93 deletions(-) diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h index 06ef330c9c73..d20da0716520 100644 --- a/editor/libeditor/nsHTMLEditor.h +++ b/editor/libeditor/nsHTMLEditor.h @@ -634,7 +634,8 @@ protected: nsresult InsertBasicBlock(const nsAString & aBlockType); /* increase/decrease the font size of selection */ - nsresult RelativeFontChange( int32_t aSizeChange); + enum class FontSize { incr, decr }; + nsresult RelativeFontChange(FontSize aDir); /* helper routines for font size changing */ nsresult RelativeFontChangeOnTextNode( int32_t aSizeChange, diff --git a/editor/libeditor/nsHTMLEditorStyle.cpp b/editor/libeditor/nsHTMLEditorStyle.cpp index 7aaf054e41d2..c85e4f5f8662 100644 --- a/editor/libeditor/nsHTMLEditorStyle.cpp +++ b/editor/libeditor/nsHTMLEditorStyle.cpp @@ -10,7 +10,6 @@ #include "nsAString.h" #include "nsAttrName.h" #include "nsAutoPtr.h" -#include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsCaseTreatment.h" #include "nsComponentManagerUtils.h" @@ -1392,150 +1391,126 @@ nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty, NS_IMETHODIMP nsHTMLEditor::IncreaseFontSize() { - return RelativeFontChange(1); + return RelativeFontChange(FontSize::incr); } NS_IMETHODIMP nsHTMLEditor::DecreaseFontSize() { - return RelativeFontChange(-1); + return RelativeFontChange(FontSize::decr); } nsresult -nsHTMLEditor::RelativeFontChange( int32_t aSizeChange) +nsHTMLEditor::RelativeFontChange(FontSize aDir) { - // Can only change font size by + or - 1 - if ( !( (aSizeChange==1) || (aSizeChange==-1) ) ) - return NS_ERROR_ILLEGAL_VALUE; - ForceCompositionEnd(); - // Get the selection + // Get the selection nsRefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE); - // Is the selection collapsed? - // if it's collapsed set typing state + // If selection is collapsed, set typing state if (selection->Collapsed()) { - nsCOMPtr atom; - if (aSizeChange == 1) { - atom = nsGkAtoms::big; - } else { - atom = nsGkAtoms::small; - } + nsIAtom& atom = aDir == FontSize::incr ? *nsGkAtoms::big : + *nsGkAtoms::small; // Let's see in what kind of element the selection is - int32_t offset; - nsCOMPtr selectedNode; - GetStartNodeAndOffset(selection, getter_AddRefs(selectedNode), &offset); - if (selectedNode && IsTextNode(selectedNode)) { - selectedNode = selectedNode->GetParentNode(); + NS_ENSURE_TRUE(selection->RangeCount() && + selection->GetRangeAt(0)->GetStartParent(), NS_OK); + OwningNonNull selectedNode = + *selection->GetRangeAt(0)->GetStartParent(); + if (IsTextNode(selectedNode)) { + NS_ENSURE_TRUE(selectedNode->GetParentNode(), NS_OK); + selectedNode = *selectedNode->GetParentNode(); } - NS_ENSURE_TRUE(selectedNode, NS_OK); - if (!CanContainTag(*selectedNode, *atom)) { + if (!CanContainTag(selectedNode, atom)) { return NS_OK; } - // manipulating text attributes on a collapsed selection only sets state for the next text insertion - mTypeInState->SetProp(atom, EmptyString(), EmptyString()); + // Manipulating text attributes on a collapsed selection only sets state + // for the next text insertion + mTypeInState->SetProp(&atom, EmptyString(), EmptyString()); return NS_OK; } - - // wrap with txn batching, rules sniffing, and selection preservation code + + // Wrap with txn batching, rules sniffing, and selection preservation code nsAutoEditBatch batchIt(this); - nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty, nsIEditor::eNext); + nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty, + nsIEditor::eNext); nsAutoSelectionReset selectionResetter(selection, this); nsAutoTxnsConserveSelection dontSpazMySelection(this); - // loop thru the ranges in the selection + // Loop through the ranges in the selection uint32_t rangeCount = selection->RangeCount(); for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) { nsRefPtr range = selection->GetRangeAt(rangeIdx); - // adjust range to include any ancestors who's children are entirely selected + // Adjust range to include any ancestors with entirely selected children nsresult res = PromoteInlineRange(range); NS_ENSURE_SUCCESS(res, res); - - // check for easy case: both range endpoints in same text node - nsCOMPtr startNode, endNode; - res = range->GetStartContainer(getter_AddRefs(startNode)); - NS_ENSURE_SUCCESS(res, res); - res = range->GetEndContainer(getter_AddRefs(endNode)); - NS_ENSURE_SUCCESS(res, res); - if ((startNode == endNode) && IsTextNode(startNode)) - { - int32_t startOffset, endOffset; - range->GetStartOffset(&startOffset); - range->GetEndOffset(&endOffset); - nsCOMPtr nodeAsText = do_QueryInterface(startNode); - res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, startOffset, endOffset); - NS_ENSURE_SUCCESS(res, res); - } - else - { - // not the easy case. range not contained in single text node. - // there are up to three phases here. There are all the nodes - // reported by the subtree iterator to be processed. And there - // are potentially a starting textnode and an ending textnode - // which are only partially contained by the range. - - // lets handle the nodes reported by the iterator. These nodes - // are entirely contained in the selection range. We build up - // a list of them (since doing operations on the document during - // iteration would perturb the iterator). - nsCOMPtr iter = - do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res); + // Check for easy case: both range endpoints in same text node + nsCOMPtr startNode = range->GetStartParent(); + nsCOMPtr endNode = range->GetEndParent(); + if (startNode == endNode && IsTextNode(startNode)) { + res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1, + static_cast(startNode->AsDOMNode()), + range->StartOffset(), range->EndOffset()); NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE); + } else { + // Not the easy case. Range not contained in single text node. There + // are up to three phases here. There are all the nodes reported by the + // subtree iterator to be processed. And there are potentially a + // starting textnode and an ending textnode which are only partially + // contained by the range. - // iterate range and build up array + // Let's handle the nodes reported by the iterator. These nodes are + // entirely contained in the selection range. We build up a list of them + // (since doing operations on the document during iteration would perturb + // the iterator). + + OwningNonNull iter = NS_NewContentSubtreeIterator(); + + // Iterate range and build up array res = iter->Init(range); if (NS_SUCCEEDED(res)) { - nsCOMArray arrayOfNodes; - while (!iter->IsDone()) { + nsTArray> arrayOfNodes; + for (; !iter->IsDone(); iter->Next()) { NS_ENSURE_TRUE(iter->GetCurrentNode()->IsContent(), NS_ERROR_FAILURE); - nsCOMPtr node = iter->GetCurrentNode()->AsContent(); + OwningNonNull node = *iter->GetCurrentNode()->AsContent(); if (IsEditable(node)) { - arrayOfNodes.AppendObject(node); + arrayOfNodes.AppendElement(node); } - - iter->Next(); } - - // now that we have the list, do the font size change on each node - int32_t listCount = arrayOfNodes.Count(); - for (int32_t j = 0; j < listCount; ++j) { - nsIContent* node = arrayOfNodes[j]; - res = RelativeFontChangeOnNode(aSizeChange, node); + + // Now that we have the list, do the font size change on each node + for (auto& node : arrayOfNodes) { + res = RelativeFontChangeOnNode(aDir == FontSize::incr ? +1 : -1, + node); NS_ENSURE_SUCCESS(res, res); } - arrayOfNodes.Clear(); } - // now check the start and end parents of the range to see if they need to - // be separately handled (they do if they are text nodes, due to how the - // subtree iterator works - it will not have reported them). - if (IsTextNode(startNode) && IsEditable(startNode)) - { - nsCOMPtr nodeAsText = do_QueryInterface(startNode); - int32_t startOffset; - uint32_t textLen; - range->GetStartOffset(&startOffset); - nodeAsText->GetLength(&textLen); - res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, startOffset, textLen); + // Now check the start and end parents of the range to see if they need + // to be separately handled (they do if they are text nodes, due to how + // the subtree iterator works - it will not have reported them). + if (IsTextNode(startNode) && IsEditable(startNode)) { + res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1, + static_cast(startNode->AsDOMNode()), + range->StartOffset(), startNode->Length()); NS_ENSURE_SUCCESS(res, res); } - if (IsTextNode(endNode) && IsEditable(endNode)) - { + if (IsTextNode(endNode) && IsEditable(endNode)) { nsCOMPtr nodeAsText = do_QueryInterface(endNode); int32_t endOffset; range->GetEndOffset(&endOffset); - res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, 0, endOffset); + res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1, + static_cast(startNode->AsDOMNode()), + 0, range->EndOffset()); NS_ENSURE_SUCCESS(res, res); } } } - - return NS_OK; + + return NS_OK; } nsresult From 9195507155ff6a188dc0f6db559534d987a7e70f Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 145/241] Bug 1154701 part 10 - Switch nsEditor::mActionListeners to nsTArray; r=ehsan --- editor/libeditor/nsEditor.cpp | 129 +++++++++++++++++----------------- editor/libeditor/nsEditor.h | 4 +- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index 3b7913b102f8..8055cb79eaef 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -1353,9 +1353,9 @@ nsEditor::CreateNode(nsIAtom* aTag, nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->WillCreateNode(nsDependentAtomString(aTag), - GetAsDOMNode(aParent), aPosition); + for (auto& listener : mActionListeners) { + listener->WillCreateNode(nsDependentAtomString(aTag), + GetAsDOMNode(aParent), aPosition); } nsCOMPtr ret; @@ -1370,11 +1370,9 @@ nsEditor::CreateNode(nsIAtom* aTag, mRangeUpdater.SelAdjCreateNode(aParent, aPosition); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->DidCreateNode(nsDependentAtomString(aTag), - GetAsDOMNode(ret), - GetAsDOMNode(aParent), aPosition, - res); + for (auto& listener : mActionListeners) { + listener->DidCreateNode(nsDependentAtomString(aTag), GetAsDOMNode(ret), + GetAsDOMNode(aParent), aPosition, res); } return ret.forget(); @@ -1396,9 +1394,9 @@ nsEditor::InsertNode(nsIContent& aNode, nsINode& aParent, int32_t aPosition) { nsAutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), - aPosition); + for (auto& listener : mActionListeners) { + listener->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), + aPosition); } nsRefPtr txn = CreateTxnForInsertNode(aNode, aParent, @@ -1407,9 +1405,9 @@ nsEditor::InsertNode(nsIContent& aNode, nsINode& aParent, int32_t aPosition) mRangeUpdater.SelAdjInsertNode(aParent.AsDOMNode(), aPosition); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), - aPosition, res); + for (auto& listener : mActionListeners) { + listener->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), aPosition, + res); } return res; @@ -1435,8 +1433,8 @@ nsEditor::SplitNode(nsIContent& aNode, int32_t aOffset, ErrorResult& aResult) nsAutoRules beginRulesSniffing(this, EditAction::splitNode, nsIEditor::eNext); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->WillSplitNode(aNode.AsDOMNode(), aOffset); + for (auto& listener : mActionListeners) { + listener->WillSplitNode(aNode.AsDOMNode(), aOffset); } nsRefPtr txn = CreateTxnForSplitNode(aNode, aOffset); @@ -1447,10 +1445,9 @@ nsEditor::SplitNode(nsIContent& aNode, int32_t aOffset, ErrorResult& aResult) mRangeUpdater.SelAdjSplitNode(aNode, aOffset, newNode); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->DidSplitNode(aNode.AsDOMNode(), aOffset, - GetAsDOMNode(newNode), - aResult.ErrorCode()); + for (auto& listener : mActionListeners) { + listener->DidSplitNode(aNode.AsDOMNode(), aOffset, GetAsDOMNode(newNode), + aResult.ErrorCode()); } return newNode; @@ -1483,10 +1480,9 @@ nsEditor::JoinNodes(nsINode& aLeftNode, nsINode& aRightNode) // Find the number of children of the lefthand node uint32_t oldLeftNodeLen = aLeftNode.Length(); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->WillJoinNodes(aLeftNode.AsDOMNode(), - aRightNode.AsDOMNode(), - parent->AsDOMNode()); + for (auto& listener : mActionListeners) { + listener->WillJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(), + parent->AsDOMNode()); } nsresult result; @@ -1498,10 +1494,9 @@ nsEditor::JoinNodes(nsINode& aLeftNode, nsINode& aRightNode) mRangeUpdater.SelAdjJoinNodes(aLeftNode, aRightNode, *parent, offset, (int32_t)oldLeftNodeLen); - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->DidJoinNodes(aLeftNode.AsDOMNode(), - aRightNode.AsDOMNode(), - parent->AsDOMNode(), result); + for (auto& listener : mActionListeners) { + listener->DidJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(), + parent->AsDOMNode(), result); } return result; @@ -1522,8 +1517,8 @@ nsEditor::DeleteNode(nsINode* aNode) nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::ePrevious); // save node location for selection updating code. - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->WillDeleteNode(aNode->AsDOMNode()); + for (auto& listener : mActionListeners) { + listener->WillDeleteNode(aNode->AsDOMNode()); } nsRefPtr txn; @@ -1532,8 +1527,8 @@ nsEditor::DeleteNode(nsINode* aNode) res = DoTransaction(txn); } - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->DidDeleteNode(aNode->AsDOMNode(), res); + for (auto& listener : mActionListeners) { + listener->DidDeleteNode(aNode->AsDOMNode(), res); } NS_ENSURE_SUCCESS(res, res); @@ -1866,10 +1861,8 @@ nsEditor::AddEditActionListener(nsIEditActionListener *aListener) NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); // Make sure the listener isn't already on the list - if (mActionListeners.IndexOf(aListener) == -1) - { - if (!mActionListeners.AppendObject(aListener)) - return NS_ERROR_FAILURE; + if (!mActionListeners.Contains(aListener)) { + mActionListeners.AppendElement(*aListener); } return NS_OK; @@ -1881,8 +1874,7 @@ nsEditor::RemoveEditActionListener(nsIEditActionListener *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE); - if (!mActionListeners.RemoveObject(aListener)) - return NS_ERROR_FAILURE; + mActionListeners.RemoveElement(aListener); return NS_OK; } @@ -2392,8 +2384,8 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, } // Let listeners know what's up - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->WillInsertText( + for (auto& listener : mActionListeners) { + listener->WillInsertText( static_cast(aTextNode.AsDOMNode()), aOffset, aStringToInsert); } @@ -2407,8 +2399,8 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, mRangeUpdater.SelAdjInsertText(aTextNode, aOffset, aStringToInsert); // let listeners know what happened - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->DidInsertText( + for (auto& listener : mActionListeners) { + listener->DidInsertText( static_cast(aTextNode.AsDOMNode()), aOffset, aStringToInsert, res); } @@ -2542,8 +2534,8 @@ nsEditor::DeleteText(nsGenericDOMDataNode& aCharData, uint32_t aOffset, nsAutoRules beginRulesSniffing(this, EditAction::deleteText, nsIEditor::ePrevious); // Let listeners know what's up - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->WillDeleteText( + for (auto& listener : mActionListeners) { + listener->WillDeleteText( static_cast(GetAsDOMNode(&aCharData)), aOffset, aLength); } @@ -2551,8 +2543,8 @@ nsEditor::DeleteText(nsGenericDOMDataNode& aCharData, uint32_t aOffset, nsresult res = DoTransaction(txn); // Let listeners know what happened - for (int32_t i = 0; i < mActionListeners.Count(); i++) { - mActionListeners[i]->DidDeleteText( + for (auto& listener : mActionListeners) { + listener->DidDeleteText( static_cast(GetAsDOMNode(&aCharData)), aOffset, aLength, res); } @@ -3920,31 +3912,38 @@ nsEditor::DeleteSelectionImpl(EDirection aAction, if (NS_SUCCEEDED(res)) { nsAutoRules beginRulesSniffing(this, EditAction::deleteSelection, aAction); - int32_t i; // Notify nsIEditActionListener::WillDelete[Selection|Text|Node] - if (!deleteNode) - for (i = 0; i < mActionListeners.Count(); i++) - mActionListeners[i]->WillDeleteSelection(selection); - else if (deleteCharData) - for (i = 0; i < mActionListeners.Count(); i++) - mActionListeners[i]->WillDeleteText(deleteCharData, deleteCharOffset, 1); - else - for (i = 0; i < mActionListeners.Count(); i++) - mActionListeners[i]->WillDeleteNode(deleteNode->AsDOMNode()); + if (!deleteNode) { + for (auto& listener : mActionListeners) { + listener->WillDeleteSelection(selection); + } + } else if (deleteCharData) { + for (auto& listener : mActionListeners) { + listener->WillDeleteText(deleteCharData, deleteCharOffset, 1); + } + } else { + for (auto& listener : mActionListeners) { + listener->WillDeleteNode(deleteNode->AsDOMNode()); + } + } // Delete the specified amount res = DoTransaction(txn); // Notify nsIEditActionListener::DidDelete[Selection|Text|Node] - if (!deleteNode) - for (i = 0; i < mActionListeners.Count(); i++) - mActionListeners[i]->DidDeleteSelection(selection); - else if (deleteCharData) - for (i = 0; i < mActionListeners.Count(); i++) - mActionListeners[i]->DidDeleteText(deleteCharData, deleteCharOffset, 1, res); - else - for (i = 0; i < mActionListeners.Count(); i++) - mActionListeners[i]->DidDeleteNode(deleteNode->AsDOMNode(), res); + if (!deleteNode) { + for (auto& listener : mActionListeners) { + listener->DidDeleteSelection(selection); + } + } else if (deleteCharData) { + for (auto& listener : mActionListeners) { + listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, res); + } + } else { + for (auto& listener : mActionListeners) { + listener->DidDeleteNode(deleteNode->AsDOMNode(), res); + } + } } return res; diff --git a/editor/libeditor/nsEditor.h b/editor/libeditor/nsEditor.h index 8e377cbc247f..077d2bc9bf38 100644 --- a/editor/libeditor/nsEditor.h +++ b/editor/libeditor/nsEditor.h @@ -7,6 +7,7 @@ #define __editor_h__ #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc. +#include "mozilla/dom/OwningNonNull.h" // for OwningNonNull #include "mozilla/dom/Text.h" #include "nsAutoPtr.h" // for nsRefPtr #include "nsCOMArray.h" // for nsCOMArray @@ -830,7 +831,8 @@ protected: nsRefPtr mComposition; // various listeners - nsCOMArray mActionListeners; // listens to all low level actions on the doc + // Listens to all low level actions on the doc + nsTArray> mActionListeners; nsCOMArray mEditorObservers; // just notify once per high level change nsCOMArray mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc) From 48afd5614f2a7db47149c57135bc363ea2586519 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 146/241] Bug 1154701 part 11 - Switch nsEditor::mEditorObservers to nsTArray; r=ehsan --- editor/libeditor/nsEditor.cpp | 21 +++++++++------------ editor/libeditor/nsEditor.h | 3 ++- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index 8055cb79eaef..f73ad1c7ab05 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -1733,10 +1733,8 @@ nsEditor::AddEditorObserver(nsIEditorObserver *aObserver) NS_ENSURE_TRUE(aObserver, NS_ERROR_NULL_POINTER); // Make sure the listener isn't already on the list - if (mEditorObservers.IndexOf(aObserver) == -1) - { - if (!mEditorObservers.AppendObject(aObserver)) - return NS_ERROR_FAILURE; + if (!mEditorObservers.Contains(aObserver)) { + mEditorObservers.AppendElement(*aObserver); } return NS_OK; @@ -1748,8 +1746,7 @@ nsEditor::RemoveEditorObserver(nsIEditorObserver *aObserver) { NS_ENSURE_TRUE(aObserver, NS_ERROR_FAILURE); - if (!mEditorObservers.RemoveObject(aObserver)) - return NS_ERROR_FAILURE; + mEditorObservers.RemoveElement(aObserver); return NS_OK; } @@ -1809,8 +1806,8 @@ nsEditor::NotifyEditorObservers(NotificationForEditorObservers aNotification) switch (aNotification) { case eNotifyEditorObserversOfEnd: mIsInEditAction = false; - for (int32_t i = 0; i < mEditorObservers.Count(); i++) { - mEditorObservers[i]->EditAction(); + for (auto& observer : mEditorObservers) { + observer->EditAction(); } if (!mDispatchInputEvent) { @@ -1821,14 +1818,14 @@ nsEditor::NotifyEditorObservers(NotificationForEditorObservers aNotification) break; case eNotifyEditorObserversOfBefore: mIsInEditAction = true; - for (int32_t i = 0; i < mEditorObservers.Count(); i++) { - mEditorObservers[i]->BeforeEditAction(); + for (auto& observer : mEditorObservers) { + observer->BeforeEditAction(); } break; case eNotifyEditorObserversOfCancel: mIsInEditAction = false; - for (int32_t i = 0; i < mEditorObservers.Count(); i++) { - mEditorObservers[i]->CancelEditAction(); + for (auto& observer : mEditorObservers) { + observer->CancelEditAction(); } break; default: diff --git a/editor/libeditor/nsEditor.h b/editor/libeditor/nsEditor.h index 077d2bc9bf38..a9f2756e2ce0 100644 --- a/editor/libeditor/nsEditor.h +++ b/editor/libeditor/nsEditor.h @@ -833,7 +833,8 @@ protected: // various listeners // Listens to all low level actions on the doc nsTArray> mActionListeners; - nsCOMArray mEditorObservers; // just notify once per high level change + // Just notify once per high level change + nsTArray> mEditorObservers; nsCOMArray mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc) nsSelectionState mSavedSel; // cached selection for nsAutoSelectionReset From 27902b013b5b39a64cc8d4dde2a1f408b72decc0 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 147/241] Bug 1154701 part 12 - Switch nsEditor::mDocStateListeners to nsTArray; r=ehsan --- editor/libeditor/nsEditor.cpp | 33 ++++++++++++++------------------- editor/libeditor/nsEditor.h | 4 ++-- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index f73ad1c7ab05..019255bd4598 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -1882,10 +1882,8 @@ nsEditor::AddDocumentStateListener(nsIDocumentStateListener *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); - if (mDocStateListeners.IndexOf(aListener) == -1) - { - if (!mDocStateListeners.AppendObject(aListener)) - return NS_ERROR_FAILURE; + if (!mDocStateListeners.Contains(aListener)) { + mDocStateListeners.AppendElement(*aListener); } return NS_OK; @@ -1897,8 +1895,7 @@ nsEditor::RemoveDocumentStateListener(nsIDocumentStateListener *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); - if (!mDocStateListeners.RemoveObject(aListener)) - return NS_ERROR_FAILURE; + mDocStateListeners.RemoveElement(aListener); return NS_OK; } @@ -2454,29 +2451,28 @@ nsEditor::GetFirstEditableNode(nsINode* aRoot) NS_IMETHODIMP nsEditor::NotifyDocumentListeners(TDocumentListenerNotification aNotificationType) { - int32_t numListeners = mDocStateListeners.Count(); - if (!numListeners) // maybe there just aren't any. + if (!mDocStateListeners.Length()) { + // Maybe there just aren't any. return NS_OK; + } - nsCOMArray listeners(mDocStateListeners); + nsTArray> + listeners(mDocStateListeners); nsresult rv = NS_OK; - int32_t i; switch (aNotificationType) { case eDocumentCreated: - for (i = 0; i < numListeners;i++) - { - rv = listeners[i]->NotifyDocumentCreated(); + for (auto& listener : listeners) { + rv = listener->NotifyDocumentCreated(); if (NS_FAILED(rv)) break; } break; case eDocumentToBeDestroyed: - for (i = 0; i < numListeners;i++) - { - rv = listeners[i]->NotifyDocumentWillBeDestroyed(); + for (auto& listener : listeners) { + rv = listener->NotifyDocumentWillBeDestroyed(); if (NS_FAILED(rv)) break; } @@ -2493,9 +2489,8 @@ nsEditor::NotifyDocumentListeners(TDocumentListenerNotification aNotificationTyp mDocDirtyState = docIsDirty; - for (i = 0; i < numListeners;i++) - { - rv = listeners[i]->NotifyDocumentStateChanged(mDocDirtyState); + for (auto& listener : listeners) { + rv = listener->NotifyDocumentStateChanged(mDocDirtyState); if (NS_FAILED(rv)) break; } diff --git a/editor/libeditor/nsEditor.h b/editor/libeditor/nsEditor.h index a9f2756e2ce0..277d2293fb1e 100644 --- a/editor/libeditor/nsEditor.h +++ b/editor/libeditor/nsEditor.h @@ -10,7 +10,6 @@ #include "mozilla/dom/OwningNonNull.h" // for OwningNonNull #include "mozilla/dom/Text.h" #include "nsAutoPtr.h" // for nsRefPtr -#include "nsCOMArray.h" // for nsCOMArray #include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr #include "nsCycleCollectionParticipant.h" #include "nsGkAtoms.h" @@ -835,7 +834,8 @@ protected: nsTArray> mActionListeners; // Just notify once per high level change nsTArray> mEditorObservers; - nsCOMArray mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc) + // Listen to overall doc state (dirty or not, just created, etc) + nsTArray> mDocStateListeners; nsSelectionState mSavedSel; // cached selection for nsAutoSelectionReset nsRangeUpdater mRangeUpdater; // utility class object for maintaining preserved ranges From 6dfd369a45b4adf8b1af74e578cce3110560674d Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 148/241] Bug 1154701 part 13 - Clean up nsHTMLEditor::SetCSSBackgroundColor; r=ehsan --- editor/libeditor/nsHTMLEditor.cpp | 228 ++++++++++++------------------ 1 file changed, 94 insertions(+), 134 deletions(-) diff --git a/editor/libeditor/nsHTMLEditor.cpp b/editor/libeditor/nsHTMLEditor.cpp index d732088b320e..35813ca23d84 100644 --- a/editor/libeditor/nsHTMLEditor.cpp +++ b/editor/libeditor/nsHTMLEditor.cpp @@ -4503,196 +4503,156 @@ nsHTMLEditor::SetIsCSSEnabled(bool aIsCSSPrefChecked) nsresult nsHTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) { - if (!mRules) { return NS_ERROR_NOT_INITIALIZED; } + NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED); ForceCompositionEnd(); // Protect the edit rules object from dying nsCOMPtr kungFuDeathGrip(mRules); nsRefPtr selection = GetSelection(); + NS_ENSURE_STATE(selection); bool isCollapsed = selection->Collapsed(); nsAutoEditBatch batchIt(this); - nsAutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext); + nsAutoRules beginRulesSniffing(this, EditAction::insertElement, + nsIEditor::eNext); nsAutoSelectionReset selectionResetter(selection, this); nsAutoTxnsConserveSelection dontSpazMySelection(this); - + bool cancel, handled; nsTextRulesInfo ruleInfo(EditAction::setTextProperty); nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled); NS_ENSURE_SUCCESS(res, res); - if (!cancel && !handled) - { - // loop thru the ranges in the selection - nsAutoString bgcolor; bgcolor.AssignLiteral("bgcolor"); - uint32_t rangeCount = selection->RangeCount(); - for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) { - nsCOMPtr cachedBlockParent = nullptr; - nsRefPtr range = selection->GetRangeAt(rangeIdx); + if (!cancel && !handled) { + // Loop through the ranges in the selection + NS_NAMED_LITERAL_STRING(bgcolor, "bgcolor"); + for (uint32_t i = 0; i < selection->RangeCount(); i++) { + nsRefPtr range = selection->GetRangeAt(i); NS_ENSURE_TRUE(range, NS_ERROR_FAILURE); - - // check for easy case: both range endpoints in same text node - nsCOMPtr startNode, endNode; - int32_t startOffset, endOffset; - res = range->GetStartContainer(getter_AddRefs(startNode)); - NS_ENSURE_SUCCESS(res, res); - res = range->GetEndContainer(getter_AddRefs(endNode)); - NS_ENSURE_SUCCESS(res, res); - res = range->GetStartOffset(&startOffset); - NS_ENSURE_SUCCESS(res, res); - res = range->GetEndOffset(&endOffset); - NS_ENSURE_SUCCESS(res, res); - if ((startNode == endNode) && IsTextNode(startNode)) - { - // let's find the block container of the text node - nsCOMPtr blockParent; - blockParent = GetBlockNodeParent(startNode); - // and apply the background color to that block container + + nsCOMPtr cachedBlockParent; + + // Check for easy case: both range endpoints in same text node + nsCOMPtr startNode = range->GetStartParent(); + int32_t startOffset = range->StartOffset(); + nsCOMPtr endNode = range->GetEndParent(); + int32_t endOffset = range->EndOffset(); + if (startNode == endNode && IsTextNode(startNode)) { + // Let's find the block container of the text node + nsCOMPtr blockParent = GetBlockNodeParent(startNode); + // And apply the background color to that block container if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; - nsCOMPtr element = do_QueryInterface(blockParent); - int32_t count; - res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false); - NS_ENSURE_SUCCESS(res, res); + mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, + &bgcolor, &aColor, false); } - } - else if ((startNode == endNode) && nsTextEditUtils::IsBody(startNode) && isCollapsed) - { - // we have no block in the document, let's apply the background to the body - nsCOMPtr element = do_QueryInterface(startNode); - int32_t count; - res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false); - NS_ENSURE_SUCCESS(res, res); - } - else if ((startNode == endNode) && (((endOffset-startOffset) == 1) || (!startOffset && !endOffset))) - { - // a unique node is selected, let's also apply the background color - // to the containing block, possibly the node itself - nsCOMPtr selectedNode = GetChildAt(startNode, startOffset); - bool isBlock =false; - res = NodeIsBlockStatic(selectedNode, &isBlock); - NS_ENSURE_SUCCESS(res, res); - nsCOMPtr blockParent = selectedNode; - if (!isBlock) { + } else if (startNode == endNode && + startNode->IsHTMLElement(nsGkAtoms::body) && isCollapsed) { + // No block in the document, let's apply the background to the body + mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(startNode->AsElement(), + nullptr, &bgcolor, &aColor, + false); + } else if (startNode == endNode && (endOffset - startOffset == 1 || + (!startOffset && !endOffset))) { + // A unique node is selected, let's also apply the background color to + // the containing block, possibly the node itself + nsCOMPtr selectedNode = startNode->GetChildAt(startOffset); + nsCOMPtr blockParent; + if (NodeIsBlockStatic(selectedNode)) { + blockParent = selectedNode->AsElement(); + } else { blockParent = GetBlockNodeParent(selectedNode); } if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; - nsCOMPtr element = do_QueryInterface(blockParent); - int32_t count; - res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false); - NS_ENSURE_SUCCESS(res, res); + mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, + &bgcolor, &aColor, false); } - } - else - { - // not the easy case. range not contained in single text node. - // there are up to three phases here. There are all the nodes - // reported by the subtree iterator to be processed. And there - // are potentially a starting textnode and an ending textnode - // which are only partially contained by the range. - - // lets handle the nodes reported by the iterator. These nodes - // are entirely contained in the selection range. We build up - // a list of them (since doing operations on the document during - // iteration would perturb the iterator). + } else { + // Not the easy case. Range not contained in single text node. There + // are up to three phases here. There are all the nodes reported by + // the subtree iterator to be processed. And there are potentially a + // starting textnode and an ending textnode which are only partially + // contained by the range. - nsCOMPtr iter = - do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res); - NS_ENSURE_SUCCESS(res, res); - NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE); + // Let's handle the nodes reported by the iterator. These nodes are + // entirely contained in the selection range. We build up a list of + // them (since doing operations on the document during iteration would + // perturb the iterator). - nsCOMArray arrayOfNodes; - nsCOMPtr node; - - // iterate range and build up array + OwningNonNull iter = + NS_NewContentSubtreeIterator(); + + nsTArray> arrayOfNodes; + nsCOMPtr node; + + // Iterate range and build up array res = iter->Init(range); - // init returns an error if no nodes in range. - // this can easily happen with the subtree - // iterator if the selection doesn't contain - // any *whole* nodes. - if (NS_SUCCEEDED(res)) - { - while (!iter->IsDone()) - { + // Init returns an error if no nodes in range. This can easily happen + // with the subtree iterator if the selection doesn't contain any + // *whole* nodes. + if (NS_SUCCEEDED(res)) { + for (; !iter->IsDone(); iter->Next()) { node = do_QueryInterface(iter->GetCurrentNode()); NS_ENSURE_TRUE(node, NS_ERROR_FAILURE); - if (IsEditable(node)) - { - arrayOfNodes.AppendObject(node); + if (IsEditable(node)) { + arrayOfNodes.AppendElement(*node); } - - iter->Next(); } } - // first check the start parent of the range to see if it needs to - // be separately handled (it does if it's a text node, due to how the + // First check the start parent of the range to see if it needs to be + // separately handled (it does if it's a text node, due to how the // subtree iterator works - it will not have reported it). - if (IsTextNode(startNode) && IsEditable(startNode)) - { - nsCOMPtr blockParent; - blockParent = GetBlockNodeParent(startNode); + if (IsTextNode(startNode) && IsEditable(startNode)) { + nsCOMPtr blockParent = GetBlockNodeParent(startNode); if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; - nsCOMPtr element = do_QueryInterface(blockParent); - int32_t count; - res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false); - NS_ENSURE_SUCCESS(res, res); + mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, + &bgcolor, &aColor, + false); } } - - // then loop through the list, set the property on each node - int32_t listCount = arrayOfNodes.Count(); - int32_t j; - for (j = 0; j < listCount; j++) - { - node = arrayOfNodes[j]; - // do we have a block here ? - bool isBlock =false; - res = NodeIsBlockStatic(node, &isBlock); - NS_ENSURE_SUCCESS(res, res); - nsCOMPtr blockParent = node; - if (!isBlock) { - // no we don't, let's find the block ancestor + + // Then loop through the list, set the property on each node + for (auto& node : arrayOfNodes) { + nsCOMPtr blockParent; + if (NodeIsBlockStatic(node)) { + blockParent = node->AsElement(); + } else { blockParent = GetBlockNodeParent(node); } if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; - nsCOMPtr element = do_QueryInterface(blockParent); - int32_t count; - // and set the property on it - res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false); - NS_ENSURE_SUCCESS(res, res); + mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, + &bgcolor, &aColor, + false); } } arrayOfNodes.Clear(); - - // last check the end parent of the range to see if it needs to - // be separately handled (it does if it's a text node, due to how the + + // Last, check the end parent of the range to see if it needs to be + // separately handled (it does if it's a text node, due to how the // subtree iterator works - it will not have reported it). - if (IsTextNode(endNode) && IsEditable(endNode)) - { - nsCOMPtr blockParent; - blockParent = GetBlockNodeParent(endNode); + if (IsTextNode(endNode) && IsEditable(endNode)) { + nsCOMPtr blockParent = GetBlockNodeParent(endNode); if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; - nsCOMPtr element = do_QueryInterface(blockParent); - int32_t count; - res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false); - NS_ENSURE_SUCCESS(res, res); + mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, + &bgcolor, &aColor, + false); } } } } } - if (!cancel) - { - // post-process + if (!cancel) { + // Post-process res = mRules->DidDoAction(selection, &ruleInfo, res); + NS_ENSURE_SUCCESS(res, res); } - return res; + return NS_OK; } NS_IMETHODIMP From fcfd672bbad0c9862d4d844ceda960585ce107b3 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Wed, 22 Apr 2015 14:27:18 +0300 Subject: [PATCH 149/241] Bug 1154701 part 14 - Remove unused nsCOMArray cruft; r=ehsan --- editor/libeditor/nsEditorUtils.cpp | 15 ------------ editor/libeditor/nsEditorUtils.h | 11 ++------- editor/libeditor/nsHTMLEditRules.cpp | 30 +++++++++--------------- editor/libeditor/nsHTMLEditRules.h | 1 - editor/libeditor/nsHTMLEditor.cpp | 2 -- editor/libeditor/nsHTMLObjectResizer.cpp | 1 - 6 files changed, 13 insertions(+), 47 deletions(-) diff --git a/editor/libeditor/nsEditorUtils.cpp b/editor/libeditor/nsEditorUtils.cpp index 64e1be3b67b4..4b268ac44455 100644 --- a/editor/libeditor/nsEditorUtils.cpp +++ b/editor/libeditor/nsEditorUtils.cpp @@ -7,7 +7,6 @@ #include "mozilla/dom/OwningNonNull.h" #include "mozilla/dom/Selection.h" -#include "nsCOMArray.h" #include "nsComponentManagerUtils.h" #include "nsError.h" #include "nsIClipboardDragDropHookList.h" @@ -104,20 +103,6 @@ nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, } } -void -nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, - nsCOMArray& arrayOfNodes) const -{ - // iterate through dom and build list - for (; !mIter->IsDone(); mIter->Next()) { - nsCOMPtr node = mIter->GetCurrentNode()->AsDOMNode(); - - if (functor(node)) { - arrayOfNodes.AppendObject(node); - } - } -} - nsDOMSubtreeIterator::nsDOMSubtreeIterator(nsRange& aRange) { mIter = NS_NewContentSubtreeIterator(); diff --git a/editor/libeditor/nsEditorUtils.h b/editor/libeditor/nsEditorUtils.h index 82eb266a75db..7e4e44ac82a6 100644 --- a/editor/libeditor/nsEditorUtils.h +++ b/editor/libeditor/nsEditorUtils.h @@ -19,7 +19,6 @@ class nsIAtom; class nsIContentIterator; class nsIDOMDocument; class nsRange; -template class nsCOMArray; namespace mozilla { namespace dom { template class OwningNonNull; @@ -168,11 +167,7 @@ class MOZ_STACK_CLASS nsAutoUpdateViewBatch class nsBoolDomIterFunctor { public: - virtual bool operator()(nsIDOMNode* aNode) const = 0; - bool operator()(nsINode* aNode) const - { - return operator()(GetAsDOMNode(aNode)); - } + virtual bool operator()(nsINode* aNode) const = 0; }; class MOZ_STACK_CLASS nsDOMIterator @@ -184,8 +179,6 @@ class MOZ_STACK_CLASS nsDOMIterator void AppendList(const nsBoolDomIterFunctor& functor, nsTArray>& arrayOfNodes) const; - void AppendList(const nsBoolDomIterFunctor& functor, - nsCOMArray& arrayOfNodes) const; protected: nsCOMPtr mIter; @@ -204,7 +197,7 @@ class nsTrivialFunctor : public nsBoolDomIterFunctor { public: // Used to build list of all nodes iterator covers - virtual bool operator()(nsIDOMNode* aNode) const + virtual bool operator()(nsINode* aNode) const { return true; } diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index a70ea5fe1581..51dcdc22cb02 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -107,7 +107,7 @@ class nsTableCellAndListItemFunctor : public nsBoolDomIterFunctor { public: // Used to build list of all li's, td's & th's iterator covers - virtual bool operator()(nsIDOMNode* aNode) const + virtual bool operator()(nsINode* aNode) const { if (nsHTMLEditUtils::IsTableCell(aNode)) return true; if (nsHTMLEditUtils::IsListItem(aNode)) return true; @@ -118,9 +118,11 @@ class nsTableCellAndListItemFunctor : public nsBoolDomIterFunctor class nsBRNodeFunctor : public nsBoolDomIterFunctor { public: - virtual bool operator()(nsIDOMNode* aNode) const + virtual bool operator()(nsINode* aNode) const { - if (nsTextEditUtils::IsBreak(aNode)) return true; + if (aNode->IsHTMLElement(nsGkAtoms::br)) { + return true; + } return false; } }; @@ -129,12 +131,11 @@ class nsEmptyEditableFunctor : public nsBoolDomIterFunctor { public: explicit nsEmptyEditableFunctor(nsHTMLEditor* editor) : mHTMLEditor(editor) {} - virtual bool operator()(nsIDOMNode* aNode) const + virtual bool operator()(nsINode* aNode) const { if (mHTMLEditor->IsEditable(aNode) && - (nsHTMLEditUtils::IsListItem(aNode) || - nsHTMLEditUtils::IsTableCellOrCaption(aNode))) - { + (nsHTMLEditUtils::IsListItem(aNode) || + nsHTMLEditUtils::IsTableCellOrCaption(GetAsDOMNode(aNode)))) { bool bIsEmptyNode; nsresult res = mHTMLEditor->IsEmptyNode(aNode, &bIsEmptyNode, false, false); NS_ENSURE_SUCCESS(res, false); @@ -151,7 +152,7 @@ class nsEditableTextFunctor : public nsBoolDomIterFunctor { public: explicit nsEditableTextFunctor(nsHTMLEditor* editor) : mHTMLEditor(editor) {} - virtual bool operator()(nsIDOMNode* aNode) const + virtual bool operator()(nsINode* aNode) const { if (nsEditor::IsTextNode(aNode) && mHTMLEditor->IsEditable(aNode)) { @@ -5718,15 +5719,6 @@ nsHTMLEditRules::PromoteRange(nsRange& aRange, EditAction aOperationType) MOZ_ASSERT(NS_SUCCEEDED(res)); } -class NodeComparator -{ - public: - bool Equals(const nsINode* node, const nsIDOMNode* domNode) const - { - return domNode == GetAsDOMNode(const_cast(node)); - } -}; - class nsUniqueFunctor : public nsBoolDomIterFunctor { public: @@ -5734,9 +5726,9 @@ public: { } // used to build list of all nodes iterator covers - virtual bool operator()(nsIDOMNode* aNode) const + virtual bool operator()(nsINode* aNode) const { - return !mArray.Contains(aNode, NodeComparator()); + return !mArray.Contains(aNode); } private: diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h index 585ca49a07ca..0d8f841f9743 100644 --- a/editor/libeditor/nsHTMLEditRules.h +++ b/editor/libeditor/nsHTMLEditRules.h @@ -37,7 +37,6 @@ class Selection; } // namespace dom } // namespace mozilla struct DOMPoint; -template class nsCOMArray; struct StyleCache : public PropItem { diff --git a/editor/libeditor/nsHTMLEditor.cpp b/editor/libeditor/nsHTMLEditor.cpp index 35813ca23d84..04cd9444ac7e 100644 --- a/editor/libeditor/nsHTMLEditor.cpp +++ b/editor/libeditor/nsHTMLEditor.cpp @@ -2988,8 +2988,6 @@ nsHTMLEditor::GetURLForStyleSheet(CSSStyleSheet* aStyleSheet, int32_t foundIndex = mStyleSheets.IndexOf(aStyleSheet); // Don't fail if we don't find it in our list - // Note: mStyleSheets is nsCOMArray, so its IndexOf() method - // returns -1 on failure. if (foundIndex == -1) return NS_OK; diff --git a/editor/libeditor/nsHTMLObjectResizer.cpp b/editor/libeditor/nsHTMLObjectResizer.cpp index 3948aec4d3aa..f0123fe49512 100644 --- a/editor/libeditor/nsHTMLObjectResizer.cpp +++ b/editor/libeditor/nsHTMLObjectResizer.cpp @@ -13,7 +13,6 @@ #include "nsAString.h" #include "nsAlgorithm.h" #include "nsAutoPtr.h" -#include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsDebug.h" #include "nsEditorUtils.h" From b2f6baa64d078f338db0c88084a9147885fd376d Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 21 Apr 2015 20:16:27 -0400 Subject: [PATCH 150/241] Bug 1157059 - Avoid calling AddRef on the pointer enclosed in an nsCOMPtr in nsBindingManager::DoProcessAttachedQueue(); r=baku --- dom/xbl/nsBindingManager.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dom/xbl/nsBindingManager.cpp b/dom/xbl/nsBindingManager.cpp index 55ecf31aa7d2..c339b5f8aef5 100644 --- a/dom/xbl/nsBindingManager.cpp +++ b/dom/xbl/nsBindingManager.cpp @@ -50,6 +50,7 @@ #include "nsThreadUtils.h" #include "mozilla/dom/NodeListBinding.h" #include "mozilla/dom/ScriptSettings.h" +#include "mozilla/unused.h" using namespace mozilla; using namespace mozilla::dom; @@ -405,7 +406,9 @@ nsBindingManager::DoProcessAttachedQueue() } if (NS_SUCCEEDED(rv)) { NS_ADDREF_THIS(); - NS_ADDREF(timer); + // We drop our reference to the timer here, since the timer callback is + // responsible for releasing the object. + unused << timer.forget().take(); } } From ed2915b75f1f577fa600315f18bafa192d64ee7f Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 22 Apr 2015 13:44:23 +0200 Subject: [PATCH 151/241] Backed out changeset 7f3cf84c11a9 (bug 1124076) for bustage on a CLOSED TREE --- dom/ipc/ContentChild.cpp | 18 - dom/ipc/ContentChild.h | 4 - dom/ipc/ContentParent.cpp | 18 - dom/ipc/ContentParent.h | 4 - dom/ipc/PContent.ipdl | 4 - .../ssl/src/PPSMContentDownloader.ipdl | 28 -- .../manager/ssl/src/PSMContentListener.cpp | 476 ++++++------------ security/manager/ssl/src/PSMContentListener.h | 72 --- security/manager/ssl/src/moz.build | 8 - security/manager/ssl/src/nsNSSModule.cpp | 14 +- 10 files changed, 165 insertions(+), 481 deletions(-) delete mode 100644 security/manager/ssl/src/PPSMContentDownloader.ipdl diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 799497ffd7a9..74b1a8b36833 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -38,7 +38,6 @@ #include "mozilla/dom/asmjscache/AsmJSCache.h" #include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h" #include "mozilla/dom/nsIContentChild.h" -#include "mozilla/psm/PSMContentListener.h" #include "mozilla/hal_sandbox/PHalChild.h" #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/FileDescriptorSetChild.h" @@ -204,7 +203,6 @@ using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::net; using namespace mozilla::jsipc; -using namespace mozilla::psm; using namespace mozilla::widget; #if defined(MOZ_WIDGET_GONK) using namespace mozilla::system; @@ -1625,22 +1623,6 @@ ContentChild::DeallocPScreenManagerChild(PScreenManagerChild* aService) return true; } -PPSMContentDownloaderChild* -ContentChild::AllocPPSMContentDownloaderChild(const uint32_t& aCertType) -{ - // NB: We don't need aCertType in the child actor. - nsRefPtr child = new PSMContentDownloaderChild(); - return child.forget().take(); -} - -bool -ContentChild::DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aListener) -{ - auto* listener = static_cast(aListener); - nsRefPtr child = dont_AddRef(listener); - return true; -} - PExternalHelperAppChild* ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index bb2d8d999a47..6adf18e222d9 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -232,10 +232,6 @@ public: bool* aSuccess) override; virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) override; - virtual PPSMContentDownloaderChild* AllocPPSMContentDownloaderChild( - const uint32_t& aCertType) override; - virtual bool DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aDownloader) override; - virtual PExternalHelperAppChild *AllocPExternalHelperAppChild( const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index d8b4c25768d8..0bc87b8b197f 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -156,7 +156,6 @@ #include "prio.h" #include "private/pprio.h" #include "ContentProcessManager.h" -#include "mozilla/psm/PSMContentListener.h" #include "nsIBidiKeyboard.h" @@ -250,7 +249,6 @@ using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::net; using namespace mozilla::jsipc; -using namespace mozilla::psm; using namespace mozilla::widget; #ifdef ENABLE_TESTS @@ -3667,22 +3665,6 @@ ContentParent::DeallocPScreenManagerParent(PScreenManagerParent* aActor) return true; } -PPSMContentDownloaderParent* -ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType) -{ - nsRefPtr downloader = - new PSMContentDownloaderParent(aCertType); - return downloader.forget().take(); -} - -bool -ContentParent::DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aListener) -{ - auto* listener = static_cast(aListener); - nsRefPtr downloader = dont_AddRef(listener); - return true; -} - PExternalHelperAppParent* ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 680845e43a46..8affe5a57c1d 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -606,10 +606,6 @@ private: virtual bool DeallocPNeckoParent(PNeckoParent* necko) override; - virtual PPSMContentDownloaderParent* AllocPPSMContentDownloaderParent( - const uint32_t& aCertType) override; - virtual bool DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aDownloader) override; - virtual PExternalHelperAppParent* AllocPExternalHelperAppParent( const OptionalURIParams& aUri, const nsCString& aMimeContentType, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 190b836330cf..a4af80229623 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -16,7 +16,6 @@ include protocol PContentPermissionRequest; include protocol PCycleCollectWithLogs; include protocol PCrashReporter; include protocol PDocAccessible; -include protocol PPSMContentDownloader; include protocol PExternalHelperApp; include protocol PDeviceStorageRequest; include protocol PFileDescriptorSet; @@ -389,7 +388,6 @@ prio(normal upto urgent) sync protocol PContent manages PDocAccessible; manages PDeviceStorageRequest; manages PFileSystemRequest; - manages PPSMContentDownloader; manages PExternalHelperApp; manages PFileDescriptorSet; manages PFMRadio; @@ -758,8 +756,6 @@ parent: CloseAlert(nsString name, Principal principal); - PPSMContentDownloader(uint32_t aCertType); - PExternalHelperApp(OptionalURIParams uri, nsCString aMimeContentType, nsCString aContentDisposition, diff --git a/security/manager/ssl/src/PPSMContentDownloader.ipdl b/security/manager/ssl/src/PPSMContentDownloader.ipdl deleted file mode 100644 index ac97d7c444fb..000000000000 --- a/security/manager/ssl/src/PPSMContentDownloader.ipdl +++ /dev/null @@ -1,28 +0,0 @@ -/* vim: set sw=2 sts=2 ts=2 et tw=80 ft=cpp: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -include protocol PContent; -include protocol PChannelDiverter; - -namespace mozilla { -namespace psm { - -protocol PPSMContentDownloader -{ - manager PContent; - -parent: - OnStartRequest(uint32_t contentLength); - OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); - OnStopRequest(nsresult code); - - DivertToParentUsing(PChannelDiverter diverter); - -child: - __delete__(); -}; - -} // namespace psm -} // namespace mozilla diff --git a/security/manager/ssl/src/PSMContentListener.cpp b/security/manager/ssl/src/PSMContentListener.cpp index 84bed2805590..789aac0fa668 100644 --- a/security/manager/ssl/src/PSMContentListener.cpp +++ b/security/manager/ssl/src/PSMContentListener.cpp @@ -1,5 +1,4 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set sw=2 sts=2 ts=2 et tw=80: * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -7,22 +6,16 @@ #include "PSMContentListener.h" -#include "nsIDivertableChannel.h" #include "nsIStreamListener.h" #include "nsIX509CertDB.h" -#include "nsIXULAppInfo.h" #include "mozilla/Casting.h" #include "mozilla/Services.h" -#include "mozilla/unused.h" - -#include "mozilla/dom/ContentChild.h" -#include "mozilla/net/ChannelDiverterParent.h" -#include "mozilla/net/ChannelDiverterChild.h" #include "nsCRT.h" #include "nsNetUtil.h" #include "nsNSSHelper.h" +#include "nsNSSShutDown.h" #include "prlog.h" @@ -34,158 +27,139 @@ namespace mozilla { namespace psm { namespace { -const int32_t kDefaultCertAllocLength = 2048; - -enum { - UNKNOWN_TYPE = 0, - X509_CA_CERT = 1, - X509_USER_CERT = 2, - X509_EMAIL_CERT = 3, - X509_SERVER_CERT = 4 -}; - -/* other mime types that we should handle sometime: - - application/x-pkcs7-mime - application/pkcs7-signature - application/pre-encrypted - -*/ - -uint32_t -getPSMContentType(const char* aContentType) -{ - // Don't forget to update the registration of content listeners in nsNSSModule.cpp - // for every supported content type. - - if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert")) - return X509_CA_CERT; - if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert")) - return X509_SERVER_CERT; - if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert")) - return X509_USER_CERT; - if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert")) - return X509_EMAIL_CERT; - - return UNKNOWN_TYPE; -} - -int64_t -ComputeContentLength(nsIRequest* request) -{ - nsCOMPtr channel(do_QueryInterface(request)); - if (!channel) { - return -1; - } - - int64_t contentLength; - nsresult rv = channel->GetContentLength(&contentLength); - if (NS_FAILED(rv) || contentLength <= 0) { - return kDefaultCertAllocLength; - } - - if (contentLength > INT32_MAX) { - return -1; - } - - return contentLength; -} - -class ImportCertRunnable : public nsRunnable +class PSMContentDownloader : public nsIStreamListener { public: - ImportCertRunnable(PSMContentStreamListener* streamer) - : mStreamer(streamer) - { - } + PSMContentDownloader() {NS_ASSERTION(false, "don't use this constructor."); } + explicit PSMContentDownloader(uint32_t type); + void setSilentDownload(bool flag); - NS_IMETHOD Run() - { - mStreamer->ImportCertificate(); - return NS_OK; - } + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER -private: - nsRefPtr mStreamer; + enum {UNKNOWN_TYPE = 0}; + enum {X509_CA_CERT = 1}; + enum {X509_USER_CERT = 2}; + enum {X509_EMAIL_CERT = 3}; + enum {X509_SERVER_CERT = 4}; + +protected: + virtual ~PSMContentDownloader(); + + char* mByteData; + int32_t mBufferOffset; + int32_t mBufferSize; + uint32_t mType; + nsCOMPtr mURI; }; - -} // unnamed namespace - -/* ------------------------ - * PSMContentStreamListener - * ------------------------ */ - -PSMContentStreamListener::PSMContentStreamListener(uint32_t type) - : mType(type) +PSMContentDownloader::PSMContentDownloader(uint32_t type) + : mByteData(nullptr), + mType(type) { } -PSMContentStreamListener::~PSMContentStreamListener() +PSMContentDownloader::~PSMContentDownloader() { + if (mByteData) + free(mByteData); } -NS_IMPL_ISUPPORTS(PSMContentStreamListener, nsIStreamListener, nsIRequestObserver) +NS_IMPL_ISUPPORTS(PSMContentDownloader, nsIStreamListener, nsIRequestObserver) + +const int32_t kDefaultCertAllocLength = 2048; NS_IMETHODIMP -PSMContentStreamListener::OnStartRequest(nsIRequest* request, nsISupports* context) +PSMContentDownloader::OnStartRequest(nsIRequest* request, nsISupports* context) { + nsresult rv; PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStartRequest\n")); + nsCOMPtr channel(do_QueryInterface(request)); + if (!channel) return NS_ERROR_FAILURE; - int64_t contentLength = ComputeContentLength(request); - if (contentLength < 0) { - return NS_ERROR_FAILURE; - } + // Get the URI // + channel->GetURI(getter_AddRefs(mURI)); - mByteData.SetCapacity(contentLength); + int64_t contentLength; + rv = channel->GetContentLength(&contentLength); + if (NS_FAILED(rv) || contentLength <= 0) + contentLength = kDefaultCertAllocLength; + if (contentLength > INT32_MAX) + return NS_ERROR_OUT_OF_MEMORY; + + mBufferOffset = 0; + mBufferSize = 0; + mByteData = (char*)moz_xmalloc(AssertedCast(contentLength)); + if (!mByteData) + return NS_ERROR_OUT_OF_MEMORY; + + mBufferSize = int32_t(contentLength); return NS_OK; } NS_IMETHODIMP -PSMContentStreamListener::OnDataAvailable(nsIRequest* request, - nsISupports* context, - nsIInputStream* aIStream, - uint64_t aSourceOffset, - uint32_t aLength) +PSMContentDownloader::OnDataAvailable(nsIRequest* request, + nsISupports* context, + nsIInputStream *aIStream, + uint64_t aSourceOffset, + uint32_t aLength) { + if (!mByteData) + return NS_ERROR_OUT_OF_MEMORY; + + uint32_t amt; + nsresult err; + //Do a check to see if we need to allocate more memory. + if ((mBufferOffset + (int32_t)aLength) > mBufferSize) { + size_t newSize = (mBufferOffset + aLength) *2; // grow some more than needed + char *newBuffer; + newBuffer = (char*)moz_xrealloc(mByteData, newSize); + if (!newBuffer) { + return NS_ERROR_OUT_OF_MEMORY; + } + mByteData = newBuffer; + mBufferSize = newSize; + } + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnDataAvailable\n")); - - nsCString chunk; - nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength); - if (NS_FAILED(rv)) { - return rv; - } - - mByteData.Append(chunk); + do { + err = aIStream->Read(mByteData+mBufferOffset, + aLength, &amt); + if (NS_FAILED(err)) return err; + if (amt == 0) break; + + aLength -= amt; + mBufferOffset += amt; + + } while (aLength > 0); + return NS_OK; } NS_IMETHODIMP -PSMContentStreamListener::OnStopRequest(nsIRequest* request, - nsISupports* context, - nsresult aStatus) +PSMContentDownloader::OnStopRequest(nsIRequest* request, + nsISupports* context, + nsresult aStatus) { + nsNSSShutDownPreventionLock locker; + //Check if the download succeeded - it might have failed due to + //network issues, etc. + if (NS_FAILED(aStatus)){ + return aStatus; + } + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStopRequest\n")); - // Because importing the cert can spin the event loop (via alerts), we can't - // do it here. Do it off the event loop instead. - nsCOMPtr r = new ImportCertRunnable(this); - MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r))); - - return NS_OK; -} - -void -PSMContentStreamListener::ImportCertificate() -{ nsCOMPtr certdb; + nsresult rv; nsCOMPtr ctx = new PipUIContext(); switch (mType) { - case X509_CA_CERT: - case X509_USER_CERT: - case X509_EMAIL_CERT: + case PSMContentDownloader::X509_CA_CERT: + case PSMContentDownloader::X509_USER_CERT: + case PSMContentDownloader::X509_EMAIL_CERT: certdb = do_GetService(NS_X509CERTDB_CONTRACTID); break; @@ -193,172 +167,48 @@ PSMContentStreamListener::ImportCertificate() break; } - if (!certdb) { - return; - } - switch (mType) { - case X509_CA_CERT: - certdb->ImportCertificates(reinterpret_cast(mByteData.BeginWriting()), - mByteData.Length(), mType, ctx); - break; - - case X509_USER_CERT: - certdb->ImportUserCertificate(reinterpret_cast(mByteData.BeginWriting()), - mByteData.Length(), ctx); - break; - - case X509_EMAIL_CERT: - certdb->ImportEmailCertificate(reinterpret_cast(mByteData.BeginWriting()), - mByteData.Length(), ctx); - break; - + case PSMContentDownloader::X509_CA_CERT: + return certdb->ImportCertificates((uint8_t*)mByteData, mBufferOffset, mType, ctx); + case PSMContentDownloader::X509_USER_CERT: + return certdb->ImportUserCertificate((uint8_t*)mByteData, mBufferOffset, ctx); + case PSMContentDownloader::X509_EMAIL_CERT: + return certdb->ImportEmailCertificate((uint8_t*)mByteData, mBufferOffset, ctx); default: + rv = NS_ERROR_FAILURE; break; } -} - -/* ------------------------ - * PSMContentDownloaderParent - * ------------------------ */ - -PSMContentDownloaderParent::PSMContentDownloaderParent(uint32_t type) - : PSMContentStreamListener(type) - , mIPCOpen(true) -{ -} - -PSMContentDownloaderParent::~PSMContentDownloaderParent() -{ -} - -bool -PSMContentDownloaderParent::RecvOnStartRequest(const uint32_t& contentLength) -{ - mByteData.SetCapacity(contentLength); - return true; -} - -bool -PSMContentDownloaderParent::RecvOnDataAvailable(const nsCString& data, - const uint64_t& offset, - const uint32_t& count) -{ - mByteData.Append(data); - return true; -} - -bool -PSMContentDownloaderParent::RecvOnStopRequest(const nsresult& code) -{ - if (NS_SUCCEEDED(code)) { - // See also PSMContentStreamListener::OnStopRequest. In this case, we don't - // have to dispatch ImportCertificate off of an event because we don't have - // to worry about Necko sending "clean up" events and destroying us if - // ImportCertificate spins the event loop. - ImportCertificate(); - } - - if (mIPCOpen) { - mozilla::unused << Send__delete__(this); - } - return true; -} - -NS_IMETHODIMP -PSMContentDownloaderParent::OnStopRequest(nsIRequest* request, nsISupports* context, nsresult code) -{ - nsresult rv = PSMContentStreamListener::OnStopRequest(request, context, code); - - if (mIPCOpen) { - mozilla::unused << Send__delete__(this); - } + return rv; } -bool -PSMContentDownloaderParent::RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent* diverter) -{ - MOZ_ASSERT(diverter); - auto p = static_cast(diverter); - p->DivertTo(this); - mozilla::unused << p->Send__delete__(p); - return true; +/* other mime types that we should handle sometime: + + application/x-pkcs7-mime + application/pkcs7-signature + application/pre-encrypted + +*/ + +uint32_t +getPSMContentType(const char * aContentType) +{ + // Don't forget to update the registration of content listeners in nsNSSModule.cpp + // for every supported content type. + + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert")) + return PSMContentDownloader::X509_CA_CERT; + else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert")) + return PSMContentDownloader::X509_SERVER_CERT; + else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert")) + return PSMContentDownloader::X509_USER_CERT; + else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert")) + return PSMContentDownloader::X509_EMAIL_CERT; + + return PSMContentDownloader::UNKNOWN_TYPE; } -void -PSMContentDownloaderParent::ActorDestroy(ActorDestroyReason why) -{ - mIPCOpen = false; -} - -/* ------------------------ - * PSMContentDownloaderChild - * ------------------------ */ - -NS_IMPL_ISUPPORTS(PSMContentDownloaderChild, nsIStreamListener) - -PSMContentDownloaderChild::PSMContentDownloaderChild() -{ -} - -PSMContentDownloaderChild::~PSMContentDownloaderChild() -{ -} - -NS_IMETHODIMP -PSMContentDownloaderChild::OnStartRequest(nsIRequest* request, nsISupports* context) -{ - nsCOMPtr divertable = do_QueryInterface(request); - if (divertable) { - mozilla::net::ChannelDiverterChild* diverter = nullptr; - nsresult rv = divertable->DivertToParent(&diverter); - if (NS_FAILED(rv)) { - return rv; - } - MOZ_ASSERT(diverter); - - return SendDivertToParentUsing(diverter) ? NS_OK : NS_ERROR_FAILURE; - } - - int64_t contentLength = ComputeContentLength(request); - if (contentLength < 0) { - return NS_ERROR_FAILURE; - } - - mozilla::unused << SendOnStartRequest(contentLength); - return NS_OK; -} - -NS_IMETHODIMP -PSMContentDownloaderChild::OnDataAvailable(nsIRequest* request, - nsISupports* context, - nsIInputStream* aIStream, - uint64_t aSourceOffset, - uint32_t aLength) -{ - nsCString chunk; - nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength); - if (NS_FAILED(rv)) { - return rv; - } - - mozilla::unused << SendOnDataAvailable(chunk, aSourceOffset, aLength); - return NS_OK; -} - -NS_IMETHODIMP -PSMContentDownloaderChild::OnStopRequest(nsIRequest* request, - nsISupports* context, - nsresult aStatus) -{ - mozilla::unused << SendOnStopRequest(aStatus); - return NS_OK; -} - -/* ------------------------ - * PSMContentListener - * ------------------------ */ +} // unnamed namespace NS_IMPL_ISUPPORTS(PSMContentListener, nsIURIContentListener, @@ -381,7 +231,7 @@ PSMContentListener::init() } NS_IMETHODIMP -PSMContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen) +PSMContentListener::OnStartURIOpen(nsIURI *aURI, bool *aAbortOpen) { //if we don't want to handle the URI, return true in //*aAbortOpen @@ -389,77 +239,73 @@ PSMContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen) } NS_IMETHODIMP -PSMContentListener::IsPreferred(const char* aContentType, - char** aDesiredContentType, - bool* aCanHandleContent) +PSMContentListener::IsPreferred(const char * aContentType, + char ** aDesiredContentType, + bool * aCanHandleContent) { return CanHandleContent(aContentType, true, aDesiredContentType, aCanHandleContent); } NS_IMETHODIMP -PSMContentListener::CanHandleContent(const char* aContentType, +PSMContentListener::CanHandleContent(const char * aContentType, bool aIsContentPreferred, - char** aDesiredContentType, - bool* aCanHandleContent) + char ** aDesiredContentType, + bool * aCanHandleContent) { - uint32_t type = getPSMContentType(aContentType); - *aCanHandleContent = (type != UNKNOWN_TYPE); + uint32_t type; + type = getPSMContentType(aContentType); + if (type == PSMContentDownloader::UNKNOWN_TYPE) { + *aCanHandleContent = false; + } else { + *aCanHandleContent = true; + } return NS_OK; } NS_IMETHODIMP -PSMContentListener::DoContent(const nsACString& aContentType, +PSMContentListener::DoContent(const nsACString & aContentType, bool aIsContentPreferred, - nsIRequest* aRequest, - nsIStreamListener** aContentHandler, - bool* aAbortProcess) + nsIRequest * aRequest, + nsIStreamListener ** aContentHandler, + bool * aAbortProcess) { uint32_t type; type = getPSMContentType(PromiseFlatCString(aContentType).get()); - if (gPIPNSSLog) { - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n")); - } - if (type != UNKNOWN_TYPE) { - nsCOMPtr downloader; - if (XRE_GetProcessType() == GeckoProcessType_Default) { - downloader = new PSMContentStreamListener(type); - } else { - downloader = static_cast( - dom::ContentChild::GetSingleton()->SendPPSMContentDownloaderConstructor(type)); - } - - downloader.forget(aContentHandler); + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n")); + if (type != PSMContentDownloader::UNKNOWN_TYPE) { + nsRefPtr downLoader = new PSMContentDownloader(type); + downLoader.forget(aContentHandler); return NS_OK; } return NS_ERROR_FAILURE; } NS_IMETHODIMP -PSMContentListener::GetLoadCookie(nsISupports** aLoadCookie) +PSMContentListener::GetLoadCookie(nsISupports * *aLoadCookie) { - nsCOMPtr loadCookie(mLoadCookie); - loadCookie.forget(aLoadCookie); + *aLoadCookie = mLoadCookie; + NS_IF_ADDREF(*aLoadCookie); return NS_OK; } NS_IMETHODIMP -PSMContentListener::SetLoadCookie(nsISupports* aLoadCookie) +PSMContentListener::SetLoadCookie(nsISupports * aLoadCookie) { mLoadCookie = aLoadCookie; return NS_OK; } NS_IMETHODIMP -PSMContentListener::GetParentContentListener(nsIURIContentListener** aContentListener) +PSMContentListener::GetParentContentListener(nsIURIContentListener ** aContentListener) { - nsCOMPtr listener(mParentContentListener); - listener.forget(aContentListener); + *aContentListener = mParentContentListener; + NS_IF_ADDREF(*aContentListener); return NS_OK; } NS_IMETHODIMP -PSMContentListener::SetParentContentListener(nsIURIContentListener* aContentListener) +PSMContentListener::SetParentContentListener(nsIURIContentListener * aContentListener) { mParentContentListener = aContentListener; return NS_OK; diff --git a/security/manager/ssl/src/PSMContentListener.h b/security/manager/ssl/src/PSMContentListener.h index 13bff90b7c49..49239029bfc8 100644 --- a/security/manager/ssl/src/PSMContentListener.h +++ b/security/manager/ssl/src/PSMContentListener.h @@ -10,84 +10,12 @@ #include "nsCOMPtr.h" #include "nsIURIContentListener.h" #include "nsWeakReference.h" -#include "mozilla/psm/PPSMContentDownloaderChild.h" -#include "mozilla/psm/PPSMContentDownloaderParent.h" #define NS_PSMCONTENTLISTEN_CID {0xc94f4a30, 0x64d7, 0x11d4, {0x99, 0x60, 0x00, 0xb0, 0xd0, 0x23, 0x54, 0xa0}} #define NS_PSMCONTENTLISTEN_CONTRACTID "@mozilla.org/security/psmdownload;1" -namespace mozilla { -namespace net { - -class PChannelDiverterParent; - -} -} - namespace mozilla { namespace psm { -// PSMContentStreamListener for parent-process downloading. -class PSMContentStreamListener : public nsIStreamListener -{ -public: - explicit PSMContentStreamListener(uint32_t type); - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - void ImportCertificate(); - -protected: - virtual ~PSMContentStreamListener(); - - nsCString mByteData; - uint32_t mType; -}; - -// Parent actor for importing a remote cert when the load was started by the -// child. -class PSMContentDownloaderParent : public PPSMContentDownloaderParent - , public PSMContentStreamListener -{ -public: - explicit PSMContentDownloaderParent(uint32_t type); - - virtual bool RecvOnStartRequest(const uint32_t &contentLength) override; - virtual bool RecvOnDataAvailable(const nsCString &data, - const uint64_t &offset, - const uint32_t &count) override; - virtual bool RecvOnStopRequest(const nsresult &code) override; - - // We inherit most of nsIStreamListener from PSMContentStreamListener, but - // we have to override OnStopRequest to know when we're done with our IPC - // ref. - NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *aContext, nsresult code) override; - - virtual bool RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent *diverter) override; - -protected: - virtual ~PSMContentDownloaderParent(); - - virtual void ActorDestroy(ActorDestroyReason why) override; - bool mIPCOpen; -}; - -// Child actor for importing a cert. -class PSMContentDownloaderChild : public nsIStreamListener - , public PPSMContentDownloaderChild -{ -public: - PSMContentDownloaderChild(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - -private: - ~PSMContentDownloaderChild(); -}; - - class PSMContentListener : public nsIURIContentListener, public nsSupportsWeakReference { diff --git a/security/manager/ssl/src/moz.build b/security/manager/ssl/src/moz.build index 2efc4a6ae4f9..75276a43d168 100644 --- a/security/manager/ssl/src/moz.build +++ b/security/manager/ssl/src/moz.build @@ -23,10 +23,6 @@ EXPORTS.mozilla += [ 'PublicSSL.h', ] -EXPORTS.mozilla.psm += [ - 'PSMContentListener.h', -] - UNIFIED_SOURCES += [ 'CryptoTask.cpp', 'nsCertOverrideService.cpp', @@ -78,10 +74,6 @@ SOURCES += [ 'nsNSSCertificateDB.cpp', ] -IPDL_SOURCES += [ - 'PPSMContentDownloader.ipdl', -] - LOCAL_INCLUDES += [ '/security/manager/boot/src', ] diff --git a/security/manager/ssl/src/nsNSSModule.cpp b/security/manager/ssl/src/nsNSSModule.cpp index 8ec8fe936a2f..c407d91be05e 100644 --- a/security/manager/ssl/src/nsNSSModule.cpp +++ b/security/manager/ssl/src/nsNSSModule.cpp @@ -135,20 +135,14 @@ _InstanceClassChrome##Constructor(nsISupports *aOuter, REFNSIID aIID, \ { \ nsresult rv; \ \ - *aResult = nullptr; \ - if (nullptr != aOuter) { \ + *aResult = nullptr; \ + if (nullptr != aOuter) { \ rv = NS_ERROR_NO_AGGREGATION; \ return rv; \ } \ \ - if (!NS_IS_PROCESS_DEFAULT && \ - ensureOperator == nssEnsureChromeOrContent) { \ - if (!EnsureNSSInitializedChromeOrContent()) { \ - return NS_ERROR_FAILURE; \ - } \ - } else if (!EnsureNSSInitialized(ensureOperator)) { \ + if (!EnsureNSSInitialized(ensureOperator)) \ return NS_ERROR_FAILURE; \ - } \ \ if (NS_IS_PROCESS_DEFAULT) \ NS_NSS_INSTANTIATE_INIT(ensureOperator, \ @@ -188,7 +182,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsTLSSocketProvider) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsSecretDecoderRing) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPK11TokenDB) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPKCS11ModuleDB) -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PSMContentListener, init) +NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, PSMContentListener, init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly, nsNSSCertificate, nsNSSCertificateFakeTransport) From 17b87281f242f4f1149e7979bb3a5a80b1da5fca Mon Sep 17 00:00:00 2001 From: Francois Marier Date: Wed, 22 Apr 2015 21:01:37 +1200 Subject: [PATCH 152/241] Bug 1147212 - Add support for goog-unwanted-shavar. r=gcp,r=matej,r=smaug --HG-- rename : toolkit/components/url-classifier/tests/mochitest/evilWorker.js => toolkit/components/url-classifier/tests/mochitest/unwantedWorker.js extra : rebase_source : efe09564160fb2fcb1adb5f6599183f053268c40 --- .../chrome/overrides/appstrings.properties | 1 + browser/base/content/aboutNetError.xhtml | 2 + browser/base/content/blockedSite.xhtml | 58 ++++++++++++++++++- browser/base/content/browser.js | 47 +++++++-------- browser/base/content/content.js | 8 ++- .../content/test/browser_bug400731.js | 19 ++++++ .../safebrowsing/content/test/head.js | 2 +- .../en-US/chrome/browser/browser.properties | 1 + .../phishing-afterload-warning-message.dtd | 5 ++ .../chrome/overrides/appstrings.properties | 1 + .../en-US/chrome/overrides/netError.dtd | 5 ++ .../base/content/contenthandlers/Content.js | 11 +--- docshell/base/nsDocShell.cpp | 13 ++++- docshell/resources/content/netError.xhtml | 2 + .../BrowserElementChildPreload.js | 3 + .../en-US/chrome/appstrings.properties | 1 + dom/locales/en-US/chrome/netError.dtd | 5 ++ .../android/chrome/content/blockedSite.xhtml | 50 +++++++++++++++- mobile/android/chrome/content/browser.js | 33 ++++------- .../android/locales/en-US/chrome/phishing.dtd | 5 ++ .../en-US/overrides/appstrings.properties | 1 + modules/libpref/init/all.js | 4 +- .../boot/public/nsISecurityUITelemetry.idl | 15 ++++- .../url-classifier/SafeBrowsing.jsm | 10 +++- .../nsUrlClassifierDBService.cpp | 3 + .../tests/mochitest/classifierFrame.html | 4 +- .../tests/mochitest/mochitest.ini | 1 + .../tests/mochitest/test_classifier.html | 10 +++- .../mochitest/test_classifier_worker.html | 10 +++- .../tests/mochitest/unwantedWorker.js | 3 + .../tests/mochitest/workerFrame.html | 18 +++++- .../tests/unit/head_urlclassifier.js | 18 +++++- .../tests/unit/test_dbservice.js | 35 ++++++++--- .../tests/unit/test_streamupdater.js | 12 +++- .../viewsource/content/viewSource.js | 26 ++------- .../webapprt/overrides/appstrings.properties | 1 + xpcom/base/ErrorList.h | 1 + 37 files changed, 332 insertions(+), 112 deletions(-) create mode 100644 toolkit/components/url-classifier/tests/mochitest/unwantedWorker.js diff --git a/b2g/locales/en-US/chrome/overrides/appstrings.properties b/b2g/locales/en-US/chrome/overrides/appstrings.properties index 805a725527ff..e212f77c8089 100644 --- a/b2g/locales/en-US/chrome/overrides/appstrings.properties +++ b/b2g/locales/en-US/chrome/overrides/appstrings.properties @@ -30,6 +30,7 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences. phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. cspBlocked=This page has a content security policy that prevents it from being loaded in this way. corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected. diff --git a/browser/base/content/aboutNetError.xhtml b/browser/base/content/aboutNetError.xhtml index 5a7bd1879b1a..c2eb60e103db 100644 --- a/browser/base/content/aboutNetError.xhtml +++ b/browser/base/content/aboutNetError.xhtml @@ -374,6 +374,7 @@

    &nssFailure2.title;

    &nssBadCert.title;

    &malwareBlocked.title;

    +

    &unwantedBlocked.title;

    &cspBlocked.title;

    &remoteXUL.title;

    &corruptedContentError.title;

    @@ -401,6 +402,7 @@
    &nssFailure2.longDesc2;
    &nssBadCert.longDesc2;
    &malwareBlocked.longDesc;
    +
    &unwantedBlocked.longDesc;
    &cspBlocked.longDesc;
    &remoteXUL.longDesc;
    &corruptedContentError.longDesc;
    diff --git a/browser/base/content/blockedSite.xhtml b/browser/base/content/blockedSite.xhtml index 99c495000d6e..27810a408aaf 100644 --- a/browser/base/content/blockedSite.xhtml +++ b/browser/base/content/blockedSite.xhtml @@ -79,6 +79,9 @@ case "phishingBlocked" : initPage_phishing(); break; + case "unwantedBlocked" : + initPage_unwanted(); + break; } } @@ -87,7 +90,7 @@ */ function initPage_malware() { - // Remove phishing strings + // Remove phishing and unwanted strings var el = document.getElementById("errorTitleText_phishing"); el.parentNode.removeChild(el); @@ -97,18 +100,57 @@ el = document.getElementById("errorLongDescText_phishing"); el.parentNode.removeChild(el); + el = document.getElementById("errorTitleText_unwanted"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorShortDescText_unwanted"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorLongDescText_unwanted"); + el.parentNode.removeChild(el); + // Set sitename document.getElementById("malware_sitename").textContent = getHostString(); document.title = document.getElementById("errorTitleText_malware") .innerHTML; } + /** + * Initialize custom strings and functionality for blocked malware case + */ + function initPage_unwanted() + { + // Remove phishing and malware strings + var el = document.getElementById("errorTitleText_phishing"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorShortDescText_phishing"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorLongDescText_phishing"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorTitleText_malware"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorShortDescText_malware"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorLongDescText_malware"); + el.parentNode.removeChild(el); + + // Set sitename + document.getElementById("unwanted_sitename").textContent = getHostString(); + document.title = document.getElementById("errorTitleText_unwanted") + .innerHTML; + } + /** * Initialize custom strings and functionality for blocked phishing case */ function initPage_phishing() { - // Remove malware strings + // Remove malware and unwanted strings var el = document.getElementById("errorTitleText_malware"); el.parentNode.removeChild(el); @@ -118,6 +160,15 @@ el = document.getElementById("errorLongDescText_malware"); el.parentNode.removeChild(el); + el = document.getElementById("errorTitleText_unwanted"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorShortDescText_unwanted"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorLongDescText_unwanted"); + el.parentNode.removeChild(el); + // Set sitename document.getElementById("phishing_sitename").textContent = getHostString(); document.title = document.getElementById("errorTitleText_phishing") @@ -161,6 +212,7 @@

    &safeb.blocked.phishingPage.title;

    &safeb.blocked.malwarePage.title;

    +

    &safeb.blocked.unwantedPage.title;

    @@ -169,12 +221,14 @@

    &safeb.blocked.phishingPage.shortDesc;

    &safeb.blocked.malwarePage.shortDesc;

    +

    &safeb.blocked.unwantedPage.shortDesc;

    &safeb.blocked.phishingPage.longDesc;

    &safeb.blocked.malwarePage.longDesc;

    +

    &safeb.blocked.unwantedPage.longDesc;

    diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 79e0a0b3d8c9..dc61724d052f 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2659,7 +2659,7 @@ let BrowserOnClick = { msg.data.sslStatusAsString); break; case "Browser:SiteBlockedError": - this.onAboutBlocked(msg.data.elementId, msg.data.isMalware, + this.onAboutBlocked(msg.data.elementId, msg.data.reason, msg.data.isTopFrame, msg.data.location); break; case "Browser:EnableOnlineMode": @@ -2843,10 +2843,15 @@ let BrowserOnClick = { } }, - onAboutBlocked: function (elementId, isMalware, isTopFrame, location) { - // Depending on what page we are displaying here (malware/phishing) + onAboutBlocked: function (elementId, reason, isTopFrame, location) { + // Depending on what page we are displaying here (malware/phishing/unwanted) // use the right strings and links for each. - let bucketName = isMalware ? "WARNING_MALWARE_PAGE_":"WARNING_PHISHING_PAGE_"; + let bucketName = "WARNING_PHISHING_PAGE_"; + if (reason === 'malware') { + bucketName = "WARNING_MALWARE_PAGE_"; + } else if (reason === 'unwanted') { + bucketName = "WARNING_UNWANTED_PAGE_"; + } let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI"); let nsISecTel = Ci.nsISecurityUITelemetry; bucketName += isTopFrame ? "TOP_" : "FRAME_"; @@ -2857,33 +2862,19 @@ let BrowserOnClick = { break; case "reportButton": - // This is the "Why is this site blocked" button. For malware, - // we can fetch a site-specific report, for phishing, we redirect - // to the generic page describing phishing protection. + // This is the "Why is this site blocked" button. We redirect + // to the generic page describing phishing/malware protection. - // We log even if malware/phishing info URL couldn't be found: + // We log even if malware/phishing/unwanted info URL couldn't be found: // the measurement is for how many users clicked the WHY BLOCKED button secHistogram.add(nsISecTel[bucketName + "WHY_BLOCKED"]); - if (isMalware) { - // Get the stop badware "why is this blocked" report url, - // append the current url, and go there. - try { - let reportURL = formatURL("browser.safebrowsing.malware.reportURL", true); - reportURL += location; - gBrowser.loadURI(reportURL); - } catch (e) { - Components.utils.reportError("Couldn't get malware report URL: " + e); - } - } - else { // It's a phishing site, not malware - openHelpLink("phishing-malware", false, "current"); - } + openHelpLink("phishing-malware", false, "current"); break; case "ignoreWarningButton": secHistogram.add(nsISecTel[bucketName + "IGNORE_WARNING"]); - this.ignoreWarningButton(isMalware); + this.ignoreWarningButton(reason); break; } }, @@ -2910,7 +2901,7 @@ let BrowserOnClick = { } }, - ignoreWarningButton: function (isMalware) { + ignoreWarningButton: function (reason) { // Allow users to override and continue through to the site, // but add a notify bar as a reminder, so that they don't lose // track after, e.g., tab switching. @@ -2929,7 +2920,7 @@ let BrowserOnClick = { }]; let title; - if (isMalware) { + if (reason === 'malware') { title = gNavigatorBundle.getString("safebrowsing.reportedAttackSite"); buttons[1] = { label: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.label"), @@ -2938,7 +2929,7 @@ let BrowserOnClick = { openUILinkIn(gSafeBrowsing.getReportURL('MalwareError'), 'tab'); } }; - } else { + } else if (reason === 'phishing') { title = gNavigatorBundle.getString("safebrowsing.reportedWebForgery"); buttons[1] = { label: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.label"), @@ -2947,6 +2938,10 @@ let BrowserOnClick = { openUILinkIn(gSafeBrowsing.getReportURL('Error'), 'tab'); } }; + } else if (reason === 'unwanted') { + title = gNavigatorBundle.getString("safebrowsing.reportedUnwantedSite"); + // There is no button for reporting errors since Google doesn't currently + // provide a URL endpoint for these reports. } let notificationBox = gBrowser.getNotificationBox(); diff --git a/browser/base/content/content.js b/browser/base/content/content.js index 85b27c5c03d1..12bfb5a63717 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -384,9 +384,15 @@ let ClickEventHandler = { }, onAboutBlocked: function (targetElement, ownerDoc) { + var reason = 'phishing'; + if (/e=malwareBlocked/.test(ownerDoc.documentURI)) { + reason = 'malware'; + } else if (/e=unwantedBlocked/.test(ownerDoc.documentURI)) { + reason = 'unwanted'; + } sendAsyncMessage("Browser:SiteBlockedError", { location: ownerDoc.location.href, - isMalware: /e=malwareBlocked/.test(ownerDoc.documentURI), + reason: reason, elementId: targetElement.getAttribute("id"), isTopFrame: (ownerDoc.defaultView.parent === ownerDoc.defaultView) }); diff --git a/browser/components/safebrowsing/content/test/browser_bug400731.js b/browser/components/safebrowsing/content/test/browser_bug400731.js index ca73c44f5a37..f6b9505e3c1f 100644 --- a/browser/components/safebrowsing/content/test/browser_bug400731.js +++ b/browser/components/safebrowsing/content/test/browser_bug400731.js @@ -34,6 +34,25 @@ function testMalware(event) { var style = content.getComputedStyle(el, null); is(style.display, "inline-block", "Ignore Warning button should be display:inline-block for malware"); + // Now launch the unwanted software test + window.addEventListener("DOMContentLoaded", testUnwanted, true); + content.location = "http://www.itisatrap.org/firefox/unwanted.html"; +} + +function testUnwanted(event) { + if (event.target != gBrowser.selectedBrowser.contentDocument) { + return; + } + + window.removeEventListener("DOMContentLoaded", testUnwanted, true); + + // Confirm that "Ignore this warning" is visible - bug 422410 + var el = content.document.getElementById("ignoreWarningButton"); + ok(el, "Ignore warning button should be present for unwanted software"); + + var style = content.getComputedStyle(el, null); + is(style.display, "inline-block", "Ignore Warning button should be display:inline-block for unwanted software"); + // Now launch the phishing test window.addEventListener("DOMContentLoaded", testPhishing, true); content.location = "http://www.itisatrap.org/firefox/its-a-trap.html"; diff --git a/browser/components/safebrowsing/content/test/head.js b/browser/components/safebrowsing/content/test/head.js index 886eff5ab245..6ba547739157 100644 --- a/browser/components/safebrowsing/content/test/head.js +++ b/browser/components/safebrowsing/content/test/head.js @@ -1,5 +1,5 @@ // Force SafeBrowsing to be initialized for the tests -Services.prefs.setCharPref("urlclassifier.malwareTable", "test-malware-simple"); +Services.prefs.setCharPref("urlclassifier.malwareTable", "test-malware-simple,test-unwanted-simple"); Services.prefs.setCharPref("urlclassifier.phishTable", "test-phish-simple"); SafeBrowsing.init(); diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 6d872848f0b3..49115bdb68da 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -398,6 +398,7 @@ safebrowsing.notAForgeryButton.accessKey=F safebrowsing.reportedAttackSite=Reported Attack Site! safebrowsing.notAnAttackButton.label=This isn't an attack site… safebrowsing.notAnAttackButton.accessKey=A +safebrowsing.reportedUnwantedSite=Reported Unwanted Software Site! # Ctrl-Tab # LOCALIZATION NOTE (ctrlTab.listAllTabs.label): #1 represents the number diff --git a/browser/locales/en-US/chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd b/browser/locales/en-US/chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd index eb8b71dc7788..aa970502c638 100644 --- a/browser/locales/en-US/chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd +++ b/browser/locales/en-US/chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd @@ -12,6 +12,11 @@ has been reported as an attack page and has been blocked based on your security preferences."> Attack pages try to install programs that steal private information, use your computer to attack others, or damage your system.

    Some attack pages intentionally distribute harmful software, but many are compromised without the knowledge or permission of their owners.

    "> + + + has been reported to contain unwanted software and has been blocked based on your security preferences."> +Unwanted software pages try to install software that can be deceptive and affect your system in unexpected ways.

    "> + has been reported as a web forgery and has been blocked based on your security preferences."> diff --git a/browser/locales/en-US/chrome/overrides/appstrings.properties b/browser/locales/en-US/chrome/overrides/appstrings.properties index 14fad72c0c29..7ed699dcf0ff 100644 --- a/browser/locales/en-US/chrome/overrides/appstrings.properties +++ b/browser/locales/en-US/chrome/overrides/appstrings.properties @@ -30,6 +30,7 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences. phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. cspBlocked=This page has a content security policy that prevents it from being loaded in this way. corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected. diff --git a/browser/locales/en-US/chrome/overrides/netError.dtd b/browser/locales/en-US/chrome/overrides/netError.dtd index 78b32f0be698..e965b78338f7 100644 --- a/browser/locales/en-US/chrome/overrides/netError.dtd +++ b/browser/locales/en-US/chrome/overrides/netError.dtd @@ -164,6 +164,11 @@ be temporary, and you can try again later.
  • Website owners who believe their site has been reported as an attack site in error may request a review.

    "> + +Unwanted software pages try to install software that can be deceptive and affect your system in unexpected ways.

    +"> + Entering any personal information on this page may result in identity theft or other fraud.

    diff --git a/browser/metro/base/content/contenthandlers/Content.js b/browser/metro/base/content/contenthandlers/Content.js index 5eb7d4259c23..ef2bf127f649 100644 --- a/browser/metro/base/content/contenthandlers/Content.js +++ b/browser/metro/base/content/contenthandlers/Content.js @@ -341,20 +341,15 @@ let Content = { } } else if (/^about:blocked/.test(errorDoc.documentURI)) { // The event came from a button on a malware/phishing block page - // First check whether it's malware or phishing, so that we can - // use the right strings/links. - let isMalware = /e=malwareBlocked/.test(errorDoc.documentURI); if (ot == errorDoc.getElementById("getMeOutButton")) { sendAsyncMessage("Browser:BlockedSite", { url: errorDoc.location.href, action: "leave" }); } else if (ot == errorDoc.getElementById("reportButton")) { - // This is the "Why is this site blocked" button. For malware, - // we can fetch a site-specific report, for phishing, we redirect - // to the generic page describing phishing protection. - let action = isMalware ? "report-malware" : "report-phishing"; + // This is the "Why is this site blocked" button. We redirect + // to the generic page describing phishing/malware protection. sendAsyncMessage("Browser:BlockedSite", - { url: errorDoc.location.href, action: action }); + { url: errorDoc.location.href, action: "report-phishing" }); } else if (ot == errorDoc.getElementById("ignoreWarningButton")) { // Allow users to override and continue through to the site, // but add a notify bar as a reminder, so that they don't lose diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 25621c30b192..ad11c018e779 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -5087,7 +5087,8 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI, } } } else if (NS_ERROR_PHISHING_URI == aError || - NS_ERROR_MALWARE_URI == aError) { + NS_ERROR_MALWARE_URI == aError || + NS_ERROR_UNWANTED_URI == aError) { nsAutoCString host; aURI->GetHost(host); CopyUTF8toUTF16(host, formatStrs[0]); @@ -5106,14 +5107,19 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI, error.AssignLiteral("phishingBlocked"); bucketId = IsFrame() ? nsISecurityUITelemetry::WARNING_PHISHING_PAGE_FRAME : nsISecurityUITelemetry::WARNING_PHISHING_PAGE_TOP; - } else { + } else if (NS_ERROR_MALWARE_URI == aError) { error.AssignLiteral("malwareBlocked"); bucketId = IsFrame() ? nsISecurityUITelemetry::WARNING_MALWARE_PAGE_FRAME : nsISecurityUITelemetry::WARNING_MALWARE_PAGE_TOP; + } else { + error.AssignLiteral("unwantedBlocked"); + bucketId = IsFrame() ? nsISecurityUITelemetry::WARNING_UNWANTED_PAGE_FRAME + : nsISecurityUITelemetry::WARNING_UNWANTED_PAGE_TOP; } - if (errorPage.EqualsIgnoreCase("blocked")) + if (errorPage.EqualsIgnoreCase("blocked")) { Telemetry::Accumulate(Telemetry::SECURITY_UI, bucketId); + } cssClass.AssignLiteral("blacklist"); } else if (NS_ERROR_CONTENT_CRASHED == aError) { @@ -7824,6 +7830,7 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress, aStatus == NS_ERROR_OFFLINE || aStatus == NS_ERROR_MALWARE_URI || aStatus == NS_ERROR_PHISHING_URI || + aStatus == NS_ERROR_UNWANTED_URI || aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE || aStatus == NS_ERROR_REMOTE_XUL || aStatus == NS_ERROR_OFFLINE || diff --git a/docshell/resources/content/netError.xhtml b/docshell/resources/content/netError.xhtml index 98d1e72a3d9f..9b9fe7a631eb 100644 --- a/docshell/resources/content/netError.xhtml +++ b/docshell/resources/content/netError.xhtml @@ -291,6 +291,7 @@

    &nssFailure2.title;

    &nssBadCert.title;

    &malwareBlocked.title;

    +

    &unwantedBlocked.title;

    &cspBlocked.title;

    &remoteXUL.title;

    &corruptedContentError.title;

    @@ -317,6 +318,7 @@
    &nssFailure2.longDesc2;
    &nssBadCert.longDesc2;
    &malwareBlocked.longDesc;
    +
    &unwantedBlocked.longDesc;
    &cspBlocked.longDesc;
    &remoteXUL.longDesc;
    &corruptedContentError.longDesc;
    diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index d272235e8559..5e2cdd868c34 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -1292,6 +1292,9 @@ BrowserElementChild.prototype = { case Cr.NS_ERROR_MALWARE_URI : sendAsyncMsg('error', { type: 'malwareBlocked' }); return; + case Cr.NS_ERROR_UNWANTED_URI : + sendAsyncMsg('error', { type: 'unwantedBlocked' }); + return; case Cr.NS_ERROR_OFFLINE : sendAsyncMsg('error', { type: 'offline' }); diff --git a/dom/locales/en-US/chrome/appstrings.properties b/dom/locales/en-US/chrome/appstrings.properties index 3ee5ee7006f2..f5924d53d1cd 100644 --- a/dom/locales/en-US/chrome/appstrings.properties +++ b/dom/locales/en-US/chrome/appstrings.properties @@ -29,6 +29,7 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences. phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. cspBlocked=This page has a content security policy that prevents it from being loaded in this way. corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected. diff --git a/dom/locales/en-US/chrome/netError.dtd b/dom/locales/en-US/chrome/netError.dtd index 533af480039d..b53350579022 100644 --- a/dom/locales/en-US/chrome/netError.dtd +++ b/dom/locales/en-US/chrome/netError.dtd @@ -81,6 +81,11 @@

    Website owners who believe their site has been reported as an attack site in error may request a review.

    "> + +Unwanted software pages try to install software that can be deceptive and affect your system in unexpected ways.

    +"> + Entering any personal information on this page may result in identity theft or other fraud.

    diff --git a/mobile/android/chrome/content/blockedSite.xhtml b/mobile/android/chrome/content/blockedSite.xhtml index ec0ce1685c2c..9392589e2172 100644 --- a/mobile/android/chrome/content/blockedSite.xhtml +++ b/mobile/android/chrome/content/blockedSite.xhtml @@ -80,6 +80,9 @@ case "phishingBlocked" : initPage_phishing(); break; + case "unwantedBlocked" : + initPage_unwanted(); + break; } } @@ -88,15 +91,21 @@ */ function initPage_malware() { - // Remove phishing strings + // Remove phishing/unwanted strings var el = document.getElementById("errorTitleText_phishing"); el.parentNode.removeChild(el); + el = document.getElementById("errorTitleText_unwanted"); + el.parentNode.removeChild(el); el = document.getElementById("errorShortDescText_phishing"); el.parentNode.removeChild(el); + el = document.getElementById("errorShortDescText_unwanted"); + el.parentNode.removeChild(el); el = document.getElementById("errorLongDescText_phishing"); el.parentNode.removeChild(el); + el = document.getElementById("errorLongDescText_unwanted"); + el.parentNode.removeChild(el); // Set sitename document.getElementById("malware_sitename").textContent = getHostString(); @@ -109,19 +118,53 @@ */ function initPage_phishing() { - // Remove malware strings + // Remove malware/unwanted strings var el = document.getElementById("errorTitleText_malware"); el.parentNode.removeChild(el); + el = document.getElementById("errorTitleText_unwanted"); + el.parentNode.removeChild(el); el = document.getElementById("errorShortDescText_malware"); el.parentNode.removeChild(el); + el = document.getElementById("errorShortDescText_unwanted"); + el.parentNode.removeChild(el); el = document.getElementById("errorLongDescText_malware"); el.parentNode.removeChild(el); + el = document.getElementById("errorLongDescText_unwanted"); + el.parentNode.removeChild(el); document.title = document.getElementById("errorTitleText_phishing") .innerHTML; } + + /** + * Initialize custom strings and functionality for blocked unwanted + * software case + */ + function initPage_unwanted() + { + // Remove malware/phishing strings + var el = document.getElementById("errorTitleText_malware"); + el.parentNode.removeChild(el); + el = document.getElementById("errorTitleText_phishing"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorShortDescText_malware"); + el.parentNode.removeChild(el); + el = document.getElementById("errorShortDescText_phishing"); + el.parentNode.removeChild(el); + + el = document.getElementById("errorLongDescText_malware"); + el.parentNode.removeChild(el); + el = document.getElementById("errorLongDescText_phishing"); + el.parentNode.removeChild(el); + + // Set sitename + document.getElementById("unwanted_sitename").textContent = getHostString(); + document.title = document.getElementById("errorTitleText_unwanted") + .innerHTML; + } ]]> @@ -133,6 +176,7 @@

    &safeb.blocked.phishingPage.title2;

    &safeb.blocked.malwarePage.title;

    +

    &safeb.blocked.unwantedPage.title;

    @@ -141,12 +185,14 @@

    &safeb.blocked.phishingPage.shortDesc2;

    &safeb.blocked.malwarePage.shortDesc;

    +

    &safeb.blocked.unwantedPage.shortDesc;

    &safeb.blocked.phishingPage.longDesc2;

    &safeb.blocked.malwarePage.longDesc;

    +

    &safeb.blocked.unwantedPage.longDesc;

    diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index f10f1eef76d3..9b25baa176ff 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -5547,10 +5547,14 @@ var ErrorPageEventHandler = { } } else if (errorDoc.documentURI.startsWith("about:blocked")) { // The event came from a button on a malware/phishing block page - // First check whether it's malware or phishing, so that we can - // use the right strings/links - let isMalware = errorDoc.documentURI.contains("e=malwareBlocked"); - let bucketName = isMalware ? "WARNING_MALWARE_PAGE_" : "WARNING_PHISHING_PAGE_"; + // First check whether it's malware, phishing or unwanted, so that we + // can use the right strings/links + let bucketName = "WARNING_PHISHING_PAGE_"; + if (errorDoc.documentURI.contains("e=malwareBlocked")) { + bucketName = "WARNING_MALWARE_PAGE_"; + } else if (errorDoc.documentURI.contains("e=unwantedBlocked")) { + bucketName = "WARNING_UNWANTED_PAGE_"; + } let nsISecTel = Ci.nsISecurityUITelemetry; let isIframe = (errorDoc.defaultView.parent === errorDoc.defaultView); bucketName += isIframe ? "TOP_" : "FRAME_"; @@ -5565,23 +5569,10 @@ var ErrorPageEventHandler = { // the measurement is for how many users clicked the WHY BLOCKED button Telemetry.addData("SECURITY_UI", nsISecTel[bucketName + "WHY_BLOCKED"]); - // This is the "Why is this site blocked" button. For malware, - // we can fetch a site-specific report, for phishing, we redirect - // to the generic page describing phishing protection. - if (isMalware) { - // Get the stop badware "why is this blocked" report url, append the current url, and go there. - try { - let reportURL = formatter.formatURLPref("browser.safebrowsing.malware.reportURL"); - reportURL += errorDoc.location.href; - BrowserApp.selectedBrowser.loadURI(reportURL); - } catch (e) { - Cu.reportError("Couldn't get malware report URL: " + e); - } - } else { - // It's a phishing site, just link to the generic information page - let url = Services.urlFormatter.formatURLPref("app.support.baseURL"); - BrowserApp.selectedBrowser.loadURI(url + "phishing-malware"); - } + // This is the "Why is this site blocked" button. We redirect + // to the generic page describing phishing/malware protection. + let url = Services.urlFormatter.formatURLPref("app.support.baseURL"); + BrowserApp.selectedBrowser.loadURI(url + "phishing-malware"); } else if (target == errorDoc.getElementById("ignoreWarningButton")) { Telemetry.addData("SECURITY_UI", nsISecTel[bucketName + "IGNORE_WARNING"]); diff --git a/mobile/android/locales/en-US/chrome/phishing.dtd b/mobile/android/locales/en-US/chrome/phishing.dtd index 42e9af98b7ac..c1c1e6ed1d74 100644 --- a/mobile/android/locales/en-US/chrome/phishing.dtd +++ b/mobile/android/locales/en-US/chrome/phishing.dtd @@ -15,3 +15,8 @@ These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.

    "> + + + + has been reported to contain unwanted software and has been blocked based on your security preferences."> + diff --git a/mobile/locales/en-US/overrides/appstrings.properties b/mobile/locales/en-US/overrides/appstrings.properties index 805a725527ff..e4d2ecce4303 100644 --- a/mobile/locales/en-US/overrides/appstrings.properties +++ b/mobile/locales/en-US/overrides/appstrings.properties @@ -31,6 +31,7 @@ externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. +unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences. cspBlocked=This page has a content security policy that prevents it from being loaded in this way. corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected. remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox. diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 77caa0d18a1a..0921383ac5b7 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4477,11 +4477,11 @@ pref("dom.inter-app-communication-api.enabled", false); pref("dom.mapped_arraybuffer.enabled", false); // The tables used for Safebrowsing phishing and malware checks. -pref("urlclassifier.malwareTable", "goog-malware-shavar,test-malware-simple"); +pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,test-malware-simple,test-unwanted-simple"); pref("urlclassifier.phishTable", "goog-phish-shavar,test-phish-simple"); pref("urlclassifier.downloadBlockTable", ""); pref("urlclassifier.downloadAllowTable", ""); -pref("urlclassifier.disallow_completions", "test-malware-simple,test-phish-simple,goog-downloadwhite-digest256,mozpub-track-digest256"); +pref("urlclassifier.disallow_completions", "test-malware-simple,test-phish-simple,test-unwanted-simple,goog-downloadwhite-digest256,mozpub-track-digest256"); // The table and update/gethash URLs for Safebrowsing phishing and malware // checks. diff --git a/security/manager/boot/public/nsISecurityUITelemetry.idl b/security/manager/boot/public/nsISecurityUITelemetry.idl index dd15d161575b..c4b81d3f985c 100644 --- a/security/manager/boot/public/nsISecurityUITelemetry.idl +++ b/security/manager/boot/public/nsISecurityUITelemetry.idl @@ -6,7 +6,7 @@ #include "nsISupports.idl" -[scriptable, uuid(f7259bf4-1f2b-4e9e-8983-1978cc076fa1)] +[scriptable, uuid(56e190a0-2802-4fc4-b09f-bcda357035c3)] interface nsISecurityUITelemetry : nsISupports { @@ -141,6 +141,17 @@ const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_BASE = 84; const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_UNTRUSTED = 1; const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_DOMAIN = 2; const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_TIME = 4; -// This uses up buckets till 91 (including) + +// Another Safe Browsing list (like malware & phishing above) +const uint32_t WARNING_UNWANTED_PAGE_TOP = 92; +const uint32_t WARNING_UNWANTED_PAGE_TOP_WHY_BLOCKED = 93; +const uint32_t WARNING_UNWANTED_PAGE_TOP_GET_ME_OUT_OF_HERE = 94; +const uint32_t WARNING_UNWANTED_PAGE_TOP_IGNORE_WARNING = 95; +const uint32_t WARNING_UNWANTED_PAGE_FRAME = 96; +const uint32_t WARNING_UNWANTED_PAGE_FRAME_WHY_BLOCKED = 97; +const uint32_t WARNING_UNWANTED_PAGE_FRAME_GET_ME_OUT_OF_HERE = 98; +const uint32_t WARNING_UNWANTED_PAGE_FRAME_IGNORE_WARNING = 99; + +// This uses up buckets till 99 (including) // We only have buckets up to 100. }; diff --git a/toolkit/components/url-classifier/SafeBrowsing.jsm b/toolkit/components/url-classifier/SafeBrowsing.jsm index 45d2ea4ca0eb..5593c214d04b 100644 --- a/toolkit/components/url-classifier/SafeBrowsing.jsm +++ b/toolkit/components/url-classifier/SafeBrowsing.jsm @@ -199,8 +199,9 @@ this.SafeBrowsing = { addMozEntries: function() { // Add test entries to the DB. // XXX bug 779008 - this could be done by DB itself? - const phishURL = "itisatrap.org/firefox/its-a-trap.html"; - const malwareURL = "itisatrap.org/firefox/its-an-attack.html"; + const phishURL = "itisatrap.org/firefox/its-a-trap.html"; + const malwareURL = "itisatrap.org/firefox/its-an-attack.html"; + const unwantedURL = "itisatrap.org/firefox/unwanted.html"; let update = "n:1000\ni:test-malware-simple\nad:1\n" + "a:1:32:" + malwareURL.length + "\n" + @@ -208,6 +209,9 @@ this.SafeBrowsing = { update += "n:1000\ni:test-phish-simple\nad:1\n" + "a:1:32:" + phishURL.length + "\n" + phishURL; + update += "n:1000\ni:test-unwanted-simple\nad:1\n" + + "a:1:32:" + unwantedURL.length + "\n" + + unwantedURL; log("addMozEntries:", update); let db = Cc["@mozilla.org/url-classifier/dbservice;1"]. @@ -222,7 +226,7 @@ this.SafeBrowsing = { }; try { - db.beginUpdate(dummyListener, "test-malware-simple,test-phish-simple", ""); + db.beginUpdate(dummyListener, "test-malware-simple,test-phish-simple,test-unwanted-simple", ""); db.beginStream("", ""); db.updateStream(update); db.finishStream(); diff --git a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp index 7bfe066ded6b..44a19a1f0ac1 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp +++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp @@ -188,6 +188,9 @@ TablesToResponse(const nsACString& tables) if (FindInReadable(NS_LITERAL_CSTRING("-track-"), tables)) { return NS_ERROR_TRACKING_URI; } + if (FindInReadable(NS_LITERAL_CSTRING("-unwanted-"), tables)) { + return NS_ERROR_UNWANTED_URI; + } return NS_OK; } diff --git a/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html b/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html index 1a624ac53083..1cd520284779 100644 --- a/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html +++ b/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html @@ -33,8 +33,8 @@ function checkLoads() { - - + + diff --git a/toolkit/components/url-classifier/tests/mochitest/mochitest.ini b/toolkit/components/url-classifier/tests/mochitest/mochitest.ini index 6a0c32e80924..87f2ae1013b5 100644 --- a/toolkit/components/url-classifier/tests/mochitest/mochitest.ini +++ b/toolkit/components/url-classifier/tests/mochitest/mochitest.ini @@ -9,6 +9,7 @@ support-files = import.css raptor.jpg track.html + unwantedWorker.js workerFrame.html [test_classifier.html] diff --git a/toolkit/components/url-classifier/tests/mochitest/test_classifier.html b/toolkit/components/url-classifier/tests/mochitest/test_classifier.html index 27b64075205f..374271addb60 100644 --- a/toolkit/components/url-classifier/tests/mochitest/test_classifier.html +++ b/toolkit/components/url-classifier/tests/mochitest/test_classifier.html @@ -24,6 +24,12 @@ var testUpdate = "a:524:32:" + testData.length + "\n" + testData; +testData = "unwanted.example.com/"; +testUpdate += + "n:1000\ni:test-unwanted-simple\nad:1\n" + + "a:524:32:" + testData.length + "\n" + + testData; + var dbService = Cc["@mozilla.org/url-classifier/dbservice;1"] .getService(Ci.nsIUrlClassifierDBService); @@ -55,7 +61,7 @@ function doUpdate(update) { } }; - dbService.beginUpdate(listener, "test-malware-simple", ""); + dbService.beginUpdate(listener, "test-malware-simple,test-unwanted-simple", ""); dbService.beginStream("", ""); dbService.updateStream(update); dbService.finishStream(); @@ -63,7 +69,7 @@ function doUpdate(update) { } SpecialPowers.pushPrefEnv( - {"set" : [["urlclassifier.malwareTable", "test-malware-simple"], + {"set" : [["urlclassifier.malwareTable", "test-malware-simple,test-unwanted-simple"], ["urlclassifier.phishTable", "test-phish-simple"]]}, function() { doUpdate(testUpdate); }); diff --git a/toolkit/components/url-classifier/tests/mochitest/test_classifier_worker.html b/toolkit/components/url-classifier/tests/mochitest/test_classifier_worker.html index f88084a83ccd..d74f2802521f 100644 --- a/toolkit/components/url-classifier/tests/mochitest/test_classifier_worker.html +++ b/toolkit/components/url-classifier/tests/mochitest/test_classifier_worker.html @@ -23,6 +23,12 @@ var testUpdate = "a:550:32:" + testData.length + "\n" + testData; +testData = "example.com/tests/toolkit/components/url-classifier/tests/mochitest/unwantedWorker.js"; +testUpdate += + "n:1000\ni:test-unwanted-simple\nad:550\n" + + "a:550:32:" + testData.length + "\n" + + testData; + var dbService = Cc["@mozilla.org/url-classifier/dbservice;1"] .getService(Ci.nsIUrlClassifierDBService); @@ -54,7 +60,7 @@ function doUpdate(update) { } }; - dbService.beginUpdate(listener, "test-malware-simple", ""); + dbService.beginUpdate(listener, "test-malware-simple,test-unwanted-simple", ""); dbService.beginStream("", ""); dbService.updateStream(update); dbService.finishStream(); @@ -73,7 +79,7 @@ function onmessage(event) } SpecialPowers.pushPrefEnv( - {"set" : [["urlclassifier.malwareTable", "test-malware-simple"], + {"set" : [["urlclassifier.malwareTable", "test-malware-simple,test-unwanted-simple"], ["urlclassifier.phishTable", "test-phish-simple"]]}, function() { doUpdate(testUpdate); }); diff --git a/toolkit/components/url-classifier/tests/mochitest/unwantedWorker.js b/toolkit/components/url-classifier/tests/mochitest/unwantedWorker.js new file mode 100644 index 000000000000..ac34977d71fa --- /dev/null +++ b/toolkit/components/url-classifier/tests/mochitest/unwantedWorker.js @@ -0,0 +1,3 @@ +onmessage = function() { + postMessage("loaded bad file"); +} diff --git a/toolkit/components/url-classifier/tests/mochitest/workerFrame.html b/toolkit/components/url-classifier/tests/mochitest/workerFrame.html index 23f0a25f8a2c..69e8dd0074ff 100644 --- a/toolkit/components/url-classifier/tests/mochitest/workerFrame.html +++ b/toolkit/components/url-classifier/tests/mochitest/workerFrame.html @@ -29,11 +29,27 @@ function startEvilWorker() { worker.onmessage = function(event) { window.parent.postMessage("failure:failed to block evilWorker.js", "*"); - startCleanWorker(); + startUnwantedWorker(); }; worker.onerror = function(event) { window.parent.postMessage("success:blocked evilWorker.js", "*"); + startUnwantedWorker(); + }; + + worker.postMessage(""); +} + +function startUnwantedWorker() { + var worker = new Worker("unwantedWorker.js"); + + worker.onmessage = function(event) { + window.parent.postMessage("failure:failed to block unwantedWorker.js", "*"); + startCleanWorker(); + }; + + worker.onerror = function(event) { + window.parent.postMessage("success:blocked unwantedWorker.js", "*"); startCleanWorker(); }; diff --git a/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js b/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js index 69ecf2fda691..7f2a4ce9ec53 100644 --- a/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js +++ b/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js @@ -53,15 +53,18 @@ function cleanUp() { delFile("safebrowsing/classifier.hashkey"); delFile("safebrowsing/test-phish-simple.sbstore"); delFile("safebrowsing/test-malware-simple.sbstore"); + delFile("safebrowsing/test-unwanted-simple.sbstore"); delFile("safebrowsing/test-phish-simple.cache"); delFile("safebrowsing/test-malware-simple.cache"); + delFile("safebrowsing/test-unwanted-simple.cache"); delFile("safebrowsing/test-phish-simple.pset"); delFile("safebrowsing/test-malware-simple.pset"); + delFile("safebrowsing/test-unwanted-simple.pset"); delFile("testLarge.pset"); delFile("testNoDelta.pset"); } -var allTables = "test-phish-simple,test-malware-simple"; +var allTables = "test-phish-simple,test-malware-simple,test-unwanted-simple"; var dbservice = Cc["@mozilla.org/url-classifier/dbservice;1"].getService(Ci.nsIUrlClassifierDBService); var streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"] @@ -114,6 +117,10 @@ function buildMalwareUpdate(chunks, hashSize) { return buildUpdate({"test-malware-simple" : chunks}, hashSize); } +function buildUnwantedUpdate(chunks, hashSize) { + return buildUpdate({"test-unwanted-simple" : chunks}, hashSize); +} + function buildBareUpdate(chunks, hashSize) { return buildUpdate({"" : chunks}, hashSize); } @@ -138,7 +145,7 @@ function doSimpleUpdate(updateText, success, failure) { }; dbservice.beginUpdate(listener, - "test-phish-simple,test-malware-simple"); + "test-phish-simple,test-malware-simple,test-unwanted-simple"); dbservice.beginStream("", ""); dbservice.updateStream(updateText); dbservice.finishStream(); @@ -180,7 +187,7 @@ function doStreamUpdate(updateText, success, failure, downloadFailure) { downloadFailure = failure; } - streamUpdater.downloadUpdates("test-phish-simple,test-malware-simple", "", + streamUpdater.downloadUpdates("test-phish-simple,test-malware-simple,test-unwanted-simple", "", dataUpdate, success, failure, downloadFailure); } @@ -237,6 +244,11 @@ malwareUrlsExist: function(urls, cb) this.checkUrls(urls, 'test-malware-simple', cb); }, +unwantedUrlsExist: function(urls, cb) +{ + this.checkUrls(urls, 'test-unwanted-simple', cb); +}, + subsDontExist: function(urls, cb) { // XXX: there's no interface for checking items in the subs table diff --git a/toolkit/components/url-classifier/tests/unit/test_dbservice.js b/toolkit/components/url-classifier/tests/unit/test_dbservice.js index 0f9108be83c2..c421c994f42e 100644 --- a/toolkit/components/url-classifier/tests/unit/test_dbservice.js +++ b/toolkit/components/url-classifier/tests/unit/test_dbservice.js @@ -47,18 +47,20 @@ var chunk6Urls = [ ]; var chunk6 = chunk6Urls.join("\n"); -// we are going to add chunks 1, 2, 4, 5, and 6 to phish-simple, and -// chunk 2 to malware-simple. Then we'll remove the urls in chunk3 -// from phish-simple, then expire chunk 1 and chunks 4-6 from -// phish-simple. +// we are going to add chunks 1, 2, 4, 5, and 6 to phish-simple, +// chunk 2 to malware-simple and chunk 3 to unwanted-simple. +// Then we'll remove the urls in chunk3 from phish-simple, then +// expire chunk 1 and chunks 4-6 from phish-simple. var phishExpected = {}; var phishUnexpected = {}; var malwareExpected = {}; +var unwantedExpected = {}; for (var i = 0; i < chunk2Urls.length; i++) { phishExpected[chunk2Urls[i]] = true; malwareExpected[chunk2Urls[i]] = true; } for (var i = 0; i < chunk3Urls.length; i++) { + unwantedExpected[chunk3Urls[i]] = true; delete phishExpected[chunk3Urls[i]]; phishUnexpected[chunk3Urls[i]] = true; } @@ -115,7 +117,7 @@ function tablesCallbackWithoutSub(tables) // there's a leading \n here because splitting left an empty string // after the trailing newline, which will sort first do_check_eq(parts.join("\n"), - "\ntest-malware-simple;a:1\ntest-phish-simple;a:2"); + "\ntest-malware-simple;a:1\ntest-phish-simple;a:2\ntest-unwanted-simple;a:1"); checkNoHost(); } @@ -133,7 +135,7 @@ function tablesCallbackWithSub(tables) // there's a leading \n here because splitting left an empty string // after the trailing newline, which will sort first do_check_eq(parts.join("\n"), - "\ntest-malware-simple;a:1\ntest-phish-simple;a:2:s:3"); + "\ntest-malware-simple;a:1\ntest-phish-simple;a:2:s:3\ntest-unwanted-simple;a:1"); // verify that expiring a sub chunk removes its name from the list var data = @@ -182,6 +184,16 @@ function malwareExists(result) { } } +function unwantedExists(result) { + dumpn("unwantedExists: " + result); + + try { + do_check_true(result.indexOf("test-unwanted-simple") != -1); + } finally { + checkDone(); + } +} + function checkState() { numExpecting = 0; @@ -203,6 +215,12 @@ function checkState() dbservice.lookup(principal, allTables, malwareExists, true); numExpecting++; } + + for (var key in unwantedExpected) { + var principal = secMan.getNoAppCodebasePrincipal(iosvc.newURI("http://" + key, null, null)); + dbservice.lookup(principal, allTables, unwantedExists, true); + numExpecting++; + } } function testSubSuccess(result) @@ -249,7 +267,10 @@ function do_adds() { chunk6 + "\n" + "i:test-malware-simple\n" + "a:1:32:" + chunk2.length + "\n" + - chunk2 + "\n"; + chunk2 + "\n" + + "i:test-unwanted-simple\n" + + "a:1:32:" + chunk3.length + "\n" + + chunk3 + "\n"; doSimpleUpdate(data, testAddSuccess, testFailure); } diff --git a/toolkit/components/url-classifier/tests/unit/test_streamupdater.js b/toolkit/components/url-classifier/tests/unit/test_streamupdater.js index 9ba73a17e053..89ea6fab3baf 100644 --- a/toolkit/components/url-classifier/tests/unit/test_streamupdater.js +++ b/toolkit/components/url-classifier/tests/unit/test_streamupdater.js @@ -131,6 +131,7 @@ function testMultipleTables() { var add1Urls = [ "foo-multiple.com/a", "bar-multiple.com/c" ]; var add2Urls = [ "foo-multiple.com/b" ]; var add3Urls = [ "bar-multiple.com/d" ]; + var add4Urls = [ "bar-multiple.com/e" ]; var update = "n:1000\n"; update += "i:test-phish-simple\n"; @@ -152,10 +153,17 @@ function testMultipleTables() { "urls" : add3Urls }]); update += "u:data:," + encodeURIComponent(update3) + "\n"; + update += "i:test-unwanted-simple\n"; + var update4 = buildBareUpdate( + [{ "chunkNum" : 4, + "urls" : add4Urls }]); + update += "u:data:," + encodeURIComponent(update4) + "\n"; + var assertions = { - "tableData" : "test-malware-simple;a:3\ntest-phish-simple;a:1-2", + "tableData" : "test-malware-simple;a:3\ntest-phish-simple;a:1-2\ntest-unwanted-simple;a:4", "urlsExist" : add1Urls.concat(add2Urls), - "malwareUrlsExist" : add3Urls + "malwareUrlsExist" : add3Urls, + "unwantedUrlsExist" : add4Urls }; doTest([update], assertions, false); diff --git a/toolkit/components/viewsource/content/viewSource.js b/toolkit/components/viewsource/content/viewSource.js index 2adbf442c684..4e89ab838101 100644 --- a/toolkit/components/viewsource/content/viewSource.js +++ b/toolkit/components/viewsource/content/viewSource.js @@ -242,33 +242,15 @@ function onClickContent(event) { if (/^about:blocked/.test(errorDoc.documentURI)) { // The event came from a button on a malware/phishing block page - // First check whether it's malware or phishing, so that we can - // use the right strings/links - var isMalware = /e=malwareBlocked/.test(errorDoc.documentURI); if (target == errorDoc.getElementById('getMeOutButton')) { // Instead of loading some safe page, just close the window window.close(); } else if (target == errorDoc.getElementById('reportButton')) { - // This is the "Why is this site blocked" button. For malware, - // we can fetch a site-specific report, for phishing, we redirect - // to the generic page describing phishing protection. - - if (isMalware) { - // Get the stop badware "why is this blocked" report url, - // append the current url, and go there. - try { - let reportURL = Services.urlFormatter.formatURLPref("browser.safebrowsing.malware.reportURL", true); - reportURL += errorDoc.location.href.slice(12); - openURL(reportURL); - } catch (e) { - Components.utils.reportError("Couldn't get malware report URL: " + e); - } - } else { - // It's a phishing site, just link to the generic information page - let url = Services.urlFormatter.formatURLPref("app.support.baseURL"); - openURL(url + "phishing-malware"); - } + // This is the "Why is this site blocked" button. We redirect + // to the generic page describing phishing/malware protection. + let url = Services.urlFormatter.formatURLPref("app.support.baseURL"); + openURL(url + "phishing-malware"); } else if (target == errorDoc.getElementById('ignoreWarningButton')) { // Allow users to override and continue through to the site gBrowser.loadURIWithFlags(content.location.href, diff --git a/webapprt/locales/en-US/webapprt/overrides/appstrings.properties b/webapprt/locales/en-US/webapprt/overrides/appstrings.properties index b41d7ac26f07..0138d137c72b 100644 --- a/webapprt/locales/en-US/webapprt/overrides/appstrings.properties +++ b/webapprt/locales/en-US/webapprt/overrides/appstrings.properties @@ -29,6 +29,7 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences. phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. cspBlocked=This application tried to access a resource that has a content security policy that prevents it from being loaded in this way. corruptedContentError=The application cannot continue loading because an error in the data transmission was detected. diff --git a/xpcom/base/ErrorList.h b/xpcom/base/ErrorList.h index 5eef3550c1e1..509d4ae9d354 100644 --- a/xpcom/base/ErrorList.h +++ b/xpcom/base/ErrorList.h @@ -678,6 +678,7 @@ ERROR(NS_ERROR_MALWARE_URI, FAILURE(30)), ERROR(NS_ERROR_PHISHING_URI, FAILURE(31)), ERROR(NS_ERROR_TRACKING_URI, FAILURE(34)), + ERROR(NS_ERROR_UNWANTED_URI, FAILURE(35)), /* Used when "Save Link As..." doesn't see the headers quickly enough to * choose a filename. See nsContextMenu.js. */ ERROR(NS_ERROR_SAVE_LINK_AS_TIMEOUT, FAILURE(32)), From a469e611a54ff5e1a4d7b0442325ab71dfc993a8 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Wed, 22 Apr 2015 15:22:40 +0200 Subject: [PATCH 153/241] Backed out 35 changesets (bug 1153629, bug 1149163, bug 1154701) for memory leaks in AsyncLatencyLogger, AsyncStatement etc on a CLOSED TREE Backed out changeset e64fa8717641 (bug 1154701) Backed out changeset 4fd3566e571c (bug 1154701) Backed out changeset 9801778d9d5b (bug 1154701) Backed out changeset a57f36dc00b4 (bug 1154701) Backed out changeset 9bd74af965fd (bug 1154701) Backed out changeset 69f9ae64772d (bug 1154701) Backed out changeset 07620ff1a21a (bug 1154701) Backed out changeset 8bd58656d297 (bug 1154701) Backed out changeset a4d41b284d92 (bug 1154701) Backed out changeset 1ab63df2b8eb (bug 1154701) Backed out changeset 31281738003d (bug 1154701) Backed out changeset 5ad34b482c25 (bug 1154701) Backed out changeset d8a83215797f (bug 1154701) Backed out changeset 81825eff1936 (bug 1154701) Backed out changeset 25bc426c8c0e (bug 1153629) Backed out changeset a9d071f07242 (bug 1153629) Backed out changeset 1f0fdf67005d (bug 1153629) Backed out changeset af47b386bea7 (bug 1153629) Backed out changeset 42f5d3fc71b3 (bug 1153629) Backed out changeset b0b609c3da83 (bug 1153629) Backed out changeset 9a62d4ec4542 (bug 1153629) Backed out changeset 87ff1d4bb056 (bug 1153629) Backed out changeset cb266456a948 (bug 1153629) Backed out changeset ee256b6f62ec (bug 1153629) Backed out changeset ecdfdce695b5 (bug 1153629) Backed out changeset 394ba1703c08 (bug 1153629) Backed out changeset 641439af501f (bug 1149163) Backed out changeset 54a8ecc0301d (bug 1149163) Backed out changeset a31a87b6dfb7 (bug 1149163) Backed out changeset e36d2f251276 (bug 1149163) Backed out changeset 152ee688999b (bug 1149163) Backed out changeset 7bf082213f82 (bug 1149163) Backed out changeset 2817e4601371 (bug 1149163) Backed out changeset bc75a87a2b7d (bug 1149163) Backed out changeset 4392cf02f1c0 (bug 1149163) --- editor/libeditor/nsEditor.cpp | 183 +- editor/libeditor/nsEditor.h | 11 +- editor/libeditor/nsEditorUtils.cpp | 92 +- editor/libeditor/nsEditorUtils.h | 31 +- editor/libeditor/nsHTMLDataTransfer.cpp | 443 +++-- editor/libeditor/nsHTMLEditRules.cpp | 2262 +++++++++++++--------- editor/libeditor/nsHTMLEditRules.h | 89 +- editor/libeditor/nsHTMLEditor.cpp | 232 ++- editor/libeditor/nsHTMLEditor.h | 64 +- editor/libeditor/nsHTMLEditorStyle.cpp | 352 ++-- editor/libeditor/nsHTMLObjectResizer.cpp | 35 +- 11 files changed, 2195 insertions(+), 1599 deletions(-) diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index 019255bd4598..3b7913b102f8 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -1353,9 +1353,9 @@ nsEditor::CreateNode(nsIAtom* aTag, nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext); - for (auto& listener : mActionListeners) { - listener->WillCreateNode(nsDependentAtomString(aTag), - GetAsDOMNode(aParent), aPosition); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->WillCreateNode(nsDependentAtomString(aTag), + GetAsDOMNode(aParent), aPosition); } nsCOMPtr ret; @@ -1370,9 +1370,11 @@ nsEditor::CreateNode(nsIAtom* aTag, mRangeUpdater.SelAdjCreateNode(aParent, aPosition); - for (auto& listener : mActionListeners) { - listener->DidCreateNode(nsDependentAtomString(aTag), GetAsDOMNode(ret), - GetAsDOMNode(aParent), aPosition, res); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->DidCreateNode(nsDependentAtomString(aTag), + GetAsDOMNode(ret), + GetAsDOMNode(aParent), aPosition, + res); } return ret.forget(); @@ -1394,9 +1396,9 @@ nsEditor::InsertNode(nsIContent& aNode, nsINode& aParent, int32_t aPosition) { nsAutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); - for (auto& listener : mActionListeners) { - listener->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), - aPosition); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), + aPosition); } nsRefPtr txn = CreateTxnForInsertNode(aNode, aParent, @@ -1405,9 +1407,9 @@ nsEditor::InsertNode(nsIContent& aNode, nsINode& aParent, int32_t aPosition) mRangeUpdater.SelAdjInsertNode(aParent.AsDOMNode(), aPosition); - for (auto& listener : mActionListeners) { - listener->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), aPosition, - res); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), + aPosition, res); } return res; @@ -1433,8 +1435,8 @@ nsEditor::SplitNode(nsIContent& aNode, int32_t aOffset, ErrorResult& aResult) nsAutoRules beginRulesSniffing(this, EditAction::splitNode, nsIEditor::eNext); - for (auto& listener : mActionListeners) { - listener->WillSplitNode(aNode.AsDOMNode(), aOffset); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->WillSplitNode(aNode.AsDOMNode(), aOffset); } nsRefPtr txn = CreateTxnForSplitNode(aNode, aOffset); @@ -1445,9 +1447,10 @@ nsEditor::SplitNode(nsIContent& aNode, int32_t aOffset, ErrorResult& aResult) mRangeUpdater.SelAdjSplitNode(aNode, aOffset, newNode); - for (auto& listener : mActionListeners) { - listener->DidSplitNode(aNode.AsDOMNode(), aOffset, GetAsDOMNode(newNode), - aResult.ErrorCode()); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->DidSplitNode(aNode.AsDOMNode(), aOffset, + GetAsDOMNode(newNode), + aResult.ErrorCode()); } return newNode; @@ -1480,9 +1483,10 @@ nsEditor::JoinNodes(nsINode& aLeftNode, nsINode& aRightNode) // Find the number of children of the lefthand node uint32_t oldLeftNodeLen = aLeftNode.Length(); - for (auto& listener : mActionListeners) { - listener->WillJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(), - parent->AsDOMNode()); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->WillJoinNodes(aLeftNode.AsDOMNode(), + aRightNode.AsDOMNode(), + parent->AsDOMNode()); } nsresult result; @@ -1494,9 +1498,10 @@ nsEditor::JoinNodes(nsINode& aLeftNode, nsINode& aRightNode) mRangeUpdater.SelAdjJoinNodes(aLeftNode, aRightNode, *parent, offset, (int32_t)oldLeftNodeLen); - for (auto& listener : mActionListeners) { - listener->DidJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(), - parent->AsDOMNode(), result); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->DidJoinNodes(aLeftNode.AsDOMNode(), + aRightNode.AsDOMNode(), + parent->AsDOMNode(), result); } return result; @@ -1517,8 +1522,8 @@ nsEditor::DeleteNode(nsINode* aNode) nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::ePrevious); // save node location for selection updating code. - for (auto& listener : mActionListeners) { - listener->WillDeleteNode(aNode->AsDOMNode()); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->WillDeleteNode(aNode->AsDOMNode()); } nsRefPtr txn; @@ -1527,8 +1532,8 @@ nsEditor::DeleteNode(nsINode* aNode) res = DoTransaction(txn); } - for (auto& listener : mActionListeners) { - listener->DidDeleteNode(aNode->AsDOMNode(), res); + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->DidDeleteNode(aNode->AsDOMNode(), res); } NS_ENSURE_SUCCESS(res, res); @@ -1733,8 +1738,10 @@ nsEditor::AddEditorObserver(nsIEditorObserver *aObserver) NS_ENSURE_TRUE(aObserver, NS_ERROR_NULL_POINTER); // Make sure the listener isn't already on the list - if (!mEditorObservers.Contains(aObserver)) { - mEditorObservers.AppendElement(*aObserver); + if (mEditorObservers.IndexOf(aObserver) == -1) + { + if (!mEditorObservers.AppendObject(aObserver)) + return NS_ERROR_FAILURE; } return NS_OK; @@ -1746,7 +1753,8 @@ nsEditor::RemoveEditorObserver(nsIEditorObserver *aObserver) { NS_ENSURE_TRUE(aObserver, NS_ERROR_FAILURE); - mEditorObservers.RemoveElement(aObserver); + if (!mEditorObservers.RemoveObject(aObserver)) + return NS_ERROR_FAILURE; return NS_OK; } @@ -1806,8 +1814,8 @@ nsEditor::NotifyEditorObservers(NotificationForEditorObservers aNotification) switch (aNotification) { case eNotifyEditorObserversOfEnd: mIsInEditAction = false; - for (auto& observer : mEditorObservers) { - observer->EditAction(); + for (int32_t i = 0; i < mEditorObservers.Count(); i++) { + mEditorObservers[i]->EditAction(); } if (!mDispatchInputEvent) { @@ -1818,14 +1826,14 @@ nsEditor::NotifyEditorObservers(NotificationForEditorObservers aNotification) break; case eNotifyEditorObserversOfBefore: mIsInEditAction = true; - for (auto& observer : mEditorObservers) { - observer->BeforeEditAction(); + for (int32_t i = 0; i < mEditorObservers.Count(); i++) { + mEditorObservers[i]->BeforeEditAction(); } break; case eNotifyEditorObserversOfCancel: mIsInEditAction = false; - for (auto& observer : mEditorObservers) { - observer->CancelEditAction(); + for (int32_t i = 0; i < mEditorObservers.Count(); i++) { + mEditorObservers[i]->CancelEditAction(); } break; default: @@ -1858,8 +1866,10 @@ nsEditor::AddEditActionListener(nsIEditActionListener *aListener) NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); // Make sure the listener isn't already on the list - if (!mActionListeners.Contains(aListener)) { - mActionListeners.AppendElement(*aListener); + if (mActionListeners.IndexOf(aListener) == -1) + { + if (!mActionListeners.AppendObject(aListener)) + return NS_ERROR_FAILURE; } return NS_OK; @@ -1871,7 +1881,8 @@ nsEditor::RemoveEditActionListener(nsIEditActionListener *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE); - mActionListeners.RemoveElement(aListener); + if (!mActionListeners.RemoveObject(aListener)) + return NS_ERROR_FAILURE; return NS_OK; } @@ -1882,8 +1893,10 @@ nsEditor::AddDocumentStateListener(nsIDocumentStateListener *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); - if (!mDocStateListeners.Contains(aListener)) { - mDocStateListeners.AppendElement(*aListener); + if (mDocStateListeners.IndexOf(aListener) == -1) + { + if (!mDocStateListeners.AppendObject(aListener)) + return NS_ERROR_FAILURE; } return NS_OK; @@ -1895,7 +1908,8 @@ nsEditor::RemoveDocumentStateListener(nsIDocumentStateListener *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); - mDocStateListeners.RemoveElement(aListener); + if (!mDocStateListeners.RemoveObject(aListener)) + return NS_ERROR_FAILURE; return NS_OK; } @@ -2378,8 +2392,8 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, } // Let listeners know what's up - for (auto& listener : mActionListeners) { - listener->WillInsertText( + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->WillInsertText( static_cast(aTextNode.AsDOMNode()), aOffset, aStringToInsert); } @@ -2393,8 +2407,8 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, mRangeUpdater.SelAdjInsertText(aTextNode, aOffset, aStringToInsert); // let listeners know what happened - for (auto& listener : mActionListeners) { - listener->DidInsertText( + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->DidInsertText( static_cast(aTextNode.AsDOMNode()), aOffset, aStringToInsert, res); } @@ -2451,28 +2465,29 @@ nsEditor::GetFirstEditableNode(nsINode* aRoot) NS_IMETHODIMP nsEditor::NotifyDocumentListeners(TDocumentListenerNotification aNotificationType) { - if (!mDocStateListeners.Length()) { - // Maybe there just aren't any. + int32_t numListeners = mDocStateListeners.Count(); + if (!numListeners) // maybe there just aren't any. return NS_OK; - } - nsTArray> - listeners(mDocStateListeners); + nsCOMArray listeners(mDocStateListeners); nsresult rv = NS_OK; + int32_t i; switch (aNotificationType) { case eDocumentCreated: - for (auto& listener : listeners) { - rv = listener->NotifyDocumentCreated(); + for (i = 0; i < numListeners;i++) + { + rv = listeners[i]->NotifyDocumentCreated(); if (NS_FAILED(rv)) break; } break; case eDocumentToBeDestroyed: - for (auto& listener : listeners) { - rv = listener->NotifyDocumentWillBeDestroyed(); + for (i = 0; i < numListeners;i++) + { + rv = listeners[i]->NotifyDocumentWillBeDestroyed(); if (NS_FAILED(rv)) break; } @@ -2489,8 +2504,9 @@ nsEditor::NotifyDocumentListeners(TDocumentListenerNotification aNotificationTyp mDocDirtyState = docIsDirty; - for (auto& listener : listeners) { - rv = listener->NotifyDocumentStateChanged(mDocDirtyState); + for (i = 0; i < numListeners;i++) + { + rv = listeners[i]->NotifyDocumentStateChanged(mDocDirtyState); if (NS_FAILED(rv)) break; } @@ -2526,8 +2542,8 @@ nsEditor::DeleteText(nsGenericDOMDataNode& aCharData, uint32_t aOffset, nsAutoRules beginRulesSniffing(this, EditAction::deleteText, nsIEditor::ePrevious); // Let listeners know what's up - for (auto& listener : mActionListeners) { - listener->WillDeleteText( + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->WillDeleteText( static_cast(GetAsDOMNode(&aCharData)), aOffset, aLength); } @@ -2535,8 +2551,8 @@ nsEditor::DeleteText(nsGenericDOMDataNode& aCharData, uint32_t aOffset, nsresult res = DoTransaction(txn); // Let listeners know what happened - for (auto& listener : mActionListeners) { - listener->DidDeleteText( + for (int32_t i = 0; i < mActionListeners.Count(); i++) { + mActionListeners[i]->DidDeleteText( static_cast(GetAsDOMNode(&aCharData)), aOffset, aLength, res); } @@ -3904,38 +3920,31 @@ nsEditor::DeleteSelectionImpl(EDirection aAction, if (NS_SUCCEEDED(res)) { nsAutoRules beginRulesSniffing(this, EditAction::deleteSelection, aAction); + int32_t i; // Notify nsIEditActionListener::WillDelete[Selection|Text|Node] - if (!deleteNode) { - for (auto& listener : mActionListeners) { - listener->WillDeleteSelection(selection); - } - } else if (deleteCharData) { - for (auto& listener : mActionListeners) { - listener->WillDeleteText(deleteCharData, deleteCharOffset, 1); - } - } else { - for (auto& listener : mActionListeners) { - listener->WillDeleteNode(deleteNode->AsDOMNode()); - } - } + if (!deleteNode) + for (i = 0; i < mActionListeners.Count(); i++) + mActionListeners[i]->WillDeleteSelection(selection); + else if (deleteCharData) + for (i = 0; i < mActionListeners.Count(); i++) + mActionListeners[i]->WillDeleteText(deleteCharData, deleteCharOffset, 1); + else + for (i = 0; i < mActionListeners.Count(); i++) + mActionListeners[i]->WillDeleteNode(deleteNode->AsDOMNode()); // Delete the specified amount res = DoTransaction(txn); // Notify nsIEditActionListener::DidDelete[Selection|Text|Node] - if (!deleteNode) { - for (auto& listener : mActionListeners) { - listener->DidDeleteSelection(selection); - } - } else if (deleteCharData) { - for (auto& listener : mActionListeners) { - listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, res); - } - } else { - for (auto& listener : mActionListeners) { - listener->DidDeleteNode(deleteNode->AsDOMNode(), res); - } - } + if (!deleteNode) + for (i = 0; i < mActionListeners.Count(); i++) + mActionListeners[i]->DidDeleteSelection(selection); + else if (deleteCharData) + for (i = 0; i < mActionListeners.Count(); i++) + mActionListeners[i]->DidDeleteText(deleteCharData, deleteCharOffset, 1, res); + else + for (i = 0; i < mActionListeners.Count(); i++) + mActionListeners[i]->DidDeleteNode(deleteNode->AsDOMNode(), res); } return res; diff --git a/editor/libeditor/nsEditor.h b/editor/libeditor/nsEditor.h index 277d2293fb1e..8e377cbc247f 100644 --- a/editor/libeditor/nsEditor.h +++ b/editor/libeditor/nsEditor.h @@ -7,9 +7,9 @@ #define __editor_h__ #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc. -#include "mozilla/dom/OwningNonNull.h" // for OwningNonNull #include "mozilla/dom/Text.h" #include "nsAutoPtr.h" // for nsRefPtr +#include "nsCOMArray.h" // for nsCOMArray #include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr #include "nsCycleCollectionParticipant.h" #include "nsGkAtoms.h" @@ -830,12 +830,9 @@ protected: nsRefPtr mComposition; // various listeners - // Listens to all low level actions on the doc - nsTArray> mActionListeners; - // Just notify once per high level change - nsTArray> mEditorObservers; - // Listen to overall doc state (dirty or not, just created, etc) - nsTArray> mDocStateListeners; + nsCOMArray mActionListeners; // listens to all low level actions on the doc + nsCOMArray mEditorObservers; // just notify once per high level change + nsCOMArray mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc) nsSelectionState mSavedSel; // cached selection for nsAutoSelectionReset nsRangeUpdater mRangeUpdater; // utility class object for maintaining preserved ranges diff --git a/editor/libeditor/nsEditorUtils.cpp b/editor/libeditor/nsEditorUtils.cpp index 4b268ac44455..210a201beffe 100644 --- a/editor/libeditor/nsEditorUtils.cpp +++ b/editor/libeditor/nsEditorUtils.cpp @@ -5,8 +5,8 @@ #include "nsEditorUtils.h" -#include "mozilla/dom/OwningNonNull.h" #include "mozilla/dom/Selection.h" +#include "nsCOMArray.h" #include "nsComponentManagerUtils.h" #include "nsError.h" #include "nsIClipboardDragDropHookList.h" @@ -66,53 +66,91 @@ nsAutoSelectionReset::Abort() * some helper classes for iterating the dom tree *****************************************************************************/ -nsDOMIterator::nsDOMIterator(nsRange& aRange) -{ - MOZ_ASSERT(aRange.GetStartParent(), "Invalid range"); - mIter = NS_NewContentIterator(); - DebugOnly res = mIter->Init(&aRange); - MOZ_ASSERT(NS_SUCCEEDED(res)); -} - -nsDOMIterator::nsDOMIterator(nsINode& aNode) -{ - mIter = NS_NewContentIterator(); - DebugOnly res = mIter->Init(&aNode); - MOZ_ASSERT(NS_SUCCEEDED(res)); -} - -nsDOMIterator::nsDOMIterator() +nsDOMIterator::nsDOMIterator() : +mIter(nullptr) { } - + nsDOMIterator::~nsDOMIterator() { } + +nsresult +nsDOMIterator::Init(nsRange* aRange) +{ + nsresult res; + mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res); + NS_ENSURE_SUCCESS(res, res); + NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE); + return mIter->Init(aRange); +} -void -nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor, - nsTArray>& arrayOfNodes) const +nsresult +nsDOMIterator::Init(nsIDOMNode* aNode) +{ + nsresult res; + mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res); + NS_ENSURE_SUCCESS(res, res); + NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE); + nsCOMPtr content = do_QueryInterface(aNode); + return mIter->Init(content); +} + +nsresult +nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor, + nsTArray>& arrayOfNodes) const { // Iterate through dom and build list - for (; !mIter->IsDone(); mIter->Next()) { + while (!mIter->IsDone()) { nsCOMPtr node = mIter->GetCurrentNode(); + NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); if (functor(node)) { - arrayOfNodes.AppendElement(*node); + arrayOfNodes.AppendElement(node); } + mIter->Next(); } + return NS_OK; } -nsDOMSubtreeIterator::nsDOMSubtreeIterator(nsRange& aRange) +nsresult +nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor, + nsCOMArray& arrayOfNodes) const { - mIter = NS_NewContentSubtreeIterator(); - DebugOnly res = mIter->Init(&aRange); - MOZ_ASSERT(NS_SUCCEEDED(res)); + nsCOMPtr node; + + // iterate through dom and build list + while (!mIter->IsDone()) + { + node = do_QueryInterface(mIter->GetCurrentNode()); + NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); + + if (functor(node)) + { + arrayOfNodes.AppendObject(node); + } + mIter->Next(); + } + return NS_OK; } +nsDOMSubtreeIterator::nsDOMSubtreeIterator() +{ +} + nsDOMSubtreeIterator::~nsDOMSubtreeIterator() { } + +nsresult +nsDOMSubtreeIterator::Init(nsRange* aRange) +{ + nsresult res; + mIter = do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res); + NS_ENSURE_SUCCESS(res, res); + NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE); + return mIter->Init(aRange); +} /****************************************************************************** * some general purpose editor utils diff --git a/editor/libeditor/nsEditorUtils.h b/editor/libeditor/nsEditorUtils.h index 7e4e44ac82a6..868572d9232d 100644 --- a/editor/libeditor/nsEditorUtils.h +++ b/editor/libeditor/nsEditorUtils.h @@ -19,9 +19,9 @@ class nsIAtom; class nsIContentIterator; class nsIDOMDocument; class nsRange; +template class nsCOMArray; namespace mozilla { namespace dom { -template class OwningNonNull; class Selection; } } @@ -167,37 +167,42 @@ class MOZ_STACK_CLASS nsAutoUpdateViewBatch class nsBoolDomIterFunctor { public: - virtual bool operator()(nsINode* aNode) const = 0; + virtual bool operator()(nsIDOMNode* aNode)=0; + bool operator()(nsINode* aNode) + { + return operator()(GetAsDOMNode(aNode)); + } }; class MOZ_STACK_CLASS nsDOMIterator { public: - explicit nsDOMIterator(nsRange& aRange); - explicit nsDOMIterator(nsINode& aNode); + nsDOMIterator(); virtual ~nsDOMIterator(); - - void AppendList(const nsBoolDomIterFunctor& functor, - nsTArray>& arrayOfNodes) const; + + nsresult Init(nsRange* aRange); + nsresult Init(nsIDOMNode* aNode); + nsresult AppendList(nsBoolDomIterFunctor& functor, + nsTArray>& arrayOfNodes) const; + nsresult AppendList(nsBoolDomIterFunctor& functor, + nsCOMArray& arrayOfNodes) const; protected: nsCOMPtr mIter; - - // For nsDOMSubtreeIterator - nsDOMIterator(); }; class MOZ_STACK_CLASS nsDOMSubtreeIterator : public nsDOMIterator { public: - explicit nsDOMSubtreeIterator(nsRange& aRange); + nsDOMSubtreeIterator(); virtual ~nsDOMSubtreeIterator(); + + nsresult Init(nsRange* aRange); }; class nsTrivialFunctor : public nsBoolDomIterFunctor { public: - // Used to build list of all nodes iterator covers - virtual bool operator()(nsINode* aNode) const + virtual bool operator()(nsIDOMNode* aNode) // used to build list of all nodes iterator covers { return true; } diff --git a/editor/libeditor/nsHTMLDataTransfer.cpp b/editor/libeditor/nsHTMLDataTransfer.cpp index a72ecd0a7ab9..284a08ef78bf 100644 --- a/editor/libeditor/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/nsHTMLDataTransfer.cpp @@ -7,7 +7,6 @@ #include #include "mozilla/dom/DocumentFragment.h" -#include "mozilla/dom/OwningNonNull.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Base64.h" #include "mozilla/BasicEvents.h" @@ -15,6 +14,7 @@ #include "mozilla/dom/Selection.h" #include "nsAString.h" #include "nsAutoPtr.h" +#include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsCRT.h" #include "nsCRTGlue.h" @@ -102,6 +102,39 @@ static nsresult RemoveFragComments(nsCString &theStr); static void RemoveBodyAndHead(nsIDOMNode *aNode); static nsresult FindTargetNode(nsIDOMNode *aStart, nsCOMPtr &aResult); +static nsCOMPtr GetListParent(nsIDOMNode* aNode) +{ + NS_ENSURE_TRUE(aNode, nullptr); + nsCOMPtr parent, tmp; + aNode->GetParentNode(getter_AddRefs(parent)); + while (parent) + { + if (nsHTMLEditUtils::IsList(parent)) { + return parent; + } + parent->GetParentNode(getter_AddRefs(tmp)); + parent = tmp; + } + return nullptr; +} + +static nsCOMPtr GetTableParent(nsIDOMNode* aNode) +{ + NS_ENSURE_TRUE(aNode, nullptr); + nsCOMPtr parent, tmp; + aNode->GetParentNode(getter_AddRefs(parent)); + while (parent) + { + if (nsHTMLEditUtils::IsTable(parent)) { + return parent; + } + parent->GetParentNode(getter_AddRefs(tmp)); + parent = tmp; + } + return nullptr; +} + + nsresult nsHTMLEditor::LoadHTML(const nsAString & aInputString) { @@ -288,21 +321,13 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // this is work to be completed at a later date (probably by jfrancis) // make a list of what nodes in docFrag we need to move - nsTArray> nodeList; - nsCOMPtr fragmentAsNodeNode = do_QueryInterface(fragmentAsNode); - NS_ENSURE_STATE(fragmentAsNodeNode || !fragmentAsNode); - nsCOMPtr streamStartParentNode = - do_QueryInterface(streamStartParent); - NS_ENSURE_STATE(streamStartParentNode || !streamStartParent); - nsCOMPtr streamEndParentNode = - do_QueryInterface(streamEndParent); - NS_ENSURE_STATE(streamEndParentNode || !streamEndParent); - CreateListOfNodesToPaste(*static_cast(fragmentAsNodeNode.get()), - nodeList, - streamStartParentNode, streamStartOffset, - streamEndParentNode, streamEndOffset); + nsCOMArray nodeList; + rv = CreateListOfNodesToPaste(fragmentAsNode, nodeList, + streamStartParent, streamStartOffset, + streamEndParent, streamEndOffset); + NS_ENSURE_SUCCESS(rv, rv); - if (nodeList.Length() == 0) { + if (nodeList.Count() == 0) { return NS_OK; } @@ -327,9 +352,9 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // but if not we want to delete _contents_ of cells and replace // with non-table elements. Use cellSelectionMode bool to // indicate results. - if (!nsHTMLEditUtils::IsTableElement(nodeList[0])) { + nsIDOMNode* firstNode = nodeList[0]; + if (!nsHTMLEditUtils::IsTableElement(firstNode)) cellSelectionMode = false; - } } if (!cellSelectionMode) @@ -377,8 +402,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, NS_ENSURE_TRUE(parentNode, NS_ERROR_FAILURE); // Adjust position based on the first node we are going to insert. - NormalizeEOLInsertPosition(GetAsDOMNode(nodeList[0]), - address_of(parentNode), &offsetOfNewNode); + NormalizeEOLInsertPosition(nodeList[0], address_of(parentNode), &offsetOfNewNode); // if there are any invisible br's after our insertion point, remove them. // this is because if there is a br at end of what we paste, it will make @@ -407,15 +431,16 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // build up list of parents of first node in list that are either // lists or tables. First examine front of paste node list. - nsTArray> startListAndTableArray; - GetListAndTableParents(StartOrEnd::start, nodeList, - startListAndTableArray); + nsCOMArray startListAndTableArray; + rv = GetListAndTableParents(false, nodeList, startListAndTableArray); + NS_ENSURE_SUCCESS(rv, rv); // remember number of lists and tables above us int32_t highWaterMark = -1; - if (startListAndTableArray.Length() > 0) { - highWaterMark = DiscoverPartialListsAndTables(nodeList, - startListAndTableArray); + if (startListAndTableArray.Count() > 0) + { + rv = DiscoverPartialListsAndTables(nodeList, startListAndTableArray, &highWaterMark); + NS_ENSURE_SUCCESS(rv, rv); } // if we have pieces of tables or lists to be inserted, let's force the paste @@ -423,31 +448,33 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, // table or list contents outside the table or list. if (highWaterMark >= 0) { - ReplaceOrphanedStructure(StartOrEnd::start, nodeList, - startListAndTableArray, highWaterMark); + rv = ReplaceOrphanedStructure(false, nodeList, startListAndTableArray, highWaterMark); + NS_ENSURE_SUCCESS(rv, rv); } // Now go through the same process again for the end of the paste node list. - nsTArray> endListAndTableArray; - GetListAndTableParents(StartOrEnd::end, nodeList, endListAndTableArray); + nsCOMArray endListAndTableArray; + rv = GetListAndTableParents(true, nodeList, endListAndTableArray); + NS_ENSURE_SUCCESS(rv, rv); highWaterMark = -1; // remember number of lists and tables above us - if (endListAndTableArray.Length() > 0) { - highWaterMark = DiscoverPartialListsAndTables(nodeList, - endListAndTableArray); + if (endListAndTableArray.Count() > 0) + { + rv = DiscoverPartialListsAndTables(nodeList, endListAndTableArray, &highWaterMark); + NS_ENSURE_SUCCESS(rv, rv); } // don't orphan partial list or table structure if (highWaterMark >= 0) { - ReplaceOrphanedStructure(StartOrEnd::end, nodeList, - endListAndTableArray, highWaterMark); + rv = ReplaceOrphanedStructure(true, nodeList, endListAndTableArray, highWaterMark); + NS_ENSURE_SUCCESS(rv, rv); } // Loop over the node list and paste the nodes: nsCOMPtr parentBlock, lastInsertNode, insertedContextParent; - int32_t listCount = nodeList.Length(); + int32_t listCount = nodeList.Count(); int32_t j; if (IsBlockNode(parentNode)) parentBlock = parentNode; @@ -457,7 +484,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, for (j=0; j curNode = nodeList[j]->AsDOMNode(); + nsCOMPtr curNode = nodeList[j]; NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE); NS_ENSURE_TRUE(curNode != fragmentAsNode, NS_ERROR_FAILURE); @@ -694,25 +721,26 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString, return mRules->DidDoAction(selection, &ruleInfo, rv); } -NS_IMETHODIMP +nsresult nsHTMLEditor::AddInsertionListener(nsIContentFilter *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); // don't let a listener be added more than once - if (!mContentFilters.Contains(aListener)) { - mContentFilters.AppendElement(*aListener); + if (mContentFilters.IndexOfObject(aListener) == -1) + { + NS_ENSURE_TRUE(mContentFilters.AppendObject(aListener), NS_ERROR_FAILURE); } return NS_OK; } -NS_IMETHODIMP +nsresult nsHTMLEditor::RemoveInsertionListener(nsIContentFilter *aListener) { NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE); - mContentFilters.RemoveElement(aListener); + NS_ENSURE_TRUE(mContentFilters.RemoveObject(aListener), NS_ERROR_FAILURE); return NS_OK; } @@ -732,15 +760,17 @@ nsHTMLEditor::DoContentFilterCallback(const nsAString &aFlavor, { *aDoContinue = true; - for (auto& listener : mContentFilters) { - if (!*aDoContinue) { - break; - } - listener->NotifyOfInsertion(aFlavor, nullptr, sourceDoc, - aWillDeleteSelection, aFragmentAsNode, - aFragStartNode, aFragStartOffset, - aFragEndNode, aFragEndOffset, aTargetNode, - aTargetOffset, aDoContinue); + int32_t i; + nsIContentFilter *listener; + for (i=0; i < mContentFilters.Count() && *aDoContinue; i++) + { + listener = (nsIContentFilter *)mContentFilters[i]; + if (listener) + listener->NotifyOfInsertion(aFlavor, nullptr, sourceDoc, + aWillDeleteSelection, aFragmentAsNode, + aFragStartNode, aFragStartOffset, + aFragEndNode, aFragEndOffset, + aTargetNode, aTargetOffset, aDoContinue); } return NS_OK; @@ -2136,170 +2166,219 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr, return rv; } -void -nsHTMLEditor::CreateListOfNodesToPaste(DocumentFragment& aFragment, - nsTArray>& outNodeList, - nsINode* aStartNode, - int32_t aStartOffset, - nsINode* aEndNode, - int32_t aEndOffset) +nsresult nsHTMLEditor::CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode, + nsCOMArray& outNodeList, + nsIDOMNode *aStartNode, + int32_t aStartOffset, + nsIDOMNode *aEndNode, + int32_t aEndOffset) { - // If no info was provided about the boundary between context and stream, + NS_ENSURE_TRUE(aFragmentAsNode, NS_ERROR_NULL_POINTER); + + nsresult rv; + + // if no info was provided about the boundary between context and stream, // then assume all is stream. - if (!aStartNode) { - aStartNode = &aFragment; + if (!aStartNode) + { + int32_t fragLen; + rv = GetLengthOfDOMNode(aFragmentAsNode, (uint32_t&)fragLen); + NS_ENSURE_SUCCESS(rv, rv); + + aStartNode = aFragmentAsNode; aStartOffset = 0; - aEndNode = &aFragment; - aEndOffset = aFragment.Length(); + aEndNode = aFragmentAsNode; + aEndOffset = fragLen; } nsRefPtr docFragRange; - nsresult rv = nsRange::CreateRange(aStartNode, aStartOffset, - aEndNode, aEndOffset, - getter_AddRefs(docFragRange)); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - NS_ENSURE_SUCCESS(rv, ); + rv = nsRange::CreateRange(aStartNode, aStartOffset, aEndNode, aEndOffset, getter_AddRefs(docFragRange)); + NS_ENSURE_SUCCESS(rv, rv); - // Now use a subtree iterator over the range to create a list of nodes + // now use a subtree iterator over the range to create a list of nodes nsTrivialFunctor functor; - nsDOMSubtreeIterator iter(*docFragRange); - iter.AppendList(functor, outNodeList); + nsDOMSubtreeIterator iter; + rv = iter.Init(docFragRange); + NS_ENSURE_SUCCESS(rv, rv); + + return iter.AppendList(functor, outNodeList); } -void -nsHTMLEditor::GetListAndTableParents(StartOrEnd aStartOrEnd, - nsTArray>& aNodeList, - nsTArray>& outArray) +nsresult +nsHTMLEditor::GetListAndTableParents(bool aEnd, + nsCOMArray& aListOfNodes, + nsCOMArray& outArray) { - MOZ_ASSERT(aNodeList.Length()); + int32_t listCount = aListOfNodes.Count(); + NS_ENSURE_TRUE(listCount > 0, NS_ERROR_FAILURE); // no empty lists, please - // Build up list of parents of first (or last) node in list that are either - // lists, or tables. - int32_t idx = aStartOrEnd == StartOrEnd::end ? aNodeList.Length() - 1 : 0; + // build up list of parents of first (or last) node in list + // that are either lists, or tables. + int32_t idx = 0; + if (aEnd) idx = listCount-1; - for (nsCOMPtr node = aNodeList[idx]; node; - node = node->GetParentNode()) { - if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsTable(node)) { - outArray.AppendElement(*node->AsElement()); + nsCOMPtr pNode = aListOfNodes[idx]; + while (pNode) + { + if (nsHTMLEditUtils::IsList(pNode) || nsHTMLEditUtils::IsTable(pNode)) + { + NS_ENSURE_TRUE(outArray.AppendObject(pNode), NS_ERROR_FAILURE); } + nsCOMPtr parent; + pNode->GetParentNode(getter_AddRefs(parent)); + pNode = parent; } + return NS_OK; } -int32_t -nsHTMLEditor::DiscoverPartialListsAndTables(nsTArray>& aPasteNodes, - nsTArray>& aListsAndTables) +nsresult +nsHTMLEditor::DiscoverPartialListsAndTables(nsCOMArray& aPasteNodes, + nsCOMArray& aListsAndTables, + int32_t *outHighWaterMark) { - int32_t ret = -1; - int32_t listAndTableParents = aListsAndTables.Length(); + NS_ENSURE_TRUE(outHighWaterMark, NS_ERROR_NULL_POINTER); - // Scan insertion list for table elements (other than table). - for (auto& curNode : aPasteNodes) { - if (nsHTMLEditUtils::IsTableElement(curNode) && - !curNode->IsHTMLElement(nsGkAtoms::table)) { - nsCOMPtr table = curNode->GetParentElement(); - while (table && !table->IsHTMLElement(nsGkAtoms::table)) { - table = table->GetParentElement(); - } - if (table) { - int32_t idx = aListsAndTables.IndexOf(table); - if (idx == -1) { - return ret; - } - ret = idx; - if (ret == listAndTableParents - 1) { - return ret; - } - } - } - if (nsHTMLEditUtils::IsListItem(curNode)) { - nsCOMPtr list = curNode->GetParentElement(); - while (list && !nsHTMLEditUtils::IsList(list)) { - list = list->GetParentElement(); - } - if (list) { - int32_t idx = aListsAndTables.IndexOf(list); - if (idx == -1) { - return ret; - } - ret = idx; - if (ret == listAndTableParents - 1) { - return ret; - } - } - } - } - return ret; -} - -nsINode* -nsHTMLEditor::ScanForListAndTableStructure(StartOrEnd aStartOrEnd, - nsTArray>& aNodes, - Element& aListOrTable) -{ - // Look upward from first/last paste node for a piece of this list/table - int32_t idx = aStartOrEnd == StartOrEnd::end ? aNodes.Length() - 1 : 0; - bool isList = nsHTMLEditUtils::IsList(&aListOrTable); + *outHighWaterMark = -1; + int32_t listAndTableParents = aListsAndTables.Count(); - for (nsCOMPtr node = aNodes[idx]; node; - node = node->GetParentNode()) { - if ((isList && nsHTMLEditUtils::IsListItem(node)) || - (!isList && nsHTMLEditUtils::IsTableElement(node) && - !node->IsHTMLElement(nsGkAtoms::table))) { - nsCOMPtr structureNode = node->GetParentElement(); - if (isList) { - while (structureNode && !nsHTMLEditUtils::IsList(structureNode)) { - structureNode = structureNode->GetParentElement(); + // scan insertion list for table elements (other than table). + int32_t listCount = aPasteNodes.Count(); + int32_t j; + for (j=0; j curNode = aPasteNodes[j]; + + NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE); + if (nsHTMLEditUtils::IsTableElement(curNode) && !nsHTMLEditUtils::IsTable(curNode)) + { + nsCOMPtr theTable = GetTableParent(curNode); + if (theTable) + { + int32_t indexT = aListsAndTables.IndexOf(theTable); + if (indexT >= 0) + { + *outHighWaterMark = indexT; + if (*outHighWaterMark == listAndTableParents-1) break; } - } else { - while (structureNode && - !structureNode->IsHTMLElement(nsGkAtoms::table)) { - structureNode = structureNode->GetParentElement(); + else + { + break; } } - if (structureNode == &aListOrTable) { - if (isList) { - return structureNode; + } + if (nsHTMLEditUtils::IsListItem(curNode)) + { + nsCOMPtr theList = GetListParent(curNode); + if (theList) + { + int32_t indexL = aListsAndTables.IndexOf(theList); + if (indexL >= 0) + { + *outHighWaterMark = indexL; + if (*outHighWaterMark == listAndTableParents-1) break; + } + else + { + break; } - return node; } } } - return nullptr; + return NS_OK; } -void -nsHTMLEditor::ReplaceOrphanedStructure(StartOrEnd aStartOrEnd, - nsTArray>& aNodeArray, - nsTArray>& aListAndTableArray, +nsresult +nsHTMLEditor::ScanForListAndTableStructure( bool aEnd, + nsCOMArray& aNodes, + nsIDOMNode *aListOrTable, + nsCOMPtr *outReplaceNode) +{ + NS_ENSURE_TRUE(aListOrTable, NS_ERROR_NULL_POINTER); + NS_ENSURE_TRUE(outReplaceNode, NS_ERROR_NULL_POINTER); + + *outReplaceNode = 0; + + // look upward from first/last paste node for a piece of this list/table + int32_t listCount = aNodes.Count(), idx = 0; + if (aEnd) idx = listCount-1; + bool bList = nsHTMLEditUtils::IsList(aListOrTable); + + nsCOMPtr pNode = aNodes[idx]; + nsCOMPtr originalNode = pNode; + while (pNode) + { + if ((bList && nsHTMLEditUtils::IsListItem(pNode)) || + (!bList && (nsHTMLEditUtils::IsTableElement(pNode) && !nsHTMLEditUtils::IsTable(pNode)))) + { + nsCOMPtr structureNode; + if (bList) structureNode = GetListParent(pNode); + else structureNode = GetTableParent(pNode); + if (structureNode == aListOrTable) + { + if (bList) + *outReplaceNode = structureNode; + else + *outReplaceNode = pNode; + break; + } + } + nsCOMPtr parent; + pNode->GetParentNode(getter_AddRefs(parent)); + pNode = parent; + } + return NS_OK; +} + +nsresult +nsHTMLEditor::ReplaceOrphanedStructure(bool aEnd, + nsCOMArray& aNodeArray, + nsCOMArray& aListAndTableArray, int32_t aHighWaterMark) { - OwningNonNull curNode = aListAndTableArray[aHighWaterMark]; + nsCOMPtr curNode = aListAndTableArray[aHighWaterMark]; + NS_ENSURE_TRUE(curNode, NS_ERROR_NULL_POINTER); - // Find substructure of list or table that must be included in paste. - nsCOMPtr replaceNode = - ScanForListAndTableStructure(aStartOrEnd, aNodeArray, curNode); + nsCOMPtr replaceNode, originalNode; - if (!replaceNode) { - return; - } - - // If we found substructure, paste it instead of its descendants. - // Postprocess list to remove any descendants of this node so that we don't - // insert them twice. - while (aNodeArray.Length()) { - int32_t idx = aStartOrEnd == StartOrEnd::start ? 0 - : aNodeArray.Length() - 1; - OwningNonNull endpoint = aNodeArray[idx]; - if (!nsEditorUtils::IsDescendantOf(endpoint, replaceNode)) { - break; - } - aNodeArray.RemoveElementAt(idx); - } - - // Now replace the removed nodes with the structural parent - if (aStartOrEnd == StartOrEnd::end) { - aNodeArray.AppendElement(*replaceNode); - } else { - aNodeArray.InsertElementAt(0, *replaceNode); + // find substructure of list or table that must be included in paste. + nsresult rv = ScanForListAndTableStructure(aEnd, aNodeArray, + curNode, address_of(replaceNode)); + NS_ENSURE_SUCCESS(rv, rv); + + // if we found substructure, paste it instead of its descendants + if (replaceNode) + { + // postprocess list to remove any descendants of this node + // so that we don't insert them twice. + nsCOMPtr endpoint; + do + { + endpoint = GetArrayEndpoint(aEnd, aNodeArray); + if (!endpoint) break; + if (nsEditorUtils::IsDescendantOf(endpoint, replaceNode)) + aNodeArray.RemoveObject(endpoint); + else + break; + } while(endpoint); + + // now replace the removed nodes with the structural parent + if (aEnd) aNodeArray.AppendObject(replaceNode); + else aNodeArray.InsertObjectAt(replaceNode, 0); } + return NS_OK; +} + +nsIDOMNode* nsHTMLEditor::GetArrayEndpoint(bool aEnd, + nsCOMArray& aNodeArray) +{ + int32_t listCount = aNodeArray.Count(); + if (listCount <= 0) { + return nullptr; + } + + if (aEnd) { + return aNodeArray[listCount-1]; + } + + return aNodeArray[0]; } diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index 51dcdc22cb02..875b2fed0a12 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -13,10 +13,10 @@ #include "mozilla/Preferences.h" #include "mozilla/dom/Selection.h" #include "mozilla/dom/Element.h" -#include "mozilla/dom/OwningNonNull.h" #include "mozilla/mozalloc.h" #include "nsAString.h" #include "nsAlgorithm.h" +#include "nsCOMArray.h" #include "nsCRT.h" #include "nsCRTGlue.h" #include "nsComponentManagerUtils.h" @@ -106,8 +106,7 @@ IsStyleCachePreservingAction(EditAction action) class nsTableCellAndListItemFunctor : public nsBoolDomIterFunctor { public: - // Used to build list of all li's, td's & th's iterator covers - virtual bool operator()(nsINode* aNode) const + virtual bool operator()(nsIDOMNode* aNode) // used to build list of all li's, td's & th's iterator covers { if (nsHTMLEditUtils::IsTableCell(aNode)) return true; if (nsHTMLEditUtils::IsListItem(aNode)) return true; @@ -118,11 +117,9 @@ class nsTableCellAndListItemFunctor : public nsBoolDomIterFunctor class nsBRNodeFunctor : public nsBoolDomIterFunctor { public: - virtual bool operator()(nsINode* aNode) const + virtual bool operator()(nsIDOMNode* aNode) { - if (aNode->IsHTMLElement(nsGkAtoms::br)) { - return true; - } + if (nsTextEditUtils::IsBreak(aNode)) return true; return false; } }; @@ -131,11 +128,12 @@ class nsEmptyEditableFunctor : public nsBoolDomIterFunctor { public: explicit nsEmptyEditableFunctor(nsHTMLEditor* editor) : mHTMLEditor(editor) {} - virtual bool operator()(nsINode* aNode) const + virtual bool operator()(nsIDOMNode* aNode) { if (mHTMLEditor->IsEditable(aNode) && - (nsHTMLEditUtils::IsListItem(aNode) || - nsHTMLEditUtils::IsTableCellOrCaption(GetAsDOMNode(aNode)))) { + (nsHTMLEditUtils::IsListItem(aNode) || + nsHTMLEditUtils::IsTableCellOrCaption(aNode))) + { bool bIsEmptyNode; nsresult res = mHTMLEditor->IsEmptyNode(aNode, &bIsEmptyNode, false, false); NS_ENSURE_SUCCESS(res, false); @@ -152,7 +150,7 @@ class nsEditableTextFunctor : public nsBoolDomIterFunctor { public: explicit nsEditableTextFunctor(nsHTMLEditor* editor) : mHTMLEditor(editor) {} - virtual bool operator()(nsINode* aNode) const + virtual bool operator()(nsIDOMNode* aNode) { if (nsEditor::IsTextNode(aNode) && mHTMLEditor->IsEditable(aNode)) { @@ -276,7 +274,8 @@ nsHTMLEditRules::Init(nsPlaintextEditor *aEditor) if (node->IsElement()) { ErrorResult rv; mDocChangeRange->SelectNode(*node, rv); - AdjustSpecialBreaks(); + res = AdjustSpecialBreaks(node); + NS_ENSURE_SUCCESS(res, res); } // add ourselves as a listener to edit actions @@ -446,7 +445,8 @@ nsHTMLEditRules::AfterEditInner(EditAction action, nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor); // expand the "changed doc range" as needed - PromoteRange(*mDocChangeRange, action); + res = PromoteRange(mDocChangeRange, action); + NS_ENSURE_SUCCESS(res, res); // if we did a ranged deletion or handling backspace key, make sure we have // a place to put caret. @@ -460,7 +460,8 @@ nsHTMLEditRules::AfterEditInner(EditAction action, } // add in any needed
    s, and remove any unneeded ones. - AdjustSpecialBreaks(); + res = AdjustSpecialBreaks(); + NS_ENSURE_SUCCESS(res, res); // merge any adjacent text nodes if ( (action != EditAction::insertText && @@ -690,30 +691,33 @@ nsHTMLEditRules::GetListState(bool *aMixed, bool *aOL, bool *aUL, bool *aDL) *aDL = false; bool bNonList = false; - nsTArray> arrayOfNodes; - nsresult res = GetListActionNodes(arrayOfNodes, EntireList::no, - TouchContent::no); + nsCOMArray arrayOfNodes; + nsresult res = GetListActionNodes(arrayOfNodes, false, true); NS_ENSURE_SUCCESS(res, res); // Examine list type for nodes in selection. - for (const auto& curNode : arrayOfNodes) { - if (!curNode->IsElement()) { + int32_t listCount = arrayOfNodes.Count(); + for (int32_t i = listCount - 1; i >= 0; --i) { + nsIDOMNode* curDOMNode = arrayOfNodes[i]; + nsCOMPtr curElement = do_QueryInterface(curDOMNode); + + if (!curElement) { bNonList = true; - } else if (curNode->IsHTMLElement(nsGkAtoms::ul)) { + } else if (curElement->IsHTMLElement(nsGkAtoms::ul)) { *aUL = true; - } else if (curNode->IsHTMLElement(nsGkAtoms::ol)) { + } else if (curElement->IsHTMLElement(nsGkAtoms::ol)) { *aOL = true; - } else if (curNode->IsHTMLElement(nsGkAtoms::li)) { - if (dom::Element* parent = curNode->GetParentElement()) { + } else if (curElement->IsHTMLElement(nsGkAtoms::li)) { + if (dom::Element* parent = curElement->GetParentElement()) { if (parent->IsHTMLElement(nsGkAtoms::ul)) { *aUL = true; } else if (parent->IsHTMLElement(nsGkAtoms::ol)) { *aOL = true; } } - } else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::dl, - nsGkAtoms::dt, - nsGkAtoms::dd)) { + } else if (curElement->IsAnyOfHTMLElements(nsGkAtoms::dl, + nsGkAtoms::dt, + nsGkAtoms::dd)) { *aDL = true; } else { bNonList = true; @@ -738,27 +742,29 @@ nsHTMLEditRules::GetListItemState(bool *aMixed, bool *aLI, bool *aDT, bool *aDD) *aDD = false; bool bNonList = false; - nsTArray> arrayOfNodes; - nsresult res = GetListActionNodes(arrayOfNodes, EntireList::no, - TouchContent::no); + nsCOMArray arrayOfNodes; + nsresult res = GetListActionNodes(arrayOfNodes, false, true); NS_ENSURE_SUCCESS(res, res); // examine list type for nodes in selection - for (const auto& node : arrayOfNodes) { - if (!node->IsElement()) { + int32_t listCount = arrayOfNodes.Count(); + for (int32_t i = listCount - 1; i >= 0; --i) { + nsIDOMNode* curNode = arrayOfNodes[i]; + nsCOMPtr element = do_QueryInterface(curNode); + if (!element) { bNonList = true; - } else if (node->IsAnyOfHTMLElements(nsGkAtoms::ul, - nsGkAtoms::ol, - nsGkAtoms::li)) { + } else if (element->IsAnyOfHTMLElements(nsGkAtoms::ul, + nsGkAtoms::ol, + nsGkAtoms::li)) { *aLI = true; - } else if (node->IsHTMLElement(nsGkAtoms::dt)) { + } else if (element->IsHTMLElement(nsGkAtoms::dt)) { *aDT = true; - } else if (node->IsHTMLElement(nsGkAtoms::dd)) { + } else if (element->IsHTMLElement(nsGkAtoms::dd)) { *aDD = true; - } else if (node->IsHTMLElement(nsGkAtoms::dl)) { + } else if (element->IsHTMLElement(nsGkAtoms::dl)) { // need to look inside dl and see which types of items it has bool bDT, bDD; - GetDefinitionListItemTypes(node->AsElement(), &bDT, &bDD); + GetDefinitionListItemTypes(element, &bDT, &bDD); *aDT |= bDT; *aDD |= bDD; } else { @@ -807,11 +813,11 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) NS_ENSURE_SUCCESS(res, res); // is the selection collapsed? - nsCOMPtr nodeToExamine; + nsCOMPtr nodeToExamine; if (selection->Collapsed()) { // if it is, we want to look at 'parent' and its ancestors // for divs with alignment on them - nodeToExamine = parent; + nodeToExamine = GetAsDOMNode(parent); } else if (!mHTMLEditor) { return NS_ERROR_UNEXPECTED; @@ -819,33 +825,35 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) else if (mHTMLEditor->IsTextNode(parent)) { // if we are in a text node, then that is the node of interest - nodeToExamine = parent; + nodeToExamine = GetAsDOMNode(parent); } else if (parent->IsHTMLElement(nsGkAtoms::html) && offset == rootOffset) { // if we have selected the body, let's look at the first editable node NS_ENSURE_STATE(mHTMLEditor); - nodeToExamine = mHTMLEditor->GetNextNode(parent, offset, true); + nodeToExamine = + GetAsDOMNode(mHTMLEditor->GetNextNode(parent, offset, true)); } else { nsTArray> arrayOfRanges; - GetPromotedRanges(*selection, arrayOfRanges, EditAction::align); + res = GetPromotedRanges(selection, arrayOfRanges, EditAction::align); + NS_ENSURE_SUCCESS(res, res); // use these ranges to construct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsCOMArray arrayOfNodes; res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, - EditAction::align, TouchContent::no); + EditAction::align, true); NS_ENSURE_SUCCESS(res, res); - nodeToExamine = arrayOfNodes.SafeElementAt(0); + nodeToExamine = arrayOfNodes.SafeObjectAt(0); } NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER); NS_NAMED_LITERAL_STRING(typeAttrName, "align"); nsIAtom *dummyProperty = nullptr; - nsCOMPtr blockParent; + nsCOMPtr blockParent; NS_ENSURE_STATE(mHTMLEditor); if (mHTMLEditor->IsBlockNode(nodeToExamine)) - blockParent = nodeToExamine->AsElement(); + blockParent = nodeToExamine; else { NS_ENSURE_STATE(mHTMLEditor); blockParent = mHTMLEditor->GetBlockNodeParent(nodeToExamine); @@ -856,16 +864,17 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) NS_ENSURE_STATE(mHTMLEditor); if (mHTMLEditor->IsCSSEnabled()) { + nsCOMPtr blockParentContent = do_QueryInterface(blockParent); NS_ENSURE_STATE(mHTMLEditor); - if (mHTMLEditor->mHTMLCSSUtils->IsCSSEditableProperty(blockParent, - dummyProperty, - &typeAttrName)) { + if (blockParentContent && + mHTMLEditor->mHTMLCSSUtils->IsCSSEditableProperty(blockParentContent, dummyProperty, &typeAttrName)) + { // we are in CSS mode and we know how to align this element with CSS nsAutoString value; // let's get the value(s) of text-align or margin-left/margin-right NS_ENSURE_STATE(mHTMLEditor); mHTMLEditor->mHTMLCSSUtils->GetCSSEquivalentToHTMLInlineStyleSet( - blockParent, dummyProperty, &typeAttrName, value, + blockParentContent, dummyProperty, &typeAttrName, value, nsHTMLCSSUtils::eComputed); if (value.EqualsLiteral("center") || value.EqualsLiteral("-moz-center") || @@ -892,6 +901,7 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) } // check up the ladder for divs with alignment + nsCOMPtr temp = nodeToExamine; bool isFirstNodeToExamine = true; while (nodeToExamine) { @@ -902,7 +912,8 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) // behaviour of html tables regarding to text alignment return NS_OK; } - if (nsHTMLEditUtils::SupportsAlignAttr(GetAsDOMNode(nodeToExamine))) { + if (nsHTMLEditUtils::SupportsAlignAttr(nodeToExamine)) + { // check for alignment nsCOMPtr elem = do_QueryInterface(nodeToExamine); if (elem) @@ -925,7 +936,9 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign) } } isFirstNodeToExamine = false; - nodeToExamine = nodeToExamine->GetParentNode(); + res = nodeToExamine->GetParentNode(getter_AddRefs(temp)); + if (NS_FAILED(res)) temp = nullptr; + nodeToExamine = temp; } return NS_OK; } @@ -952,17 +965,23 @@ nsHTMLEditRules::GetIndentState(bool *aCanIndent, bool *aCanOutdent) OwningNonNull selection = *mHTMLEditor->GetSelection(); // contruct a list of nodes to act on. - nsTArray> arrayOfNodes; - nsresult res = GetNodesFromSelection(*selection, EditAction::indent, - arrayOfNodes, TouchContent::no); + nsCOMArray arrayOfNodes; + nsresult res = GetNodesFromSelection(selection, EditAction::indent, + arrayOfNodes, true); NS_ENSURE_SUCCESS(res, res); // examine nodes in selection for blockquotes or list elements; // these we can outdent. Note that we return true for canOutdent // if *any* of the selection is outdentable, rather than all of it. + int32_t listCount = arrayOfNodes.Count(); + int32_t i; NS_ENSURE_STATE(mHTMLEditor); bool useCSS = mHTMLEditor->IsCSSEnabled(); - for (auto& curNode : Reversed(arrayOfNodes)) { + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr curNode = do_QueryInterface(arrayOfNodes[i]); + NS_ENSURE_STATE(curNode || !arrayOfNodes[i]); + if (nsHTMLEditUtils::IsNodeThatCanOutdent(GetAsDOMNode(curNode))) { *aCanOutdent = true; break; @@ -1053,19 +1072,22 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) // using "x" as an uninitialized value, since "" is meaningful nsAutoString formatStr(NS_LITERAL_STRING("x")); - nsTArray> arrayOfNodes; - nsresult res = GetParagraphFormatNodes(arrayOfNodes, TouchContent::no); + nsCOMArray arrayOfNodes; + nsresult res = GetParagraphFormatNodes(arrayOfNodes, true); NS_ENSURE_SUCCESS(res, res); // post process list. We need to replace any block nodes that are not format // nodes with their content. This is so we only have to look "up" the hierarchy // to find format nodes, instead of both up and down. - for (int32_t i = arrayOfNodes.Length() - 1; i >= 0; i--) { - auto& curNode = arrayOfNodes[i]; + int32_t listCount = arrayOfNodes.Count(); + int32_t i; + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr curNode = arrayOfNodes[i]; nsAutoString format; // if it is a known format node we have it easy - if (IsBlockNode(GetAsDOMNode(curNode)) && - !nsHTMLEditUtils::IsFormatNode(curNode)) { + if (IsBlockNode(curNode) && !nsHTMLEditUtils::IsFormatNode(curNode)) + { // arrayOfNodes.RemoveObject(curNode); res = AppendInnerFormatNodes(arrayOfNodes, curNode); NS_ENSURE_SUCCESS(res, res); @@ -1074,8 +1096,10 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) // we might have an empty node list. if so, find selection parent // and put that on the list - if (!arrayOfNodes.Length()) { - nsCOMPtr selNode; + listCount = arrayOfNodes.Count(); + if (!listCount) + { + nsCOMPtr selNode; int32_t selOffset; NS_ENSURE_STATE(mHTMLEditor); nsRefPtr selection = mHTMLEditor->GetSelection(); @@ -1084,7 +1108,8 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) res = mHTMLEditor->GetStartNodeAndOffset(selection, getter_AddRefs(selNode), &selOffset); NS_ENSURE_SUCCESS(res, res); NS_ENSURE_TRUE(selNode, NS_ERROR_NULL_POINTER); - arrayOfNodes.AppendElement(*selNode); + arrayOfNodes.AppendObject(selNode); + listCount = 1; } // remember root node @@ -1093,12 +1118,15 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) NS_ENSURE_TRUE(rootElem, NS_ERROR_NULL_POINTER); // loop through the nodes in selection and examine their paragraph format - for (auto& curNode : Reversed(arrayOfNodes)) { + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr curNode = arrayOfNodes[i]; nsAutoString format; // if it is a known format node we have it easy - if (nsHTMLEditUtils::IsFormatNode(curNode)) { - GetFormatString(GetAsDOMNode(curNode), format); - } else if (IsBlockNode(GetAsDOMNode(curNode))) { + if (nsHTMLEditUtils::IsFormatNode(curNode)) + GetFormatString(curNode, format); + else if (IsBlockNode(curNode)) + { // this is a div or some other non-format block. // we should ignore it. Its children were appended to this list // by AppendInnerFormatNodes() call above. We will get needed @@ -1107,7 +1135,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) } else { - nsCOMPtr node, tmp = GetAsDOMNode(curNode); + nsCOMPtr node, tmp = curNode; tmp->GetParentNode(getter_AddRefs(node)); while (node) { @@ -1144,7 +1172,17 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat) } nsresult -nsHTMLEditRules::AppendInnerFormatNodes(nsTArray>& aArray, +nsHTMLEditRules::AppendInnerFormatNodes(nsCOMArray& aArray, + nsIDOMNode *aNode) +{ + nsCOMPtr node = do_QueryInterface(aNode); + NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); + + return AppendInnerFormatNodes(aArray, node); +} + +nsresult +nsHTMLEditRules::AppendInnerFormatNodes(nsCOMArray& aArray, nsINode* aNode) { MOZ_ASSERT(aNode); @@ -1163,11 +1201,11 @@ nsHTMLEditRules::AppendInnerFormatNodes(nsTArray>& aArray // if it's a div, etc, recurse AppendInnerFormatNodes(aArray, child); } else if (isFormat) { - aArray.AppendElement(*child); + aArray.AppendObject(child->AsDOMNode()); } else if (!foundInline) { // if this is the first inline we've found, use it foundInline = true; - aArray.AppendElement(*child); + aArray.AppendObject(child->AsDOMNode()); } } return NS_OK; @@ -2399,10 +2437,13 @@ nsHTMLEditRules::WillDeleteSelection(Selection* aSelection, OwningNonNull range = *aSelection->GetRangeAt(rangeIdx); // Build a list of nodes in the range - nsTArray> arrayOfNodes; + nsTArray> arrayOfNodes; nsTrivialFunctor functor; - nsDOMSubtreeIterator iter(*range); - iter.AppendList(functor, arrayOfNodes); + nsDOMSubtreeIterator iter; + res = iter.Init(range); + NS_ENSURE_SUCCESS(res, res); + res = iter.AppendList(functor, arrayOfNodes); + NS_ENSURE_SUCCESS(res, res); // Now that we have the list, delete non-table elements int32_t listCount = arrayOfNodes.Length(); @@ -2854,17 +2895,22 @@ nsHTMLEditRules::JoinBlocks(nsIDOMNode *aLeftNode, nsresult nsHTMLEditRules::MoveBlock(nsIDOMNode *aLeftBlock, nsIDOMNode *aRightBlock, int32_t aLeftOffset, int32_t aRightOffset) { - nsTArray> arrayOfNodes; + nsCOMArray arrayOfNodes; + nsCOMPtr isupports; // GetNodesFromPoint is the workhorse that figures out what we wnat to move. nsresult res = GetNodesFromPoint(::DOMPoint(aRightBlock,aRightOffset), - EditAction::makeList, arrayOfNodes, - TouchContent::no); + EditAction::makeList, arrayOfNodes, true); NS_ENSURE_SUCCESS(res, res); - for (auto& curNode : arrayOfNodes) { + int32_t listCount = arrayOfNodes.Count(); + int32_t i; + for (i=0; iDeleteNode(curNode); @@ -2872,7 +2918,7 @@ nsHTMLEditRules::MoveBlock(nsIDOMNode *aLeftBlock, nsIDOMNode *aRightBlock, int3 else { // otherwise move the content as is, checking against the dtd. - res = MoveNodeSmart(GetAsDOMNode(curNode), aLeftBlock, &aLeftOffset); + res = MoveNodeSmart(curNode, aLeftBlock, &aLeftOffset); } } return res; @@ -3048,17 +3094,18 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); - nsTArray> arrayOfNodes; - res = GetListActionNodes(arrayOfNodes, - aEntireList ? EntireList::yes : EntireList::no); + nsCOMArray arrayOfNodes; + res = GetListActionNodes(arrayOfNodes, aEntireList); NS_ENSURE_SUCCESS(res, res); + int32_t listCount = arrayOfNodes.Count(); + // check if all our nodes are
    s, or empty inlines bool bOnlyBreaks = true; - for (auto& curNode : arrayOfNodes) { + for (int32_t j = 0; j < listCount; j++) { + nsIDOMNode* curNode = arrayOfNodes[j]; // if curNode is not a Break or empty inline, we're done - if (!nsTextEditUtils::IsBreak(curNode) && - !IsEmptyInline(GetAsDOMNode(curNode))) { + if (!nsTextEditUtils::IsBreak(curNode) && !IsEmptyInline(curNode)) { bOnlyBreaks = false; break; } @@ -3066,12 +3113,12 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, // if no nodes, we make empty list. Ditto if the user tried to make a list // of some # of breaks. - if (!arrayOfNodes.Length() || bOnlyBreaks) { + if (!listCount || bOnlyBreaks) { // if only breaks, delete them if (bOnlyBreaks) { - for (auto& node : arrayOfNodes) { + for (int32_t j = 0; j < (int32_t)listCount; j++) { NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->DeleteNode(node); + res = mHTMLEditor->DeleteNode(arrayOfNodes[j]); NS_ENSURE_SUCCESS(res, res); } } @@ -3113,20 +3160,21 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, // if there is only one node in the array, and it is a list, div, or // blockquote, then look inside of it until we find inner list or content. - LookInsideDivBQandList(arrayOfNodes); + res = LookInsideDivBQandList(arrayOfNodes); + NS_ENSURE_SUCCESS(res, res); // Ok, now go through all the nodes and put then in the list, // or whatever is approriate. Wohoo! - uint32_t listCount = arrayOfNodes.Length(); + listCount = arrayOfNodes.Count(); nsCOMPtr curParent; nsCOMPtr curList, prevListItem; - for (uint32_t i = 0; i < listCount; i++) { + for (int32_t i = 0; i < listCount; i++) { // here's where we actually figure out what to do nsCOMPtr newBlock; - NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); - nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); + nsCOMPtr curNode = do_QueryInterface(arrayOfNodes[i]); + NS_ENSURE_STATE(curNode); int32_t offset; curParent = nsEditor::GetNodeLocation(curNode, &offset); @@ -3246,11 +3294,12 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection, if (curNode->IsHTMLElement(nsGkAtoms::div)) { prevListItem = nullptr; int32_t j = i + 1; - GetInnerContent(*curNode, arrayOfNodes, &j); + res = GetInnerContent(curNode->AsDOMNode(), arrayOfNodes, &j); + NS_ENSURE_SUCCESS(res, res); NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->RemoveContainer(curNode); NS_ENSURE_SUCCESS(res, res); - listCount = arrayOfNodes.Length(); + listCount = arrayOfNodes.Count(); continue; } @@ -3328,44 +3377,51 @@ nsHTMLEditRules::WillRemoveList(Selection* aSelection, nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); nsTArray> arrayOfRanges; - GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::makeList); + res = GetPromotedRanges(aSelection, arrayOfRanges, EditAction::makeList); + NS_ENSURE_SUCCESS(res, res); // use these ranges to contruct a list of nodes to act on. - nsTArray> arrayOfNodes; - res = GetListActionNodes(arrayOfNodes, EntireList::no); + nsCOMArray arrayOfNodes; + res = GetListActionNodes(arrayOfNodes, false); NS_ENSURE_SUCCESS(res, res); // Remove all non-editable nodes. Leave them be. - int32_t listCount = arrayOfNodes.Length(); + int32_t listCount = arrayOfNodes.Count(); int32_t i; for (i=listCount-1; i>=0; i--) { - OwningNonNull testNode = arrayOfNodes[i]; + nsIDOMNode* testNode = arrayOfNodes[i]; NS_ENSURE_STATE(mHTMLEditor); if (!mHTMLEditor->IsEditable(testNode)) { - arrayOfNodes.RemoveElementAt(i); + arrayOfNodes.RemoveObjectAt(i); } } // reset list count - listCount = arrayOfNodes.Length(); + listCount = arrayOfNodes.Count(); // Only act on lists or list items in the array - for (auto& curNode : arrayOfNodes) { + nsCOMPtr curParent; + for (i=0; i> arrayOfNodes; - res = GetNodesFromSelection(*aSelection, EditAction::makeBasicBlock, + nsCOMArray arrayOfNodes; + res = GetNodesFromSelection(aSelection, EditAction::makeBasicBlock, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); // Remove all non-editable nodes. Leave them be. - int32_t listCount = arrayOfNodes.Length(); + int32_t listCount = arrayOfNodes.Count(); int32_t i; for (i=listCount-1; i>=0; i--) { NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsEditable(arrayOfNodes[i])) { - arrayOfNodes.RemoveElementAt(i); + if (!mHTMLEditor->IsEditable(arrayOfNodes[i])) + { + arrayOfNodes.RemoveObjectAt(i); } } - + // reset list count - listCount = arrayOfNodes.Length(); + listCount = arrayOfNodes.Count(); // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) @@ -3487,9 +3544,10 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, else // we are making a block { // consume a br, if needed + nsCOMPtr brNode; NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr brNode = - mHTMLEditor->GetNextHTMLNode(parent, offset, true); + res = mHTMLEditor->GetNextHTMLNode(parent->AsDOMNode(), offset, + address_of(brNode), true); NS_ENSURE_SUCCESS(res, res); if (brNode && nsTextEditUtils::IsBreak(brNode)) { @@ -3497,7 +3555,7 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, res = mHTMLEditor->DeleteNode(brNode); NS_ENSURE_SUCCESS(res, res); // we don't need to act on this node any more - arrayOfNodes.RemoveElement(brNode); + arrayOfNodes.RemoveObject(brNode); } // make sure we can put a block here res = SplitAsNeeded(blockType, parent, offset); @@ -3509,12 +3567,13 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, // remember our new block for postprocessing mNewBlock = theBlock; // delete anything that was in the list of nodes - while (!arrayOfNodes.IsEmpty()) { - OwningNonNull curNode = arrayOfNodes[0]; + for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) + { + nsCOMPtr curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveElementAt(0); + arrayOfNodes.RemoveObjectAt(0); } // put selection in new block res = aSelection->Collapse(theBlock,0); @@ -3528,13 +3587,13 @@ nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection, // Ok, now go through all the nodes and make the right kind of blocks, // or whatever is approriate. Wohoo! // Note: blockquote is handled a little differently - if (tString.EqualsLiteral("blockquote")) { + if (tString.EqualsLiteral("blockquote")) res = MakeBlockquote(arrayOfNodes); - } else if (tString.EqualsLiteral("normal") || tString.IsEmpty()) { + else if (tString.EqualsLiteral("normal") || + tString.IsEmpty() ) res = RemoveBlockStyle(arrayOfNodes); - } else { - res = ApplyBlockStyle(arrayOfNodes, *blockType); - } + else + res = ApplyBlockStyle(arrayOfNodes, aBlockType); return res; } return res; @@ -3591,22 +3650,21 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, NS_ENSURE_SUCCESS(res, res); NS_ENSURE_STATE(mHTMLEditor); nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor); - nsTArray> arrayOfRanges; - nsTArray> arrayOfNodes; + nsTArray> arrayOfRanges; + nsCOMArray arrayOfNodes; // short circuit: detect case of collapsed selection inside an
  • . // just sublist that
  • . This prevents bug 97797. - nsCOMPtr liNode; + nsCOMPtr liNode; if (aSelection->Collapsed()) { - nsCOMPtr node; - nsCOMPtr block; + nsCOMPtr node, block; int32_t offset; NS_ENSURE_STATE(mHTMLEditor); nsresult res = mHTMLEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(node), &offset); NS_ENSURE_SUCCESS(res, res); - if (IsBlockNode(GetAsDOMNode(node))) { - block = node->AsElement(); + if (IsBlockNode(node)) { + block = node; } else { NS_ENSURE_STATE(mHTMLEditor); block = mHTMLEditor->GetBlockNodeParent(node); @@ -3617,7 +3675,7 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, if (liNode) { - arrayOfNodes.AppendElement(*liNode); + arrayOfNodes.AppendObject(liNode); } else { @@ -3625,10 +3683,10 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, // this basically just expands the range to include the immediate // block parent, and then further expands to include any ancestors // whose children are all in the range - res = GetNodesFromSelection(*aSelection, EditAction::indent, arrayOfNodes); + res = GetNodesFromSelection(aSelection, EditAction::indent, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); } - + // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { @@ -3649,12 +3707,13 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, mNewBlock = theBlock->AsDOMNode(); RelativeChangeIndentationOfElementNode(theBlock->AsDOMNode(), +1); // delete anything that was in the list of nodes - while (!arrayOfNodes.IsEmpty()) { - OwningNonNull curNode = arrayOfNodes[0]; + for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) + { + nsCOMPtr curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveElementAt(0); + arrayOfNodes.RemoveObjectAt(0); } // put selection in new block res = aSelection->Collapse(theBlock,0); @@ -3669,12 +3728,12 @@ nsHTMLEditRules::WillCSSIndent(Selection* aSelection, nsCOMPtr curParent; nsCOMPtr curList, curQuote; nsCOMPtr sibling; - int32_t listCount = arrayOfNodes.Length(); + int32_t listCount = arrayOfNodes.Count(); for (i=0; iIsContent()); - nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); + nsCOMPtr curNode = do_QueryInterface(arrayOfNodes[i]); + NS_ENSURE_STATE(!arrayOfNodes[i] || curNode); // Ignore all non-editable nodes. Leave them be. NS_ENSURE_STATE(mHTMLEditor); @@ -3808,10 +3867,11 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, // whose children are all in the range nsTArray> arrayOfRanges; - GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::indent); + res = GetPromotedRanges(aSelection, arrayOfRanges, EditAction::indent); + NS_ENSURE_SUCCESS(res, res); // use these ranges to contruct a list of nodes to act on. - nsTArray> arrayOfNodes; + nsCOMArray arrayOfNodes; res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::indent); NS_ENSURE_SUCCESS(res, res); @@ -3834,12 +3894,13 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, // remember our new block for postprocessing mNewBlock = theBlock->AsDOMNode(); // delete anything that was in the list of nodes - while (!arrayOfNodes.IsEmpty()) { - OwningNonNull curNode = arrayOfNodes[0]; + for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) + { + nsCOMPtr curNode = arrayOfNodes[0]; NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - arrayOfNodes.RemoveElementAt(0); + arrayOfNodes.RemoveObjectAt(0); } // put selection in new block res = aSelection->Collapse(theBlock,0); @@ -3854,12 +3915,12 @@ nsHTMLEditRules::WillHTMLIndent(Selection* aSelection, nsCOMPtr curParent; nsCOMPtr sibling; nsCOMPtr curList, curQuote, indentedLI; - int32_t listCount = arrayOfNodes.Length(); + int32_t listCount = arrayOfNodes.Count(); for (i=0; iIsContent()); - nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); + nsCOMPtr curNode = do_QueryInterface(arrayOfNodes[i]); + NS_ENSURE_STATE(!arrayOfNodes[i] || curNode); // Ignore all non-editable nodes. Leave them be. NS_ENSURE_STATE(mHTMLEditor); @@ -4040,8 +4101,8 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, // this basically just expands the range to include the immediate // block parent, and then further expands to include any ancestors // whose children are all in the range - nsTArray> arrayOfNodes; - res = GetNodesFromSelection(*aSelection, EditAction::outdent, + nsCOMArray arrayOfNodes; + res = GetNodesFromSelection(aSelection, EditAction::outdent, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); @@ -4050,13 +4111,20 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, nsCOMPtr curBlockQuote, firstBQChild, lastBQChild; bool curBlockQuoteIsIndentedWithCSS = false; - for (auto& curNode : arrayOfNodes) { + int32_t listCount = arrayOfNodes.Count(); + int32_t i; + for (i=0; i curParent = curNode->GetParentNode(); - int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; + nsCOMPtr curNode = arrayOfNodes[i]; + nsCOMPtr curNode_ = do_QueryInterface(curNode); + NS_ENSURE_STATE(curNode_); + nsCOMPtr curParent = curNode_->GetParentNode(); + int32_t offset = curParent ? curParent->IndexOf(curNode_) : -1; // is it a blockquote? - if (curNode->IsHTMLElement(nsGkAtoms::blockquote)) { + if (nsHTMLEditUtils::IsBlockquote(curNode)) + { // if it is a blockquote, remove it. // So we need to finish up dealng with any curBlockQuote first. if (curBlockQuote) @@ -4070,19 +4138,18 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, curBlockQuoteIsIndentedWithCSS = false; } NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(curNode)); + res = mHTMLEditor->RemoveBlockContainer(curNode); NS_ENSURE_SUCCESS(res, res); continue; } // is it a block with a 'margin' property? - if (useCSS && IsBlockNode(GetAsDOMNode(curNode))) { + if (useCSS && IsBlockNode(curNode)) + { NS_ENSURE_STATE(mHTMLEditor); - nsIAtom* marginProperty = - MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, - GetAsDOMNode(curNode)); + nsIAtom* marginProperty = MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, curNode); nsAutoString value; NS_ENSURE_STATE(mHTMLEditor); - mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(*curNode, + mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(*curNode_, *marginProperty, value); float f; @@ -4091,7 +4158,7 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, mHTMLEditor->mHTMLCSSUtils->ParseLength(value, &f, getter_AddRefs(unit)); if (f > 0) { - RelativeChangeIndentationOfElementNode(GetAsDOMNode(curNode), -1); + RelativeChangeIndentationOfElementNode(curNode, -1); continue; } } @@ -4112,7 +4179,7 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, curBlockQuoteIsIndentedWithCSS = false; } bool bOutOfList; - res = PopListItem(GetAsDOMNode(curNode), &bOutOfList); + res = PopListItem(curNode, &bOutOfList); NS_ENSURE_SUCCESS(res, res); continue; } @@ -4120,9 +4187,9 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (curBlockQuote) { // if so, is this node a descendant? - if (nsEditorUtils::IsDescendantOf(GetAsDOMNode(curNode), - curBlockQuote)) { - lastBQChild = GetAsDOMNode(curNode); + if (nsEditorUtils::IsDescendantOf(curNode, curBlockQuote)) + { + lastBQChild = curNode; continue; // then we don't need to do anything different for this node } else @@ -4142,7 +4209,7 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, } // are we inside a blockquote? - nsCOMPtr n = curNode; + nsCOMPtr n = curNode_; curBlockQuoteIsIndentedWithCSS = false; // keep looking up the hierarchy as long as we don't hit the body or the // active editing host or a table element (other than an entire table) @@ -4157,16 +4224,14 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (n->IsHTMLElement(nsGkAtoms::blockquote)) { // if so, remember it, and remember first node we are taking out of it. curBlockQuote = GetAsDOMNode(n); - firstBQChild = GetAsDOMNode(curNode); - lastBQChild = GetAsDOMNode(curNode); + firstBQChild = curNode; + lastBQChild = curNode; break; } else if (useCSS) { NS_ENSURE_STATE(mHTMLEditor); - nsIAtom* marginProperty = - MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, - GetAsDOMNode(curNode)); + nsIAtom* marginProperty = MarginPropertyAtomForIndent(mHTMLEditor->mHTMLCSSUtils, curNode); nsAutoString value; NS_ENSURE_STATE(mHTMLEditor); mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(*n, *marginProperty, @@ -4178,8 +4243,8 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (f > 0 && !(nsHTMLEditUtils::IsList(curParent) && nsHTMLEditUtils::IsList(curNode))) { curBlockQuote = GetAsDOMNode(n); - firstBQChild = GetAsDOMNode(curNode); - lastBQChild = GetAsDOMNode(curNode); + firstBQChild = curNode; + lastBQChild = curNode; curBlockQuoteIsIndentedWithCSS = true; break; } @@ -4194,14 +4259,17 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, if (nsHTMLEditUtils::IsList(curNode)) // just unwrap this sublist { NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(curNode)); + res = mHTMLEditor->RemoveBlockContainer(curNode); NS_ENSURE_SUCCESS(res, res); } // handled list item case above } else if (nsHTMLEditUtils::IsList(curNode)) // node is a list, but parent is non-list: move list items out { - nsCOMPtr child = curNode->GetLastChild(); + nsCOMPtr childDOM; + curNode->GetLastChild(getter_AddRefs(childDOM)); + nsCOMPtr child = do_QueryInterface(childDOM); + NS_ENSURE_STATE(!childDOM || child); while (child) { if (nsHTMLEditUtils::IsListItem(child)) @@ -4228,11 +4296,13 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, res = mHTMLEditor->DeleteNode(child); NS_ENSURE_SUCCESS(res, res); } - child = curNode->GetLastChild(); + curNode->GetLastChild(getter_AddRefs(childDOM)); + child = do_QueryInterface(childDOM); + NS_ENSURE_STATE(!childDOM || child); } // delete the now-empty list NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(curNode)); + res = mHTMLEditor->RemoveBlockContainer(curNode); NS_ENSURE_SUCCESS(res, res); } else if (useCSS) { @@ -4296,21 +4366,28 @@ nsHTMLEditRules::WillOutdent(Selection* aSelection, } -/////////////////////////////////////////////////////////////////////////////// -// RemovePartOfBlock: Split aBlock and move aStartChild to aEndChild out of -// aBlock. -nsresult -nsHTMLEditRules::RemovePartOfBlock(Element& aBlock, - nsIContent& aStartChild, - nsIContent& aEndChild) +/////////////////////////////////////////////////////////////////////////// +// RemovePartOfBlock: split aBlock and move aStartChild to aEndChild out +// of aBlock. return left side of block (if any) in +// aLeftNode. return right side of block (if any) in +// aRightNode. +// +nsresult +nsHTMLEditRules::RemovePartOfBlock(nsIDOMNode *aBlock, + nsIDOMNode *aStartChild, + nsIDOMNode *aEndChild, + nsCOMPtr *aLeftNode, + nsCOMPtr *aRightNode) { - nsresult res = SplitBlock(aBlock.AsDOMNode(), aStartChild.AsDOMNode(), - aEndChild.AsDOMNode()); + nsCOMPtr middleNode; + nsresult res = SplitBlock(aBlock, aStartChild, aEndChild, + aLeftNode, aRightNode, + address_of(middleNode)); NS_ENSURE_SUCCESS(res, res); - // Get rid of part of blockquote we are outdenting + // get rid of part of blockquote we are outdenting NS_ENSURE_STATE(mHTMLEditor); - return mHTMLEditor->RemoveBlockContainer(aBlock.AsDOMNode()); + return mHTMLEditor->RemoveBlockContainer(aBlock); } nsresult @@ -4563,10 +4640,8 @@ nsHTMLEditRules::CreateStyleForInsertText(Selection* aSelection, while (item) { NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr content = do_QueryInterface(node); - NS_ENSURE_STATE(content || !node); - res = mHTMLEditor->SetInlinePropertyOnNode(*content, *item->tag, - &item->attr, item->value); + res = mHTMLEditor->SetInlinePropertyOnNode(node, item->tag, &item->attr, + &item->value); NS_ENSURE_SUCCESS(res, res); item = mHTMLEditor->mTypeInState->TakeSetProperty(); } @@ -4630,20 +4705,21 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, // block parent, and then further expands to include any ancestors // whose children are all in the range *aHandled = true; - nsTArray> nodeArray; - res = GetNodesFromSelection(*aSelection, EditAction::align, nodeArray); + nsCOMArray arrayOfNodes; + res = GetNodesFromSelection(aSelection, EditAction::align, arrayOfNodes); NS_ENSURE_SUCCESS(res, res); // if we don't have any nodes, or we have only a single br, then we are // creating an empty alignment div. We have to do some different things for these. bool emptyDiv = false; - int32_t listCount = nodeArray.Length(); + int32_t listCount = arrayOfNodes.Count(); if (!listCount) emptyDiv = true; if (listCount == 1) { - OwningNonNull theNode = nodeArray[0]; + nsCOMPtr theNode = arrayOfNodes[0]; - if (nsHTMLEditUtils::SupportsAlignAttr(GetAsDOMNode(theNode))) { + if (nsHTMLEditUtils::SupportsAlignAttr(theNode)) + { // the node is a table element, an horiz rule, a paragraph, a div // or a section header; in HTML 4, it can directly carry the ALIGN // attribute and we don't need to make a div! If we are in CSS mode, @@ -4664,9 +4740,9 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, // // XXX: It seems a little error prone for the emptyDiv special // case code to assume that the start node of the selection - // is the parent of the single node in the nodeArray, as + // is the parent of the single node in the arrayOfNodes, as // the paragraph above points out. Do we rely on the selection - // start node because of the fact that nodeArray can be empty? + // start node because of the fact that arrayOfNodes can be empty? // We should probably revisit this issue. - kin nsCOMPtr parent; @@ -4735,7 +4811,8 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, // means that adjacent nodes in the array don't have the same parent. nsTArray transitionList; - MakeTransitionList(nodeArray, transitionList); + res = MakeTransitionList(arrayOfNodes, transitionList); + NS_ENSURE_SUCCESS(res, res); // Ok, now go through all the nodes and give them an align attrib or put them in a div, // or whatever is appropriate. Wohoo! @@ -4745,7 +4822,7 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, bool useCSS = mHTMLEditor->IsCSSEnabled(); for (int32_t i = 0; i < listCount; ++i) { // here's where we actually figure out what to do - nsCOMPtr curNode = nodeArray[i]->AsDOMNode(); + nsCOMPtr curNode = arrayOfNodes[i]; nsCOMPtr curContent = do_QueryInterface(curNode); NS_ENSURE_STATE(curContent); @@ -4800,7 +4877,7 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, else if (nsHTMLEditUtils::IsList(curParent)) { // if we don't use CSS, add a contraint to list element : they have // to be inside another list, ie >= second level of nesting - res = AlignInnerBlocks(*curContent, alignType); + res = AlignInnerBlocks(curNode, alignType); NS_ENSURE_SUCCESS(res, res); curDiv = 0; continue; @@ -4843,27 +4920,37 @@ nsHTMLEditRules::WillAlign(Selection* aSelection, } -/////////////////////////////////////////////////////////////////////////////// -// AlignInnerBlocks: Align inside table cells or list items -// +/////////////////////////////////////////////////////////////////////////// +// AlignInnerBlocks: align inside table cells or list items +// nsresult -nsHTMLEditRules::AlignInnerBlocks(nsINode& aNode, const nsAString* alignType) +nsHTMLEditRules::AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType) { - NS_ENSURE_TRUE(alignType, NS_ERROR_NULL_POINTER); - - // Gather list of table cells or list items - nsTArray> nodeArray; + NS_ENSURE_TRUE(aNode && alignType, NS_ERROR_NULL_POINTER); + nsresult res; + + // gather list of table cells or list items + nsCOMArray arrayOfNodes; nsTableCellAndListItemFunctor functor; - nsDOMIterator iter(aNode); - iter.AppendList(functor, nodeArray); + nsDOMIterator iter; + res = iter.Init(aNode); + NS_ENSURE_SUCCESS(res, res); + res = iter.AppendList(functor, arrayOfNodes); + NS_ENSURE_SUCCESS(res, res); + + // now that we have the list, align their contents as requested + int32_t listCount = arrayOfNodes.Count(); + int32_t j; - // Now that we have the list, align their contents as requested - for (auto& node : nodeArray) { - nsresult res = AlignBlockContents(node->AsDOMNode(), alignType); + for (j = 0; j < listCount; j++) + { + nsIDOMNode* node = arrayOfNodes[0]; + res = AlignBlockContents(node, alignType); NS_ENSURE_SUCCESS(res, res); + arrayOfNodes.RemoveObjectAt(0); } - return NS_OK; + return res; } @@ -5071,32 +5158,44 @@ nsHTMLEditRules::CheckForInvisibleBR(nsIDOMNode *aBlock, } -//////////////////////////////////////////////////////////////////////////////// -// GetInnerContent: aLists and aTables allow the caller to specify what kind of -// content to "look inside". If aTables is Tables::yes, look -// inside any table content, and insert the inner content into -// the supplied issupportsarray at offset aIndex. Similarly -// with aLists and list content. aIndex is updated to point -// past inserted elements. -// -void -nsHTMLEditRules::GetInnerContent(nsINode& aNode, - nsTArray>& aOutArrayOfNodes, - int32_t* aIndex, Lists aLists, Tables aTables) +/////////////////////////////////////////////////////////////////////////// +// GetInnerContent: aList and aTbl allow the caller to specify what kind +// of content to "look inside". If aTbl is true, look inside +// any table content, and insert the inner content into the +// supplied issupportsarray at offset aIndex. +// Similarly with aList and list content. +// aIndex is updated to point past inserted elements. +// +nsresult +nsHTMLEditRules::GetInnerContent(nsIDOMNode *aNode, nsCOMArray &outArrayOfNodes, + int32_t *aIndex, bool aList, bool aTbl) { - MOZ_ASSERT(aIndex); + nsCOMPtr aNode_ = do_QueryInterface(aNode); + NS_ENSURE_TRUE(aNode_ && aIndex, NS_ERROR_NULL_POINTER); - for (nsCOMPtr node = mHTMLEditor->GetFirstEditableChild(aNode); - node; node = node->GetNextSibling()) { - if ((aLists == Lists::yes && (nsHTMLEditUtils::IsList(node) || - nsHTMLEditUtils::IsListItem(node))) || - (aTables == Tables::yes && nsHTMLEditUtils::IsTableElement(node))) { - GetInnerContent(*node, aOutArrayOfNodes, aIndex, aLists, aTables); - } else { - aOutArrayOfNodes.InsertElementAt(*aIndex, *node); + nsCOMPtr node = + GetAsDOMNode(mHTMLEditor->GetFirstEditableChild(*aNode_)); + nsresult res = NS_OK; + while (NS_SUCCEEDED(res) && node) + { + if ( ( aList && (nsHTMLEditUtils::IsList(node) || + nsHTMLEditUtils::IsListItem(node) ) ) + || ( aTbl && nsHTMLEditUtils::IsTableElement(node) ) ) + { + res = GetInnerContent(node, outArrayOfNodes, aIndex, aList, aTbl); + NS_ENSURE_SUCCESS(res, res); + } + else + { + outArrayOfNodes.InsertObjectAt(node, *aIndex); (*aIndex)++; } + nsCOMPtr tmp; + res = node->GetNextSibling(getter_AddRefs(tmp)); + node = tmp; } + + return res; } /////////////////////////////////////////////////////////////////////////// @@ -5619,374 +5718,481 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode, } -/////////////////////////////////////////////////////////////////////////////// -// GetPromotedRanges: Run all the selection range endpoint through +/////////////////////////////////////////////////////////////////////////// +// GetPromotedRanges: run all the selection range endpoint through // GetPromotedPoint() -// -void -nsHTMLEditRules::GetPromotedRanges(Selection& aSelection, - nsTArray>& outArrayOfRanges, +// +nsresult +nsHTMLEditRules::GetPromotedRanges(Selection* inSelection, + nsTArray>& outArrayOfRanges, EditAction inOperationType) { - uint32_t rangeCount = aSelection.RangeCount(); + NS_ENSURE_TRUE(inSelection, NS_ERROR_NULL_POINTER); - for (uint32_t i = 0; i < rangeCount; i++) { - nsRefPtr selectionRange = aSelection.GetRangeAt(i); - MOZ_ASSERT(selectionRange); + int32_t rangeCount; + nsresult res = inSelection->GetRangeCount(&rangeCount); + NS_ENSURE_SUCCESS(res, res); + + int32_t i; + nsRefPtr selectionRange; + nsRefPtr opRange; - // Clone range so we don't muck with actual selection ranges - nsRefPtr opRange = selectionRange->CloneRange(); + for (i = 0; i < rangeCount; i++) + { + selectionRange = inSelection->GetRangeAt(i); + NS_ENSURE_STATE(selectionRange); - // Make a new adjusted range to represent the appropriate block content. - // The basic idea is to push out the range endpoints to truly enclose the - // blocks that we will affect. This call alters opRange. - PromoteRange(*opRange, inOperationType); + // clone range so we don't muck with actual selection ranges + opRange = selectionRange->CloneRange(); - // Stuff new opRange into array + // make a new adjusted range to represent the appropriate block content. + // The basic idea is to push out the range endpoints + // to truly enclose the blocks that we will affect. + // This call alters opRange. + res = PromoteRange(opRange, inOperationType); + NS_ENSURE_SUCCESS(res, res); + + // stuff new opRange into array outArrayOfRanges.AppendElement(opRange); } + return res; } -/////////////////////////////////////////////////////////////////////////////// -// PromoteRange: Expand a range to include any parents for which all editable -// children are already in range. -// -void -nsHTMLEditRules::PromoteRange(nsRange& aRange, EditAction aOperationType) +/////////////////////////////////////////////////////////////////////////// +// PromoteRange: expand a range to include any parents for which all +// editable children are already in range. +// +nsresult +nsHTMLEditRules::PromoteRange(nsRange* inRange, EditAction inOperationType) { - NS_ENSURE_TRUE(mHTMLEditor, ); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); - - nsCOMPtr startNode = aRange.GetStartParent(); - nsCOMPtr endNode = aRange.GetEndParent(); - int32_t startOffset = aRange.StartOffset(); - int32_t endOffset = aRange.EndOffset(); - + NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER); + nsresult res; + nsCOMPtr startNode, endNode; + int32_t startOffset, endOffset; + + res = inRange->GetStartContainer(getter_AddRefs(startNode)); + NS_ENSURE_SUCCESS(res, res); + res = inRange->GetStartOffset(&startOffset); + NS_ENSURE_SUCCESS(res, res); + res = inRange->GetEndContainer(getter_AddRefs(endNode)); + NS_ENSURE_SUCCESS(res, res); + res = inRange->GetEndOffset(&endOffset); + NS_ENSURE_SUCCESS(res, res); + // MOOSE major hack: // GetPromotedPoint doesn't really do the right thing for collapsed ranges // inside block elements that contain nothing but a solo
    . It's easier // to put a workaround here than to revamp GetPromotedPoint. :-( - if (startNode == endNode && startOffset == endOffset) { - nsCOMPtr block; - if (IsBlockNode(GetAsDOMNode(startNode))) { - block = startNode->AsElement(); + if ( (startNode == endNode) && (startOffset == endOffset)) + { + nsCOMPtr block; + if (IsBlockNode(startNode)) { + block = startNode; } else { + NS_ENSURE_STATE(mHTMLEditor); block = mHTMLEditor->GetBlockNodeParent(startNode); } - if (block) { + if (block) + { bool bIsEmptyNode = false; - nsCOMPtr root = mHTMLEditor->GetActiveEditingHost(); + // check for the editing host + NS_ENSURE_STATE(mHTMLEditor); + nsIContent *rootContent = mHTMLEditor->GetActiveEditingHost(); + nsCOMPtr rootNode = do_QueryInterface(rootContent); + nsCOMPtr blockNode = do_QueryInterface(block); + NS_ENSURE_TRUE(rootNode && blockNode, NS_ERROR_UNEXPECTED); // Make sure we don't go higher than our root element in the content tree - NS_ENSURE_TRUE(root, ); - if (!nsContentUtils::ContentIsDescendantOf(root, block)) { - mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, true, false); + if (!nsContentUtils::ContentIsDescendantOf(rootNode, blockNode)) + { + NS_ENSURE_STATE(mHTMLEditor); + res = mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, true, false); } - if (bIsEmptyNode) { + if (bIsEmptyNode) + { + uint32_t numChildren; + nsEditor::GetLengthOfDOMNode(block, numChildren); startNode = block; endNode = block; startOffset = 0; - endOffset = block->Length(); + endOffset = numChildren; } } } - // Make a new adjusted range to represent the appropriate block content. - // This is tricky. The basic idea is to push out the range endpoints to - // truly enclose the blocks that we will affect. - + // make a new adjusted range to represent the appropriate block content. + // this is tricky. the basic idea is to push out the range endpoints + // to truly enclose the blocks that we will affect + nsCOMPtr opStartNode; nsCOMPtr opEndNode; int32_t opStartOffset, opEndOffset; nsRefPtr opRange; - - GetPromotedPoint(kStart, GetAsDOMNode(startNode), startOffset, - aOperationType, address_of(opStartNode), &opStartOffset); - GetPromotedPoint(kEnd, GetAsDOMNode(endNode), endOffset, aOperationType, + + GetPromotedPoint(kStart, startNode, startOffset, inOperationType, + address_of(opStartNode), &opStartOffset); + GetPromotedPoint(kEnd, endNode, endOffset, inOperationType, address_of(opEndNode), &opEndOffset); // Make sure that the new range ends up to be in the editable section. - if (!mHTMLEditor->IsDescendantOfEditorRoot( - nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) || - !mHTMLEditor->IsDescendantOfEditorRoot( - nsEditor::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) { - return; + NS_ENSURE_STATE(mHTMLEditor); + if (!mHTMLEditor->IsDescendantOfEditorRoot(nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) || + !mHTMLEditor || // Check again, since it may have gone away + !mHTMLEditor->IsDescendantOfEditorRoot(nsEditor::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) { + NS_ENSURE_STATE(mHTMLEditor); + return NS_OK; } - DebugOnly res = aRange.SetStart(opStartNode, opStartOffset); - MOZ_ASSERT(NS_SUCCEEDED(res)); - res = aRange.SetEnd(opEndNode, opEndOffset); - MOZ_ASSERT(NS_SUCCEEDED(res)); -} + res = inRange->SetStart(opStartNode, opStartOffset); + NS_ENSURE_SUCCESS(res, res); + res = inRange->SetEnd(opEndNode, opEndOffset); + return res; +} class nsUniqueFunctor : public nsBoolDomIterFunctor { public: - explicit nsUniqueFunctor(nsTArray> &aArray) : mArray(aArray) + explicit nsUniqueFunctor(nsCOMArray &aArray) : mArray(aArray) { } - // used to build list of all nodes iterator covers - virtual bool operator()(nsINode* aNode) const + virtual bool operator()(nsIDOMNode* aNode) // used to build list of all nodes iterator covers { - return !mArray.Contains(aNode); + return mArray.IndexOf(aNode) < 0; } private: - nsTArray>& mArray; + nsCOMArray &mArray; }; -/////////////////////////////////////////////////////////////////////////////// -// GetNodesForOperation: Run through the ranges in the array and construct a -// new array of nodes to be acted on. -// -nsresult -nsHTMLEditRules::GetNodesForOperation(nsTArray>& aArrayOfRanges, - nsTArray>& aOutArrayOfNodes, - EditAction aOperationType, - TouchContent aTouchContent) +/////////////////////////////////////////////////////////////////////////// +// GetNodesForOperation: run through the ranges in the array and construct +// a new array of nodes to be acted on. +// +nsresult +nsHTMLEditRules::GetNodesForOperation(nsTArray>& inArrayOfRanges, + nsCOMArray& outArrayOfNodes, + EditAction inOperationType, + bool aDontTouchContent) { - NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); + int32_t rangeCount = inArrayOfRanges.Length(); + + int32_t i; + nsRefPtr opRange; - int32_t rangeCount = aArrayOfRanges.Length(); - nsresult res; - - // Bust up any inlines that cross our range endpoints, but only if we are - // allowed to touch content. - - if (aTouchContent == TouchContent::yes) { - nsTArray> rangeItemArray; + nsresult res = NS_OK; + + // bust up any inlines that cross our range endpoints, + // but only if we are allowed to touch content. + + if (!aDontTouchContent) + { + nsTArray> rangeItemArray; rangeItemArray.AppendElements(rangeCount); - // First register ranges for special editor gravity - for (int32_t i = 0; i < rangeCount; i++) { + NS_ASSERTION(static_cast(rangeCount) == rangeItemArray.Length(), + "How did that happen?"); + + // first register ranges for special editor gravity + for (i = 0; i < rangeCount; i++) + { + opRange = inArrayOfRanges[0]; rangeItemArray[i] = new nsRangeStore(); - rangeItemArray[i]->StoreRange(aArrayOfRanges[0]); + rangeItemArray[i]->StoreRange(opRange); + NS_ENSURE_STATE(mHTMLEditor); mHTMLEditor->mRangeUpdater.RegisterRangeItem(rangeItemArray[i]); - aArrayOfRanges.RemoveElementAt(0); - } - // Now bust up inlines. - for (auto& item : Reversed(rangeItemArray)) { - res = BustUpInlinesAtRangeEndpoints(*item); - if (NS_FAILED(res)) { - break; - } - } - // Then unregister the ranges - for (auto& item : rangeItemArray) { + inArrayOfRanges.RemoveElementAt(0); + } + // now bust up inlines. Safe to start at rangeCount-1, since we + // asserted we have enough items above. + for (i = rangeCount-1; i >= 0 && NS_SUCCEEDED(res); i--) + { + res = BustUpInlinesAtRangeEndpoints(*rangeItemArray[i]); + } + // then unregister the ranges + for (i = 0; i < rangeCount; i++) + { + nsRangeStore* item = rangeItemArray[i]; + NS_ENSURE_STATE(mHTMLEditor); mHTMLEditor->mRangeUpdater.DropRangeItem(item); - aArrayOfRanges.AppendElement(item->GetRange()); + opRange = item->GetRange(); + inArrayOfRanges.AppendElement(opRange); } NS_ENSURE_SUCCESS(res, res); } - // Gather up a list of all the nodes - for (auto& range : aArrayOfRanges) { - nsDOMSubtreeIterator iter(*range); - if (aOutArrayOfNodes.Length() == 0) { - iter.AppendList(nsTrivialFunctor(), aOutArrayOfNodes); - } else { - // We don't want duplicates in aOutArrayOfNodes, so we use an + // gather up a list of all the nodes + for (i = 0; i < rangeCount; i++) + { + opRange = inArrayOfRanges[i]; + + nsDOMSubtreeIterator iter; + res = iter.Init(opRange); + NS_ENSURE_SUCCESS(res, res); + if (outArrayOfNodes.Count() == 0) { + nsTrivialFunctor functor; + res = iter.AppendList(functor, outArrayOfNodes); + NS_ENSURE_SUCCESS(res, res); + } + else { + // We don't want duplicates in outArrayOfNodes, so we use an // iterator/functor that only return nodes that are not already in - // aOutArrayOfNodes. - nsTArray> nodes; - iter.AppendList(nsUniqueFunctor(aOutArrayOfNodes), nodes); - aOutArrayOfNodes.AppendElements(nodes); + // outArrayOfNodes. + nsCOMArray nodes; + nsUniqueFunctor functor(outArrayOfNodes); + res = iter.AppendList(functor, nodes); + NS_ENSURE_SUCCESS(res, res); + if (!outArrayOfNodes.AppendObjects(nodes)) + return NS_ERROR_OUT_OF_MEMORY; } - } + } - // Certain operations should not act on li's and td's, but rather inside - // them. Alter the list as needed. - if (aOperationType == EditAction::makeBasicBlock) { - for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - OwningNonNull node = aOutArrayOfNodes[i]; - if (nsHTMLEditUtils::IsListItem(node)) { - int32_t j = i; - aOutArrayOfNodes.RemoveElementAt(i); - GetInnerContent(*node, aOutArrayOfNodes, &j); - } - } - // Indent/outdent already do something special for list items, but we still - // need to make sure we don't act on table elements - } else if (aOperationType == EditAction::outdent || - aOperationType == EditAction::indent || - aOperationType == EditAction::setAbsolutePosition) { - for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - OwningNonNull node = aOutArrayOfNodes[i]; - if (nsHTMLEditUtils::IsTableElementButNotTable(node)) { - int32_t j = i; - aOutArrayOfNodes.RemoveElementAt(i); - GetInnerContent(*node, aOutArrayOfNodes, &j); - } - } - } - // Outdent should look inside of divs. - if (aOperationType == EditAction::outdent && - !mHTMLEditor->IsCSSEnabled()) { - for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - OwningNonNull node = aOutArrayOfNodes[i]; - if (node->IsHTMLElement(nsGkAtoms::div)) { - int32_t j = i; - aOutArrayOfNodes.RemoveElementAt(i); - GetInnerContent(*node, aOutArrayOfNodes, &j, Lists::no, Tables::no); - } - } - } - - - // Post-process the list to break up inline containers that contain br's, but - // only for operations that might care, like making lists or paragraphs - if (aOperationType == EditAction::makeBasicBlock || - aOperationType == EditAction::makeList || - aOperationType == EditAction::align || - aOperationType == EditAction::setAbsolutePosition || - aOperationType == EditAction::indent || - aOperationType == EditAction::outdent) { - for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - OwningNonNull node = aOutArrayOfNodes[i]; - if (aTouchContent == TouchContent::yes && - IsInlineNode(GetAsDOMNode(node)) && mHTMLEditor->IsContainer(node) && - !mHTMLEditor->IsTextNode(node)) { - nsTArray> arrayOfInlines; - res = BustUpInlinesAtBRs(*node, arrayOfInlines); + // certain operations should not act on li's and td's, but rather inside + // them. alter the list as needed + if (inOperationType == EditAction::makeBasicBlock) { + int32_t listCount = outArrayOfNodes.Count(); + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr node = outArrayOfNodes[i]; + if (nsHTMLEditUtils::IsListItem(node)) + { + int32_t j=i; + outArrayOfNodes.RemoveObjectAt(i); + res = GetInnerContent(node, outArrayOfNodes, &j); NS_ENSURE_SUCCESS(res, res); - - // Put these nodes in aOutArrayOfNodes, replacing the current node - aOutArrayOfNodes.RemoveElementAt(i); - aOutArrayOfNodes.InsertElementsAt(i, arrayOfInlines); } } } + // indent/outdent already do something special for list items, but + // we still need to make sure we don't act on table elements + else if (inOperationType == EditAction::outdent || + inOperationType == EditAction::indent || + inOperationType == EditAction::setAbsolutePosition) { + int32_t listCount = outArrayOfNodes.Count(); + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr node = outArrayOfNodes[i]; + if (nsHTMLEditUtils::IsTableElementButNotTable(node)) + { + int32_t j=i; + outArrayOfNodes.RemoveObjectAt(i); + res = GetInnerContent(node, outArrayOfNodes, &j); + NS_ENSURE_SUCCESS(res, res); + } + } + } + // outdent should look inside of divs. + if (inOperationType == EditAction::outdent && + (!mHTMLEditor || !mHTMLEditor->IsCSSEnabled())) { + NS_ENSURE_STATE(mHTMLEditor); + int32_t listCount = outArrayOfNodes.Count(); + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr node = outArrayOfNodes[i]; + if (nsHTMLEditUtils::IsDiv(node)) + { + int32_t j=i; + outArrayOfNodes.RemoveObjectAt(i); + res = GetInnerContent(node, outArrayOfNodes, &j, false, false); + NS_ENSURE_SUCCESS(res, res); + } + } + } + + + // post process the list to break up inline containers that contain br's. + // but only for operations that might care, like making lists or para's... + if (inOperationType == EditAction::makeBasicBlock || + inOperationType == EditAction::makeList || + inOperationType == EditAction::align || + inOperationType == EditAction::setAbsolutePosition || + inOperationType == EditAction::indent || + inOperationType == EditAction::outdent) { + int32_t listCount = outArrayOfNodes.Count(); + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr node = outArrayOfNodes[i]; + if (!aDontTouchContent && IsInlineNode(node) && + (!mHTMLEditor || mHTMLEditor->IsContainer(node)) && + (!mHTMLEditor || !mHTMLEditor->IsTextNode(node))) + { + NS_ENSURE_STATE(mHTMLEditor); + nsCOMArray arrayOfInlines; + res = BustUpInlinesAtBRs(node, arrayOfInlines); + NS_ENSURE_SUCCESS(res, res); + // put these nodes in outArrayOfNodes, replacing the current node + outArrayOfNodes.RemoveObjectAt(i); + outArrayOfNodes.InsertObjectsAt(arrayOfInlines, i); + } + } + } + return res; +} + + + +/////////////////////////////////////////////////////////////////////////// +// GetChildNodesForOperation: +// +nsresult +nsHTMLEditRules::GetChildNodesForOperation(nsIDOMNode *inNode, + nsCOMArray& outArrayOfNodes) +{ + nsCOMPtr node = do_QueryInterface(inNode); + NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); + + for (nsIContent* child = node->GetFirstChild(); + child; + child = child->GetNextSibling()) { + nsIDOMNode* childNode = child->AsDOMNode(); + if (!outArrayOfNodes.AppendObject(childNode)) { + return NS_ERROR_FAILURE; + } + } return NS_OK; } -void -nsHTMLEditRules::GetChildNodesForOperation(nsINode& aNode, - nsTArray>& outArrayOfNodes) -{ - for (nsCOMPtr child = aNode.GetFirstChild(); - child; child = child->GetNextSibling()) { - outArrayOfNodes.AppendElement(*child); - } -} - -nsresult -nsHTMLEditRules::GetListActionNodes(nsTArray>& aOutArrayOfNodes, - EntireList aEntireList, - TouchContent aTouchContent) +/////////////////////////////////////////////////////////////////////////// +// GetListActionNodes: +// +nsresult +nsHTMLEditRules::GetListActionNodes(nsCOMArray &outArrayOfNodes, + bool aEntireList, + bool aDontTouchContent) { + nsresult res = NS_OK; + NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); - nsRefPtr selection = mHTMLEditor->GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE); - - // Added this in so that ui code can ask to change an entire list, even if - // selection is only in part of it. used by list item dialog. - if (aEntireList == EntireList::yes) { + // added this in so that ui code can ask to change an entire list, even if selection + // is only in part of it. used by list item dialog. + if (aEntireList) + { uint32_t rangeCount = selection->RangeCount(); for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) { nsRefPtr range = selection->GetRangeAt(rangeIdx); - for (nsCOMPtr parent = range->GetCommonAncestor(); - parent; parent = parent->GetParentNode()) { - if (nsHTMLEditUtils::IsList(parent)) { - aOutArrayOfNodes.AppendElement(*parent); - break; + nsCOMPtr commonParent, parent, tmp; + range->GetCommonAncestorContainer(getter_AddRefs(commonParent)); + if (commonParent) + { + parent = commonParent; + while (parent) + { + if (nsHTMLEditUtils::IsList(parent)) + { + outArrayOfNodes.AppendObject(parent); + break; + } + parent->GetParentNode(getter_AddRefs(tmp)); + parent = tmp; } } } - // If we didn't find any nodes this way, then try the normal way. Perhaps - // the selection spans multiple lists but with no common list parent. - if (aOutArrayOfNodes.Length()) { - return NS_OK; - } + // if we didn't find any nodes this way, then try the normal way. perhaps the + // selection spans multiple lists but with no common list parent. + if (outArrayOfNodes.Count()) return NS_OK; } { // We don't like other people messing with our selection! + NS_ENSURE_STATE(mHTMLEditor); nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor); // contruct a list of nodes to act on. - nsresult res = GetNodesFromSelection(*selection, EditAction::makeList, - aOutArrayOfNodes, aTouchContent); + res = GetNodesFromSelection(selection, EditAction::makeList, + outArrayOfNodes, aDontTouchContent); NS_ENSURE_SUCCESS(res, res); } - - // Pre-process our list of nodes - for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) { - OwningNonNull testNode = aOutArrayOfNodes[i]; + + // pre process our list of nodes... + int32_t listCount = outArrayOfNodes.Count(); + int32_t i; + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr testNode = outArrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. - if (!mHTMLEditor->IsEditable(testNode)) { - aOutArrayOfNodes.RemoveElementAt(i); - continue; + NS_ENSURE_STATE(mHTMLEditor); + if (!mHTMLEditor->IsEditable(testNode)) + { + outArrayOfNodes.RemoveObjectAt(i); } - - // Scan for table elements and divs. If we find table elements other than - // table, replace it with a list of any editable non-table content. - if (nsHTMLEditUtils::IsTableElementButNotTable(testNode)) { - int32_t j = i; - aOutArrayOfNodes.RemoveElementAt(i); - GetInnerContent(*testNode, aOutArrayOfNodes, &j, Lists::no); + + // scan for table elements and divs. If we find table elements other than table, + // replace it with a list of any editable non-table content. + if (nsHTMLEditUtils::IsTableElementButNotTable(testNode)) + { + int32_t j=i; + outArrayOfNodes.RemoveObjectAt(i); + res = GetInnerContent(testNode, outArrayOfNodes, &j, false); + NS_ENSURE_SUCCESS(res, res); } } - // If there is only one node in the array, and it is a list, div, or - // blockquote, then look inside of it until we find inner list or content. - LookInsideDivBQandList(aOutArrayOfNodes); - - return NS_OK; + // if there is only one node in the array, and it is a list, div, or blockquote, + // then look inside of it until we find inner list or content. + res = LookInsideDivBQandList(outArrayOfNodes); + return res; } -void -nsHTMLEditRules::LookInsideDivBQandList(nsTArray>& aNodeArray) +/////////////////////////////////////////////////////////////////////////// +// LookInsideDivBQandList: +// +nsresult +nsHTMLEditRules::LookInsideDivBQandList(nsCOMArray& aNodeArray) { - NS_ENSURE_TRUE(mHTMLEditor, ); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); - - // If there is only one node in the array, and it is a list, div, or - // blockquote, then look inside of it until we find inner list or content. - int32_t listCount = aNodeArray.Length(); + // if there is only one node in the array, and it is a list, div, or blockquote, + // then look inside of it until we find inner list or content. + int32_t listCount = aNodeArray.Count(); if (listCount != 1) { - return; + return NS_OK; } - OwningNonNull curNode = aNodeArray[0]; + nsCOMPtr curNode = do_QueryInterface(aNodeArray[0]); + NS_ENSURE_STATE(curNode); - while (curNode->IsHTMLElement(nsGkAtoms::div) || - nsHTMLEditUtils::IsList(curNode) || - curNode->IsHTMLElement(nsGkAtoms::blockquote)) { - // Dive as long as there's only one child, and it's a list, div, blockquote + while (curNode->IsElement() && + (curNode->IsHTMLElement(nsGkAtoms::div) || + nsHTMLEditUtils::IsList(curNode) || + curNode->IsHTMLElement(nsGkAtoms::blockquote))) { + // dive as long as there is only one child, and it is a list, div, blockquote + NS_ENSURE_STATE(mHTMLEditor); uint32_t numChildren = mHTMLEditor->CountEditableChildren(curNode); if (numChildren != 1) { break; } - // Keep diving! XXX One would expect to dive into the one editable node. - nsCOMPtr child = curNode->GetFirstChild(); - if (!child->IsHTMLElement(nsGkAtoms::div) && - !nsHTMLEditUtils::IsList(child) && - !child->IsHTMLElement(nsGkAtoms::blockquote)) { + // keep diving + // XXX One would expect to dive into the one editable node. + nsIContent* tmp = curNode->GetFirstChild(); + if (!tmp->IsElement()) { break; } - // check editability XXX floppy moose - curNode = child; + dom::Element* element = tmp->AsElement(); + if (!element->IsHTMLElement(nsGkAtoms::div) && + !nsHTMLEditUtils::IsList(element) && + !element->IsHTMLElement(nsGkAtoms::blockquote)) { + break; + } + + // check editablility XXX floppy moose + curNode = tmp; } - // We've found innermost list/blockquote/div: replace the one node in the - // array with these nodes - aNodeArray.RemoveElementAt(0); + // we've found innermost list/blockquote/div: + // replace the one node in the array with these nodes + aNodeArray.RemoveObjectAt(0); if (curNode->IsAnyOfHTMLElements(nsGkAtoms::div, nsGkAtoms::blockquote)) { int32_t j = 0; - GetInnerContent(*curNode, aNodeArray, &j, Lists::no, Tables::no); - return; + return GetInnerContent(curNode->AsDOMNode(), aNodeArray, &j, false, false); } - aNodeArray.AppendElement(*curNode); + aNodeArray.AppendObject(curNode->AsDOMNode()); + return NS_OK; } @@ -6013,42 +6219,49 @@ nsHTMLEditRules::GetDefinitionListItemTypes(dom::Element* aElement, bool* aDT, b } } -nsresult -nsHTMLEditRules::GetParagraphFormatNodes(nsTArray>& outArrayOfNodes, - TouchContent aTouchContent) -{ +/////////////////////////////////////////////////////////////////////////// +// GetParagraphFormatNodes: +// +nsresult +nsHTMLEditRules::GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, + bool aDontTouchContent) +{ NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); - nsRefPtr selection = mHTMLEditor->GetSelection(); NS_ENSURE_STATE(selection); - // Contruct a list of nodes to act on. - nsresult res = GetNodesFromSelection(*selection, EditAction::makeBasicBlock, - outArrayOfNodes, aTouchContent); + // contruct a list of nodes to act on. + nsresult res = GetNodesFromSelection(selection, EditAction::makeBasicBlock, + outArrayOfNodes, aDontTouchContent); NS_ENSURE_SUCCESS(res, res); - // Pre-process our list of nodes - for (int32_t i = outArrayOfNodes.Length() - 1; i >= 0; i--) { - OwningNonNull testNode = outArrayOfNodes[i]; + // pre process our list of nodes... + int32_t listCount = outArrayOfNodes.Count(); + int32_t i; + for (i=listCount-1; i>=0; i--) + { + nsCOMPtr testNode = outArrayOfNodes[i]; // Remove all non-editable nodes. Leave them be. - if (!mHTMLEditor->IsEditable(testNode)) { - outArrayOfNodes.RemoveElementAt(i); + NS_ENSURE_STATE(mHTMLEditor); + if (!mHTMLEditor->IsEditable(testNode)) + { + outArrayOfNodes.RemoveObjectAt(i); } - - // Scan for table elements. If we find table elements other than table, - // replace it with a list of any editable non-table content. Ditto for - // list elements. + + // scan for table elements. If we find table elements other than table, + // replace it with a list of any editable non-table content. Ditto for list elements. if (nsHTMLEditUtils::IsTableElement(testNode) || - nsHTMLEditUtils::IsList(testNode) || - nsHTMLEditUtils::IsListItem(testNode)) { - int32_t j = i; - outArrayOfNodes.RemoveElementAt(i); - GetInnerContent(testNode, outArrayOfNodes, &j); + nsHTMLEditUtils::IsList(testNode) || + nsHTMLEditUtils::IsListItem(testNode) ) + { + int32_t j=i; + outArrayOfNodes.RemoveObjectAt(i); + res = GetInnerContent(testNode, outArrayOfNodes, &j); + NS_ENSURE_SUCCESS(res, res); } } - return NS_OK; + return res; } @@ -6102,67 +6315,81 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item) -nsresult -nsHTMLEditRules::BustUpInlinesAtBRs(nsINode& aNode, - nsTArray>& aOutArrayOfNodes) +/////////////////////////////////////////////////////////////////////////// +// BustUpInlinesAtBRs: +// +nsresult +nsHTMLEditRules::BustUpInlinesAtBRs(nsIDOMNode *inNode, + nsCOMArray& outArrayOfNodes) { - NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); + nsCOMPtr node = do_QueryInterface(inNode); + NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER); - // First build up a list of all the break nodes inside the inline container. - nsTArray> arrayOfBreaks; + // first step is to build up a list of all the break nodes inside + // the inline container. + nsCOMArray arrayOfBreaks; nsBRNodeFunctor functor; - nsDOMIterator iter(aNode); - iter.AppendList(functor, arrayOfBreaks); - - // If there aren't any breaks, just put inNode itself in the array - if (!arrayOfBreaks.Length()) { - aOutArrayOfNodes.AppendElement(aNode); - return NS_OK; + nsDOMIterator iter; + nsresult res = iter.Init(inNode); + NS_ENSURE_SUCCESS(res, res); + res = iter.AppendList(functor, arrayOfBreaks); + NS_ENSURE_SUCCESS(res, res); + + // if there aren't any breaks, just put inNode itself in the array + int32_t listCount = arrayOfBreaks.Count(); + if (!listCount) + { + if (!outArrayOfNodes.AppendObject(inNode)) + return NS_ERROR_FAILURE; } - - // Else we need to bust up inNode along all the breaks - nsCOMPtr inlineParentNode = aNode.GetParentNode(); - nsCOMPtr splitDeepNode = GetAsDOMNode(&aNode); - nsCOMPtr leftDOMNode, rightDOMNode; - - for (uint32_t i = 0; i < arrayOfBreaks.Length(); i++) { - OwningNonNull breakNode = *arrayOfBreaks[i]->AsElement(); - NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER); - nsCOMPtr splitParentNode = breakNode->GetParentNode(); - int32_t splitOffset = splitParentNode ? - splitParentNode->IndexOf(breakNode) : -1; - - int32_t resultOffset; - nsresult res = mHTMLEditor->SplitNodeDeep(splitDeepNode, - GetAsDOMNode(splitParentNode), splitOffset, &resultOffset, false, - address_of(leftDOMNode), address_of(rightDOMNode)); - NS_ENSURE_SUCCESS(res, res); - - // Put left node in node list - if (leftDOMNode) { - // Might not be a left node. A break might have been at the very - // beginning of inline container, in which case SplitNodeDeep would not - // actually split anything - nsCOMPtr leftNode = do_QueryInterface(leftDOMNode); - NS_ENSURE_STATE(leftNode); - aOutArrayOfNodes.AppendElement(*leftNode); + else + { + // else we need to bust up inNode along all the breaks + nsCOMPtr breakNode; + nsCOMPtr inlineParentNode = node->GetParentNode(); + nsCOMPtr leftNode; + nsCOMPtr rightNode; + nsCOMPtr splitDeepNode = inNode; + nsCOMPtr splitParentNode; + int32_t splitOffset, resultOffset, i; + + for (i=0; i< listCount; i++) + { + breakNode = do_QueryInterface(arrayOfBreaks[i]); + NS_ENSURE_TRUE(breakNode, NS_ERROR_NULL_POINTER); + NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER); + splitParentNode = GetAsDOMNode(nsEditor::GetNodeLocation(breakNode, + &splitOffset)); + NS_ENSURE_STATE(mHTMLEditor); + res = mHTMLEditor->SplitNodeDeep(splitDeepNode, splitParentNode, splitOffset, + &resultOffset, false, address_of(leftNode), address_of(rightNode)); + NS_ENSURE_SUCCESS(res, res); + // put left node in node list + if (leftNode) + { + // might not be a left node. a break might have been at the very + // beginning of inline container, in which case splitnodedeep + // would not actually split anything + if (!outArrayOfNodes.AppendObject(leftNode)) + return NS_ERROR_FAILURE; + } + // move break outside of container and also put in node list + NS_ENSURE_STATE(mHTMLEditor); + res = mHTMLEditor->MoveNode(breakNode, inlineParentNode, resultOffset); + NS_ENSURE_SUCCESS(res, res); + if (!outArrayOfNodes.AppendObject(GetAsDOMNode(breakNode))) + return NS_ERROR_FAILURE; + // now rightNode becomes the new node to split + splitDeepNode = rightNode; + } + // now tack on remaining rightNode, if any, to the list + if (rightNode) + { + if (!outArrayOfNodes.AppendObject(rightNode)) + return NS_ERROR_FAILURE; } - // Move break outside of container and also put in node list - res = mHTMLEditor->MoveNode(breakNode, inlineParentNode, resultOffset); - NS_ENSURE_SUCCESS(res, res); - aOutArrayOfNodes.AppendElement(*breakNode); - - // Now rightNode becomes the new node to split - splitDeepNode = rightDOMNode; } - // Now tack on remaining rightNode, if any, to the list - if (rightDOMNode) { - nsCOMPtr rightNode = do_QueryInterface(rightDOMNode); - NS_ENSURE_STATE(rightNode); - aOutArrayOfNodes.AppendElement(*rightNode); - } - return NS_OK; + return res; } @@ -6182,83 +6409,93 @@ nsHTMLEditRules::GetHighestInlineParent(nsIDOMNode* aNode) } -/////////////////////////////////////////////////////////////////////////////// -// GetNodesFromPoint: Given a particular operation, construct a list of nodes -// from a point that will be operated on. -// -nsresult -nsHTMLEditRules::GetNodesFromPoint(::DOMPoint aPoint, - EditAction aOperation, - nsTArray>& outArrayOfNodes, - TouchContent aTouchContent) +/////////////////////////////////////////////////////////////////////////// +// GetNodesFromPoint: given a particular operation, construct a list +// of nodes from a point that will be operated on. +// +nsresult +nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point, + EditAction operation, + nsCOMArray &arrayOfNodes, + bool dontTouchContent) { - NS_ENSURE_STATE(aPoint.node); - nsRefPtr range = new nsRange(aPoint.node); - nsresult res = range->SetStart(aPoint.node, aPoint.offset); - MOZ_ASSERT(NS_SUCCEEDED(res)); - - // Expand the range to include adjacent inlines - PromoteRange(*range, aOperation); - - // Make array of ranges + NS_ENSURE_STATE(point.node); + nsRefPtr range = new nsRange(point.node); + nsresult res = range->SetStart(point.node, point.offset); + NS_ENSURE_SUCCESS(res, res); + + // expand the range to include adjacent inlines + res = PromoteRange(range, operation); + NS_ENSURE_SUCCESS(res, res); + + // make array of ranges nsTArray> arrayOfRanges; - - // Stuff new opRange into array + + // stuff new opRange into array arrayOfRanges.AppendElement(range); - - // Use these ranges to contruct a list of nodes to act on - res = GetNodesForOperation(arrayOfRanges, outArrayOfNodes, aOperation, - aTouchContent); - NS_ENSURE_SUCCESS(res, res); - - return NS_OK; + + // use these ranges to contruct a list of nodes to act on. + res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, operation, dontTouchContent); + return res; } -/////////////////////////////////////////////////////////////////////////////// -// GetNodesFromSelection: Given a particular operation, construct a list of -// nodes from the selection that will be operated on. -// -nsresult -nsHTMLEditRules::GetNodesFromSelection(Selection& aSelection, - EditAction aOperation, - nsTArray>& outArrayOfNodes, - TouchContent aTouchContent) +/////////////////////////////////////////////////////////////////////////// +// GetNodesFromSelection: given a particular operation, construct a list +// of nodes from the selection that will be operated on. +// +nsresult +nsHTMLEditRules::GetNodesFromSelection(Selection* selection, + EditAction operation, + nsCOMArray& arrayOfNodes, + bool dontTouchContent) { - // Promote selection ranges + NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); + nsresult res; + + // promote selection ranges nsTArray> arrayOfRanges; - GetPromotedRanges(aSelection, arrayOfRanges, aOperation); - - // Use these ranges to contruct a list of nodes to act on. - nsresult res = GetNodesForOperation(arrayOfRanges, outArrayOfNodes, - aOperation, aTouchContent); + res = GetPromotedRanges(selection, arrayOfRanges, operation); NS_ENSURE_SUCCESS(res, res); - - return NS_OK; + + // use these ranges to contruct a list of nodes to act on. + res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, operation, dontTouchContent); + return res; } -/////////////////////////////////////////////////////////////////////////////// -// MakeTransitionList: Detect all the transitions in the array, where a -// transition means that adjacent nodes in the array don't -// have the same parent. -void -nsHTMLEditRules::MakeTransitionList(nsTArray>& aNodeArray, - nsTArray& aTransitionArray) +/////////////////////////////////////////////////////////////////////////// +// MakeTransitionList: detect all the transitions in the array, where a +// transition means that adjacent nodes in the array +// don't have the same parent. +// +nsresult +nsHTMLEditRules::MakeTransitionList(nsCOMArray& inArrayOfNodes, + nsTArray &inTransitionArray) { - nsCOMPtr prevParent; - - aTransitionArray.EnsureLengthAtLeast(aNodeArray.Length()); - for (uint32_t i = 0; i < aNodeArray.Length(); i++) { - if (aNodeArray[i]->GetParentNode() != prevParent) { - // Different parents: transition point - aTransitionArray[i] = true; - } else { - // Same parents: these nodes grew up together - aTransitionArray[i] = false; + uint32_t listCount = inArrayOfNodes.Count(); + inTransitionArray.EnsureLengthAtLeast(listCount); + uint32_t i; + nsCOMPtr prevElementParent; + nsCOMPtr curElementParent; + + for (i=0; iGetParentNode(getter_AddRefs(curElementParent)); + if (curElementParent != prevElementParent) + { + // different parents, or separated by
    : transition point + inTransitionArray[i] = true; } - prevParent = aNodeArray[i]->GetParentNode(); + else + { + // same parents: these nodes grew up together + inTransitionArray[i] = false; + } + prevElementParent = curElementParent; } + return NS_OK; } @@ -6752,52 +6989,71 @@ nsHTMLEditRules::ReturnInListItem(Selection* aSelection, } -/////////////////////////////////////////////////////////////////////////////// -// MakeBlockquote: Put the list of nodes into one or more blockquotes. -// -nsresult -nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) +/////////////////////////////////////////////////////////////////////////// +// MakeBlockquote: put the list of nodes into one or more blockquotes. +// +nsresult +nsHTMLEditRules::MakeBlockquote(nsCOMArray& arrayOfNodes) { - // The idea here is to put the nodes into a minimal number of blockquotes. - // When the user blockquotes something, they expect one blockquote. That may - // not be possible (for instance, if they have two table cells selected, you - // need two blockquotes inside the cells). - nsresult res; + // the idea here is to put the nodes into a minimal number of + // blockquotes. When the user blockquotes something, they expect + // one blockquote. That may not be possible (for instance, if they + // have two table cells selected, you need two blockquotes inside the cells). + + nsresult res = NS_OK; + + nsCOMPtr curNode, newBlock; + nsCOMPtr curParent; nsCOMPtr curBlock; - nsCOMPtr prevParent; + int32_t offset; + int32_t listCount = arrayOfNodes.Count(); + + nsCOMPtr prevParent; + + int32_t i; + for (i=0; i curContent = do_QueryInterface(curNode); + NS_ENSURE_STATE(curContent); + curParent = curContent->GetParentNode(); + offset = curParent ? curParent->IndexOf(curContent) : -1; - for (auto& curNode : aNodeArray) { - // Get the node to act on, and its location - NS_ENSURE_STATE(curNode->IsContent()); - - // If the node is a table element or list item, dive inside - if (nsHTMLEditUtils::IsTableElementButNotTable(curNode) || - nsHTMLEditUtils::IsListItem(curNode)) { - // Forget any previous block - curBlock = nullptr; - // Recursion time - nsTArray> childArray; - GetChildNodesForOperation(*curNode, childArray); + // if the node is a table element or list item, dive inside + if (nsHTMLEditUtils::IsTableElementButNotTable(curNode) || + nsHTMLEditUtils::IsListItem(curNode)) + { + curBlock = 0; // forget any previous block + // recursion time + nsCOMArray childArray; + res = GetChildNodesForOperation(curNode, childArray); + NS_ENSURE_SUCCESS(res, res); res = MakeBlockquote(childArray); NS_ENSURE_SUCCESS(res, res); } - - // If the node has different parent than previous node, further nodes in a - // new parent - if (prevParent) { - if (prevParent != curNode->GetParentNode()) { - // Forget any previous blockquote node we were using - curBlock = nullptr; - prevParent = curNode->GetParentNode(); + + // if the node has different parent than previous node, + // further nodes in a new parent + if (prevParent) + { + nsCOMPtr temp; + curNode->GetParentNode(getter_AddRefs(temp)); + if (temp != prevParent) + { + curBlock = 0; // forget any previous blockquote node we were using + prevParent = temp; } - } else { - prevParent = curNode->GetParentNode(); } + else - // If no curBlock, make one - if (!curBlock) { - nsCOMPtr curParent = curNode->GetParentNode(); - int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; + { + curNode->GetParentNode(getter_AddRefs(prevParent)); + } + + // if no curBlock, make one + if (!curBlock) + { res = SplitAsNeeded(*nsGkAtoms::blockquote, curParent, offset); NS_ENSURE_SUCCESS(res, res); NS_ENSURE_STATE(mHTMLEditor); @@ -6808,231 +7064,292 @@ nsHTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) mNewBlock = curBlock->AsDOMNode(); // note: doesn't matter if we set mNewBlock multiple times. } - + NS_ENSURE_STATE(mHTMLEditor); - res = mHTMLEditor->MoveNode(curNode->AsContent(), curBlock, -1); + res = mHTMLEditor->MoveNode(curContent, curBlock, -1); NS_ENSURE_SUCCESS(res, res); } - return NS_OK; + return res; } -/////////////////////////////////////////////////////////////////////////////// -// RemoveBlockStyle: Make the nodes have no special block type. -nsresult -nsHTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray) + +/////////////////////////////////////////////////////////////////////////// +// RemoveBlockStyle: make the nodes have no special block type. +// +nsresult +nsHTMLEditRules::RemoveBlockStyle(nsCOMArray& arrayOfNodes) { - NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); + // intent of this routine is to be used for converting to/from + // headers, paragraphs, pre, and address. Those blocks + // that pretty much just contain inline things... + + nsresult res = NS_OK; + + nsCOMPtr curBlock, firstNode, lastNode; + int32_t listCount = arrayOfNodes.Count(); + for (int32_t i = 0; i < listCount; ++i) { + // get the node to act on, and its location + nsCOMPtr curNode = arrayOfNodes[i]; - // Intent of this routine is to be used for converting to/from headers, - // paragraphs, pre, and address. Those blocks that pretty much just contain - // inline things... - nsresult res; + nsCOMPtr curElement = do_QueryInterface(curNode); - nsCOMPtr curBlock; - nsCOMPtr firstNode, lastNode; - for (auto& curNode : aNodeArray) { - // If curNode is a address, p, header, address, or pre, remove it - if (nsHTMLEditUtils::IsFormatNode(curNode)) { - // Process any partial progress saved - if (curBlock) { - res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); + // if curNode is a address, p, header, address, or pre, remove it + if (curElement && nsHTMLEditUtils::IsFormatNode(curElement)) { + // process any partial progress saved + if (curBlock) + { + res = RemovePartOfBlock(curBlock, firstNode, lastNode); NS_ENSURE_SUCCESS(res, res); - firstNode = lastNode = curBlock = nullptr; + curBlock = 0; firstNode = 0; lastNode = 0; } - // Remove current block - res = mHTMLEditor->RemoveBlockContainer(curNode->AsDOMNode()); + // remove curent block + NS_ENSURE_STATE(mHTMLEditor); + res = mHTMLEditor->RemoveBlockContainer(curNode); NS_ENSURE_SUCCESS(res, res); - } else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table, - nsGkAtoms::tr, - nsGkAtoms::tbody, - nsGkAtoms::td, - nsGkAtoms::li, - nsGkAtoms::blockquote, - nsGkAtoms::div) || - nsHTMLEditUtils::IsList(curNode)) { - // Process any partial progress saved - if (curBlock) { - res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); + } else if (curElement && + (curElement->IsAnyOfHTMLElements(nsGkAtoms::table, + nsGkAtoms::tr, + nsGkAtoms::tbody, + nsGkAtoms::td, + nsGkAtoms::li, + nsGkAtoms::blockquote, + nsGkAtoms::div) || + nsHTMLEditUtils::IsList(curElement))) { + // process any partial progress saved + if (curBlock) + { + res = RemovePartOfBlock(curBlock, firstNode, lastNode); NS_ENSURE_SUCCESS(res, res); - firstNode = lastNode = curBlock = nullptr; + curBlock = 0; firstNode = 0; lastNode = 0; } - // Recursion time - nsTArray> childArray; - GetChildNodesForOperation(*curNode, childArray); + // recursion time + nsCOMArray childArray; + res = GetChildNodesForOperation(curNode, childArray); + NS_ENSURE_SUCCESS(res, res); res = RemoveBlockStyle(childArray); NS_ENSURE_SUCCESS(res, res); - } else if (IsInlineNode(GetAsDOMNode(curNode))) { - if (curBlock) { - // If so, is this node a descendant? - if (nsEditorUtils::IsDescendantOf(curNode, curBlock)) { - // Then we don't need to do anything different for this node - lastNode = curNode->AsContent(); - continue; - } else { - // Otherwise, we have progressed beyond end of curBlock, so let's - // handle it now. We need to remove the portion of curBlock that - // contains [firstNode - lastNode]. - res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); + } + else if (IsInlineNode(curNode)) + { + if (curBlock) + { + // if so, is this node a descendant? + if (nsEditorUtils::IsDescendantOf(curNode, curBlock)) + { + lastNode = curNode; + continue; // then we don't need to do anything different for this node + } + else + { + // otherwise, we have progressed beyond end of curBlock, + // so lets handle it now. We need to remove the portion of + // curBlock that contains [firstNode - lastNode]. + res = RemovePartOfBlock(curBlock, firstNode, lastNode); NS_ENSURE_SUCCESS(res, res); - firstNode = lastNode = curBlock = nullptr; - // Fall out and handle curNode + curBlock = 0; firstNode = 0; lastNode = 0; + // fall out and handle curNode } } + NS_ENSURE_STATE(mHTMLEditor); curBlock = mHTMLEditor->GetBlockNodeParent(curNode); if (curBlock && nsHTMLEditUtils::IsFormatNode(curBlock)) { - firstNode = lastNode = curNode->AsContent(); - } else { - // Not a block kind that we care about. - curBlock = nullptr; + firstNode = curNode; + lastNode = curNode; + } + else + curBlock = 0; // not a block kind that we care about. + } + else + { // some node that is already sans block style. skip over it and + // process any partial progress saved + if (curBlock) + { + res = RemovePartOfBlock(curBlock, firstNode, lastNode); + NS_ENSURE_SUCCESS(res, res); + curBlock = 0; firstNode = 0; lastNode = 0; } - } else if (curBlock) { - // Some node that is already sans block style. Skip over it and process - // any partial progress saved. - res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); - NS_ENSURE_SUCCESS(res, res); - firstNode = lastNode = curBlock = nullptr; } } - // Process any partial progress saved - if (curBlock) { - res = RemovePartOfBlock(*curBlock, *firstNode, *lastNode); + // process any partial progress saved + if (curBlock) + { + res = RemovePartOfBlock(curBlock, firstNode, lastNode); NS_ENSURE_SUCCESS(res, res); - firstNode = lastNode = curBlock = nullptr; + curBlock = 0; firstNode = 0; lastNode = 0; } - return NS_OK; + return res; } -/////////////////////////////////////////////////////////////////////////////// -// ApplyBlockStyle: Do whatever it takes to make the list of nodes into one or -// more blocks of type aBlockTag. -nsresult -nsHTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, - nsIAtom& aBlockTag) +/////////////////////////////////////////////////////////////////////////// +// ApplyBlockStyle: do whatever it takes to make the list of nodes into +// one or more blocks of type blockTag. +// +nsresult +nsHTMLEditRules::ApplyBlockStyle(nsCOMArray& arrayOfNodes, const nsAString *aBlockTag) { - // Intent of this routine is to be used for converting to/from headers, - // paragraphs, pre, and address. Those blocks that pretty much just contain - // inline things... - NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr kungFuDeathGrip(mHTMLEditor); - - nsresult res; + // intent of this routine is to be used for converting to/from + // headers, paragraphs, pre, and address. Those blocks + // that pretty much just contain inline things... + + NS_ENSURE_TRUE(aBlockTag, NS_ERROR_NULL_POINTER); + nsCOMPtr blockTag = do_GetAtom(*aBlockTag); + nsresult res = NS_OK; + + nsCOMPtr curParent; + nsCOMPtr newBlock; + int32_t offset; + int32_t listCount = arrayOfNodes.Count(); + nsString tString(*aBlockTag);////MJUDGE SCC NEED HELP // Remove all non-editable nodes. Leave them be. - for (int32_t i = aNodeArray.Length() - 1; i >= 0; i--) { - if (!mHTMLEditor->IsEditable(aNodeArray[i])) { - aNodeArray.RemoveElementAt(i); + int32_t j; + for (j=listCount-1; j>=0; j--) + { + NS_ENSURE_STATE(mHTMLEditor); + if (!mHTMLEditor->IsEditable(arrayOfNodes[j])) + { + arrayOfNodes.RemoveObjectAt(j); } } - - nsCOMPtr newBlock; - + + // reset list count + listCount = arrayOfNodes.Count(); + nsCOMPtr curBlock; - for (auto& curNode : aNodeArray) { - nsCOMPtr curParent = curNode->GetParentNode(); - int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; - - // Is it already the right kind of block? - if (curNode->IsHTMLElement(&aBlockTag)) { - // Forget any previous block used for previous inline nodes - curBlock = nullptr; - // Do nothing to this block - continue; + int32_t i; + for (i=0; i curNode = do_QueryInterface(arrayOfNodes[i]); + NS_ENSURE_STATE(curNode); + curParent = curNode->GetParentNode(); + offset = curParent ? curParent->IndexOf(curNode) : -1; + nsAutoString curNodeTag; + curNode->NodeInfo()->NameAtom()->ToString(curNodeTag); + ToLowerCase(curNodeTag); + + // is it already the right kind of block? + if (curNodeTag == *aBlockTag) + { + curBlock = 0; // forget any previous block used for previous inline nodes + continue; // do nothing to this block } - - // If curNode is a address, p, header, address, or pre, replace it with a - // new block of correct type. - // XXX: pre can't hold everything the others can - if (nsHTMLEditUtils::IsMozDiv(curNode) || - nsHTMLEditUtils::IsFormatNode(curNode)) { - // Forget any previous block used for previous inline nodes - curBlock = nullptr; - newBlock = mHTMLEditor->ReplaceContainer(curNode->AsElement(), - &aBlockTag, nullptr, nullptr, - nsEditor::eCloneAttributes); + + // if curNode is a address, p, header, address, or pre, replace + // it with a new block of correct type. + // xxx floppy moose: pre can't hold everything the others can + if (nsHTMLEditUtils::IsMozDiv(curNode) || + nsHTMLEditUtils::IsFormatNode(curNode)) + { + curBlock = 0; // forget any previous block used for previous inline nodes + NS_ENSURE_STATE(mHTMLEditor); + nsCOMPtr element = curNode->AsElement(); + newBlock = dont_AddRef(GetAsDOMNode( + mHTMLEditor->ReplaceContainer(element, blockTag, nullptr, nullptr, + nsEditor::eCloneAttributes).take())); NS_ENSURE_STATE(newBlock); - } else if (nsHTMLEditUtils::IsTable(curNode) || - nsHTMLEditUtils::IsList(curNode) || - curNode->IsAnyOfHTMLElements(nsGkAtoms::tbody, - nsGkAtoms::tr, - nsGkAtoms::td, - nsGkAtoms::li, - nsGkAtoms::blockquote, - nsGkAtoms::div)) { - // Forget any previous block used for previous inline nodes - curBlock = nullptr; - // Recursion time - nsTArray> childArray; - GetChildNodesForOperation(*curNode, childArray); - if (childArray.Length()) { + } + else if (nsHTMLEditUtils::IsTable(curNode) || + (curNodeTag.EqualsLiteral("tbody")) || + (curNodeTag.EqualsLiteral("tr")) || + (curNodeTag.EqualsLiteral("td")) || + nsHTMLEditUtils::IsList(curNode) || + (curNodeTag.EqualsLiteral("li")) || + curNode->IsAnyOfHTMLElements(nsGkAtoms::blockquote, + nsGkAtoms::div)) { + curBlock = 0; // forget any previous block used for previous inline nodes + // recursion time + nsCOMArray childArray; + res = GetChildNodesForOperation(GetAsDOMNode(curNode), childArray); + NS_ENSURE_SUCCESS(res, res); + int32_t childCount = childArray.Count(); + if (childCount) + { res = ApplyBlockStyle(childArray, aBlockTag); NS_ENSURE_SUCCESS(res, res); - } else { - // Make sure we can put a block here - res = SplitAsNeeded(aBlockTag, curParent, offset); + } + else + { + // make sure we can put a block here + res = SplitAsNeeded(*blockTag, curParent, offset); NS_ENSURE_SUCCESS(res, res); + NS_ENSURE_STATE(mHTMLEditor); nsCOMPtr theBlock = - mHTMLEditor->CreateNode(&aBlockTag, curParent, offset); + mHTMLEditor->CreateNode(blockTag, curParent, offset); NS_ENSURE_STATE(theBlock); - // Remember our new block for postprocessing + // remember our new block for postprocessing mNewBlock = theBlock->AsDOMNode(); } - } else if (curNode->IsHTMLElement(nsGkAtoms::br)) { - // If the node is a break, we honor it by putting further nodes in a new - // parent - if (curBlock) { - // Forget any previous block used for previous inline nodes - curBlock = nullptr; + } + + // if the node is a break, we honor it by putting further nodes in a new parent + else if (curNodeTag.EqualsLiteral("br")) + { + if (curBlock) + { + curBlock = 0; // forget any previous block used for previous inline nodes + NS_ENSURE_STATE(mHTMLEditor); res = mHTMLEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(res, res); - } else { - // The break is the first (or even only) node we encountered. Create a + } + else + { + // the break is the first (or even only) node we encountered. Create a // block for it. - res = SplitAsNeeded(aBlockTag, curParent, offset); + res = SplitAsNeeded(*blockTag, curParent, offset); NS_ENSURE_SUCCESS(res, res); - curBlock = mHTMLEditor->CreateNode(&aBlockTag, curParent, offset); + NS_ENSURE_STATE(mHTMLEditor); + curBlock = mHTMLEditor->CreateNode(blockTag, curParent, offset); NS_ENSURE_STATE(curBlock); - // Remember our new block for postprocessing + // remember our new block for postprocessing mNewBlock = curBlock->AsDOMNode(); - // Note: doesn't matter if we set mNewBlock multiple times. - res = mHTMLEditor->MoveNode(curNode->AsContent(), curBlock, -1); + // note: doesn't matter if we set mNewBlock multiple times. + NS_ENSURE_STATE(mHTMLEditor); + res = mHTMLEditor->MoveNode(curNode, curBlock, -1); NS_ENSURE_SUCCESS(res, res); } + + + // if curNode is inline, pull it into curBlock + // note: it's assumed that consecutive inline nodes in the + // arrayOfNodes are actually members of the same block parent. + // this happens to be true now as a side effect of how + // arrayOfNodes is contructed, but some additional logic should + // be added here if that should change + } else if (IsInlineNode(GetAsDOMNode(curNode))) { - // If curNode is inline, pull it into curBlock. Note: it's assumed that - // consecutive inline nodes in aNodeArray are actually members of the - // same block parent. This happens to be true now as a side effect of - // how aNodeArray is contructed, but some additional logic should be - // added here if that should change - // - // If curNode is a non editable, drop it if we are going to
    .
    -      if (&aBlockTag == nsGkAtoms::pre && !mHTMLEditor->IsEditable(curNode)) {
    -        // Do nothing to this block
    -        continue;
    -      }
    -
    -      // If no curBlock, make one
    -      if (!curBlock) {
    -        res = SplitAsNeeded(aBlockTag, curParent, offset);
    +      // if curNode is a non editable, drop it if we are going to 
    +      NS_ENSURE_STATE(mHTMLEditor);
    +      if (tString.LowerCaseEqualsLiteral("pre") 
    +        && (!mHTMLEditor->IsEditable(curNode)))
    +        continue; // do nothing to this block
    +      
    +      // if no curBlock, make one
    +      if (!curBlock)
    +      {
    +        res = SplitAsNeeded(*blockTag, curParent, offset);
             NS_ENSURE_SUCCESS(res, res);
    -        curBlock = mHTMLEditor->CreateNode(&aBlockTag, curParent, offset);
    +        NS_ENSURE_STATE(mHTMLEditor);
    +        curBlock = mHTMLEditor->CreateNode(blockTag, curParent, offset);
             NS_ENSURE_STATE(curBlock);
    -        // Remember our new block for postprocessing
    +        // remember our new block for postprocessing
             mNewBlock = curBlock->AsDOMNode();
    -        // Note: doesn't matter if we set mNewBlock multiple times.
    +        // note: doesn't matter if we set mNewBlock multiple times.
           }
    -
    -      // XXX If curNode is a br, replace it with a return if going to 
    -
    -      // This is a continuation of some inline nodes that belong together in
    -      // the same block item.  Use curBlock.
    -      res = mHTMLEditor->MoveNode(curNode->AsContent(), curBlock, -1);
    +      
    +      // if curNode is a Break, replace it with a return if we are going to 
    +      // xxx floppy moose
    + 
    +      // this is a continuation of some inline nodes that belong together in
    +      // the same block item.  use curBlock
    +      NS_ENSURE_STATE(mHTMLEditor);
    +      res = mHTMLEditor->MoveNode(curNode, curBlock, -1);
           NS_ENSURE_SUCCESS(res, res);
         }
       }
    -  return NS_OK;
    +  return res;
     }
     
     
    @@ -7280,26 +7597,40 @@ nsHTMLEditRules::ClearCachedStyles()
     }
     
     
    -void
    -nsHTMLEditRules::AdjustSpecialBreaks()
    +nsresult 
    +nsHTMLEditRules::AdjustSpecialBreaks(bool aSafeToAskFrames)
     {
    -  NS_ENSURE_TRUE(mHTMLEditor, );
    -
    -  // Gather list of empty nodes
    -  nsTArray> nodeArray;
    +  nsCOMArray arrayOfNodes;
    +  nsCOMPtr isupports;
    +  int32_t nodeCount,j;
    +  
    +  // gather list of empty nodes
    +  NS_ENSURE_STATE(mHTMLEditor);
       nsEmptyEditableFunctor functor(mHTMLEditor);
    -  nsDOMIterator iter(*mDocChangeRange);
    -  iter.AppendList(functor, nodeArray);
    +  nsDOMIterator iter;
    +  nsresult res = iter.Init(mDocChangeRange);
    +  NS_ENSURE_SUCCESS(res, res);
    +  res = iter.AppendList(functor, arrayOfNodes);
    +  NS_ENSURE_SUCCESS(res, res);
     
    -  // Put moz-br's into these empty li's and td's
    -  for (auto& node : nodeArray) {
    -    // Need to put br at END of node.  It may have empty containers in it and
    -    // still pass the "IsEmptyNode" test, and we want the br's to be after
    -    // them.  Also, we want the br to be after the selection if the selection
    -    // is in this node.
    -    nsresult res = CreateMozBR(node->AsDOMNode(), (int32_t)node->Length());
    -    NS_ENSURE_SUCCESS(res, );
    +  // put moz-br's into these empty li's and td's
    +  nodeCount = arrayOfNodes.Count();
    +  for (j = 0; j < nodeCount; j++)
    +  {
    +    // need to put br at END of node.  It may have
    +    // empty containers in it and still pass the "IsEmptynode" test,
    +    // and we want the br's to be after them.  Also, we want the br
    +    // to be after the selection if the selection is in this node.
    +    uint32_t len;
    +    nsCOMPtr theNode = arrayOfNodes[0];
    +    arrayOfNodes.RemoveObjectAt(0);
    +    res = nsEditor::GetLengthOfDOMNode(theNode, len);
    +    NS_ENSURE_SUCCESS(res, res);
    +    res = CreateMozBR(theNode, (int32_t)len);
    +    NS_ENSURE_SUCCESS(res, res);
       }
    +  
    +  return res;
     }
     
     nsresult 
    @@ -7705,56 +8036,53 @@ nsHTMLEditRules::InDifferentTableElements(nsINode* aNode1, nsINode* aNode2)
     }
     
     
    -nsresult
    +nsresult 
     nsHTMLEditRules::RemoveEmptyNodes()
     {
    -  NS_ENSURE_STATE(mHTMLEditor);
    -  nsCOMPtr kungFuDeathGrip(mHTMLEditor);
    -
    -  // Some general notes on the algorithm used here: the goal is to examine all
    -  // the nodes in mDocChangeRange, and remove the empty ones.  We do this by
    -  // using a content iterator to traverse all the nodes in the range, and
    -  // placing the empty nodes into an array.  After finishing the iteration, we
    -  // delete the empty nodes in the array.  (They cannot be deleted as we find
    -  // them because that would invalidate the iterator.)
    -  //
    +  // some general notes on the algorithm used here: the goal is to examine all the
    +  // nodes in mDocChangeRange, and remove the empty ones.  We do this by using a
    +  // content iterator to traverse all the nodes in the range, and placing the empty
    +  // nodes into an array.  After finishing the iteration, we delete the empty nodes
    +  // in the array.  (they cannot be deleted as we find them becasue that would 
    +  // invalidate the iterator.)  
       // Since checking to see if a node is empty can be costly for nodes with many
    -  // descendants, there are some optimizations made.  I rely on the fact that
    -  // the iterator is post-order: it will visit children of a node before
    -  // visiting the parent node.  So if I find that a child node is not empty, I
    -  // know that its parent is not empty without even checking.  So I put the
    -  // parent on a "skipList" which is just a voidArray of nodes I can skip the
    -  // empty check on.  If I encounter a node on the skiplist, i skip the
    -  // processing for that node and replace its slot in the skiplist with that
    -  // node's parent.
    -  //
    -  // An interesting idea is to go ahead and regard parent nodes that are NOT on
    -  // the skiplist as being empty (without even doing the IsEmptyNode check) on
    -  // the theory that if they weren't empty, we would have encountered a
    -  // non-empty child earlier and thus put this parent node on the skiplist.
    -  //
    -  // Unfortunately I can't use that strategy here, because the range may
    -  // include some children of a node while excluding others.  Thus I could find
    -  // all the _examined_ children empty, but still not have an empty parent.
    -
    +  // descendants, there are some optimizations made.  I rely on the fact that the
    +  // iterator is post-order: it will visit children of a node before visiting the 
    +  // parent node.  So if I find that a child node is not empty, I know that its
    +  // parent is not empty without even checking.  So I put the parent on a "skipList"
    +  // which is just a voidArray of nodes I can skip the empty check on.  If I 
    +  // encounter a node on the skiplist, i skip the processing for that node and replace
    +  // its slot in the skiplist with that node's parent.
    +  // An interseting idea is to go ahead and regard parent nodes that are NOT on the
    +  // skiplist as being empty (without even doing the IsEmptyNode check) on the theory
    +  // that if they weren't empty, we would have encountered a non-empty child earlier
    +  // and thus put this parent node on the skiplist.
    +  // Unfortunately I can't use that strategy here, because the range may include 
    +  // some children of a node while excluding others.  Thus I could find all the 
    +  // _examined_ children empty, but still not have an empty parent.
    +  
       // need an iterator
    -  nsCOMPtr iter = NS_NewContentIterator();
    -
    +  nsCOMPtr iter =
    +                  do_CreateInstance("@mozilla.org/content/post-content-iterator;1");
    +  NS_ENSURE_TRUE(iter, NS_ERROR_NULL_POINTER);
    +  
       nsresult res = iter->Init(mDocChangeRange);
       NS_ENSURE_SUCCESS(res, res);
    +  
    +  nsCOMArray arrayOfEmptyNodes, arrayOfEmptyCites;
    +  nsTArray > skipList;
     
    -  nsTArray> arrayOfEmptyNodes, arrayOfEmptyCites, skipList;
    -
    -  // Check for empty nodes
    +  // check for empty nodes
       while (!iter->IsDone()) {
    -    OwningNonNull node = *iter->GetCurrentNode();
    +    nsINode* node = iter->GetCurrentNode();
    +    NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
     
    -    nsCOMPtr parent = node->GetParentNode();
    +    nsINode* parent = node->GetParentNode();
     
         size_t idx = skipList.IndexOf(node);
         if (idx != skipList.NoIndex) {
    -      // This node is on our skip list.  Skip processing for this node, and
    -      // replace its value in the skip list with the value of its parent
    +      // this node is on our skip list.  Skip processing for this node, 
    +      // and replace its value in the skip list with the value of its parent
           skipList[idx] = parent;
         } else {
           bool bIsCandidate = false;
    @@ -7762,82 +8090,99 @@ nsHTMLEditRules::RemoveEmptyNodes()
           bool bIsMailCite = false;
     
           if (node->IsElement()) {
    -        if (node->IsHTMLElement(nsGkAtoms::body)) {
    -          // Don't delete the body
    -        } else if ((bIsMailCite = nsHTMLEditUtils::IsMailCite(node)) ||
    -                   node->IsHTMLElement(nsGkAtoms::a) ||
    -                   nsHTMLEditUtils::IsInlineStyle(node) ||
    -                   nsHTMLEditUtils::IsList(node) ||
    -                   node->IsHTMLElement(nsGkAtoms::div)) {
    -          // Only consider certain nodes to be empty for purposes of removal
    +        dom::Element* element = node->AsElement();
    +        if (element->IsHTMLElement(nsGkAtoms::body)) {
    +          // don't delete the body
    +        } else if ((bIsMailCite = nsHTMLEditUtils::IsMailCite(element))  ||
    +                   element->IsHTMLElement(nsGkAtoms::a)                  ||
    +                   nsHTMLEditUtils::IsInlineStyle(element)               ||
    +                   nsHTMLEditUtils::IsList(element)                      ||
    +                   element->IsHTMLElement(nsGkAtoms::div)) {
    +          // only consider certain nodes to be empty for purposes of removal
               bIsCandidate = true;
    -        } else if (nsHTMLEditUtils::IsFormatNode(node) ||
    -                   nsHTMLEditUtils::IsListItem(node) ||
    -                   node->IsHTMLElement(nsGkAtoms::blockquote)) {
    -          // These node types are candidates if selection is not in them.  If
    -          // it is one of these, don't delete if selection inside.  This is so
    -          // we can create empty headings, etc., for the user to type into.
    +        } else if (nsHTMLEditUtils::IsFormatNode(element) ||
    +                   nsHTMLEditUtils::IsListItem(element)   ||
    +                   element->IsHTMLElement(nsGkAtoms::blockquote)) {
    +          // these node types are candidates if selection is not in them
    +          // if it is one of these, don't delete if selection inside.
    +          // this is so we can create empty headings, etc, for the
    +          // user to type into.
               bool bIsSelInNode;
               res = SelectionEndpointInNode(node, &bIsSelInNode);
               NS_ENSURE_SUCCESS(res, res);
    -          if (!bIsSelInNode) {
    +          if (!bIsSelInNode)
    +          {
                 bIsCandidate = true;
               }
             }
           }
    -
    +      
           if (bIsCandidate) {
    -        // We delete mailcites even if they have a solo br in them.  Other
    -        // nodes we require to be empty.
    +        // we delete mailcites even if they have a solo br in them
    +        // other nodes we require to be empty
    +        NS_ENSURE_STATE(mHTMLEditor);
             res = mHTMLEditor->IsEmptyNode(node->AsDOMNode(), &bIsEmptyNode,
                                            bIsMailCite, true);
             NS_ENSURE_SUCCESS(res, res);
             if (bIsEmptyNode) {
               if (bIsMailCite) {
                 // mailcites go on a separate list from other empty nodes
    -            arrayOfEmptyCites.AppendElement(*node);
    +            arrayOfEmptyCites.AppendObject(node);
               } else {
    -            arrayOfEmptyNodes.AppendElement(*node);
    +            arrayOfEmptyNodes.AppendObject(node);
               }
             }
           }
    -
    +      
           if (!bIsEmptyNode) {
             // put parent on skip list
    -        skipList.AppendElement(*parent);
    +        skipList.AppendElement(parent);
           }
         }
     
         iter->Next();
       }
    -
    +  
       // now delete the empty nodes
    -  for (auto& delNode : arrayOfEmptyNodes) {
    +  int32_t nodeCount = arrayOfEmptyNodes.Count();
    +  for (int32_t j = 0; j < nodeCount; j++) {
    +    nsCOMPtr delNode = arrayOfEmptyNodes[0]->AsDOMNode();
    +    arrayOfEmptyNodes.RemoveObjectAt(0);
    +    NS_ENSURE_STATE(mHTMLEditor);
         if (mHTMLEditor->IsModifiableNode(delNode)) {
    +      NS_ENSURE_STATE(mHTMLEditor);
           res = mHTMLEditor->DeleteNode(delNode);
           NS_ENSURE_SUCCESS(res, res);
         }
       }
    -
    -  // Now delete the empty mailcites.  This is a separate step because we want
    -  // to pull out any br's and preserve them.
    -  for (auto& delNode : arrayOfEmptyCites) {
    +  
    +  // now delete the empty mailcites
    +  // this is a separate step because we want to pull out any br's and preserve them.
    +  nodeCount = arrayOfEmptyCites.Count();
    +  for (int32_t j = 0; j < nodeCount; j++) {
    +    nsCOMPtr delNode = arrayOfEmptyCites[0]->AsDOMNode();
    +    arrayOfEmptyCites.RemoveObjectAt(0);
         bool bIsEmptyNode;
    +    NS_ENSURE_STATE(mHTMLEditor);
         res = mHTMLEditor->IsEmptyNode(delNode, &bIsEmptyNode, false, true);
         NS_ENSURE_SUCCESS(res, res);
    -    if (!bIsEmptyNode) {
    -      // We are deleting a cite that has just a br.  We want to delete cite,
    +    if (!bIsEmptyNode)
    +    {
    +      // we are deleting a cite that has just a br.  We want to delete cite, 
           // but preserve br.
    -      nsCOMPtr parent = delNode->GetParentNode();
    -      int32_t offset = parent ? parent->IndexOf(delNode) : -1;
    -      nsCOMPtr br = mHTMLEditor->CreateBR(parent, offset);
    -      NS_ENSURE_STATE(br);
    +      nsCOMPtr parent, brNode;
    +      int32_t offset;
    +      parent = nsEditor::GetNodeLocation(delNode, &offset);
    +      NS_ENSURE_STATE(mHTMLEditor);
    +      res = mHTMLEditor->CreateBR(parent, offset, address_of(brNode));
    +      NS_ENSURE_SUCCESS(res, res);
         }
    +    NS_ENSURE_STATE(mHTMLEditor);
         res = mHTMLEditor->DeleteNode(delNode);
         NS_ENSURE_SUCCESS(res, res);
       }
    -
    -  return NS_OK;
    +  
    +  return res;
     }
     
     nsresult
    @@ -7905,33 +8250,33 @@ nsHTMLEditRules::IsEmptyInline(nsIDOMNode *aNode)
     }
     
     
    -bool
    -nsHTMLEditRules::ListIsEmptyLine(nsTArray>& aArrayOfNodes)
    +bool 
    +nsHTMLEditRules::ListIsEmptyLine(nsCOMArray &arrayOfNodes)
     {
    -  // We have a list of nodes which we are candidates for being moved into a new
    -  // block.  Determine if it's anything more than a blank line.  Look for
    -  // editable content above and beyond one single BR.
    -  NS_ENSURE_TRUE(aArrayOfNodes.Length(), true);
    -
    -  NS_ENSURE_TRUE(mHTMLEditor, false);
    -  nsCOMPtr kungFuDeathGrip(mHTMLEditor);
    -
    -  int32_t brCount = 0;
    -
    -  for (auto& node : aArrayOfNodes) {
    -    if (!mHTMLEditor->IsEditable(node)) {
    -      continue;
    -    }
    -    if (nsTextEditUtils::IsBreak(node)) {
    -      // First break doesn't count
    -      if (brCount) {
    -        return false;
    +  // we have a list of nodes which we are candidates for being moved
    +  // into a new block.  Determine if it's anything more than a blank line.
    +  // Look for editable content above and beyond one single BR.
    +  int32_t listCount = arrayOfNodes.Count();
    +  NS_ENSURE_TRUE(listCount, true);
    +  nsCOMPtr somenode;
    +  int32_t j, brCount=0;
    +  for (j = 0; j < listCount; j++)
    +  {
    +    somenode = arrayOfNodes[j];
    +    NS_ENSURE_TRUE(mHTMLEditor, false);
    +    if (somenode && mHTMLEditor->IsEditable(somenode))
    +    {
    +      if (nsTextEditUtils::IsBreak(somenode))
    +      {
    +        // first break doesn't count
    +        if (brCount) return false;
    +        brCount++;
           }
    -      brCount++;
    -    } else if (IsEmptyInline(GetAsDOMNode(node))) {
    -      // Empty inline, keep looking
    -    } else {
    -      return false;
    +      else if (IsEmptyInline(somenode)) 
    +      {
    +        // empty inline, keep looking
    +      }
    +      else return false;
         }
       }
       return true;
    @@ -8734,11 +9079,12 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection,
       // whose children are all in the range
       
       nsTArray> arrayOfRanges;
    -  GetPromotedRanges(*aSelection, arrayOfRanges,
    -                    EditAction::setAbsolutePosition);
    +  res = GetPromotedRanges(aSelection, arrayOfRanges,
    +                          EditAction::setAbsolutePosition);
    +  NS_ENSURE_SUCCESS(res, res);
       
       // use these ranges to contruct a list of nodes to act on.
    -  nsTArray> arrayOfNodes;
    +  nsCOMArray arrayOfNodes;
       res = GetNodesForOperation(arrayOfRanges, arrayOfNodes,
                                  EditAction::setAbsolutePosition);
       NS_ENSURE_SUCCESS(res, res);                                 
    @@ -8762,12 +9108,13 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection,
         // remember our new block for postprocessing
         mNewBlock = thePositionedDiv->AsDOMNode();
         // delete anything that was in the list of nodes
    -    while (!arrayOfNodes.IsEmpty()) {
    -      OwningNonNull curNode = arrayOfNodes[0];
    +    for (int32_t j = arrayOfNodes.Count() - 1; j >= 0; --j) 
    +    {
    +      nsCOMPtr curNode = arrayOfNodes[0];
           NS_ENSURE_STATE(mHTMLEditor);
           res = mHTMLEditor->DeleteNode(curNode);
           NS_ENSURE_SUCCESS(res, res);
    -      arrayOfNodes.RemoveElementAt(0);
    +      arrayOfNodes.RemoveObjectAt(0);
         }
         // put selection in new block
         res = aSelection->Collapse(thePositionedDiv,0);
    @@ -8778,13 +9125,16 @@ nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection,
     
       // Ok, now go through all the nodes and put them in a blockquote, 
       // or whatever is appropriate.  Wohoo!
    +  int32_t i;
       nsCOMPtr curParent;
       nsCOMPtr indentedLI, sibling;
       nsCOMPtr curList, curPositionedDiv;
    -  for (uint32_t i = 0; i < arrayOfNodes.Length(); i++) {
    +  int32_t listCount = arrayOfNodes.Count();
    +  for (i=0; iIsContent());
    -    nsCOMPtr curNode = arrayOfNodes[i]->AsContent();
    +    nsCOMPtr curNode = do_QueryInterface(arrayOfNodes[i]);
    +    NS_ENSURE_STATE(curNode);
     
         // Ignore all non-editable nodes.  Leave them be.
         NS_ENSURE_STATE(mHTMLEditor);
    diff --git a/editor/libeditor/nsHTMLEditRules.h b/editor/libeditor/nsHTMLEditRules.h
    index 0d8f841f9743..01760d2cffaf 100644
    --- a/editor/libeditor/nsHTMLEditRules.h
    +++ b/editor/libeditor/nsHTMLEditRules.h
    @@ -37,6 +37,7 @@ class Selection;
     }  // namespace dom
     }  // namespace mozilla
     struct DOMPoint;
    +template  class nsCOMArray;
     
     struct StyleCache : public PropItem
     {
    @@ -190,17 +191,14 @@ protected:
       nsresult DidMakeBasicBlock(mozilla::dom::Selection* aSelection,
                                  nsRulesInfo* aInfo, nsresult aResult);
       nsresult DidAbsolutePosition();
    -  nsresult AlignInnerBlocks(nsINode& aNode, const nsAString* alignType);
    +  nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
       nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType);
    -  nsresult AppendInnerFormatNodes(nsTArray>& aArray,
    +  nsresult AppendInnerFormatNodes(nsCOMArray& aArray,
                                       nsINode* aNode);
    +  nsresult AppendInnerFormatNodes(nsCOMArray& aArray,
    +                                  nsIDOMNode *aNode);
       nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat);
    -  enum class Lists { no, yes };
    -  enum class Tables { no, yes };
    -  void GetInnerContent(nsINode& aNode,
    -                       nsTArray>& aOutArrayOfNodes,
    -                       int32_t* aIndex, Lists aLists = Lists::yes,
    -                       Tables aTables = Tables::yes);
    +  nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray& outArrayOfNodes, int32_t *aIndex, bool aList = true, bool aTble = true);
       already_AddRefed IsInListItem(nsIDOMNode* aNode);
       mozilla::dom::Element* IsInListItem(nsINode* aNode);
       nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
    @@ -219,9 +217,11 @@ protected:
                                 int32_t aOffset);
       nsresult AfterEditInner(EditAction action,
                               nsIEditor::EDirection aDirection);
    -  nsresult RemovePartOfBlock(mozilla::dom::Element& aBlock,
    -                             nsIContent& aStartChild,
    -                             nsIContent& aEndChild);
    +  nsresult RemovePartOfBlock(nsIDOMNode *aBlock, 
    +                             nsIDOMNode *aStartChild, 
    +                             nsIDOMNode *aEndChild,
    +                             nsCOMPtr *aLeftNode = 0,
    +                             nsCOMPtr *aRightNode = 0);
       nsresult SplitBlock(nsIDOMNode *aBlock, 
                           nsIDOMNode *aStartChild, 
                           nsIDOMNode *aEndChild,
    @@ -263,44 +263,37 @@ protected:
       void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
                             int32_t aOffset, EditAction actionID,
                             nsCOMPtr* outNode, int32_t* outOffset);
    -  void GetPromotedRanges(mozilla::dom::Selection& aSelection, 
    -                         nsTArray>& outArrayOfRanges,
    -                         EditAction inOperationType);
    -  void PromoteRange(nsRange& aRange, EditAction inOperationType);
    -  enum class TouchContent { no, yes };
    -  nsresult GetNodesForOperation(nsTArray>& aArrayOfRanges,
    -                                nsTArray>& aOutArrayOfNodes,
    -                                EditAction aOperationType,
    -                                TouchContent aTouchContent = TouchContent::yes);
    -  void GetChildNodesForOperation(nsINode& aNode,
    -      nsTArray>& outArrayOfNodes);
    -  nsresult GetNodesFromPoint(::DOMPoint aPoint,
    -                             EditAction aOperation,
    -                             nsTArray>& outArrayOfNodes,
    -                             TouchContent aTouchContent);
    -  nsresult GetNodesFromSelection(mozilla::dom::Selection& aSelection,
    -                                 EditAction aOperation,
    -                                 nsTArray>& outArrayOfNodes,
    -                                 TouchContent aTouchContent = TouchContent::yes);
    -  enum class EntireList { no, yes };
    -  nsresult GetListActionNodes(nsTArray>& aOutArrayOfNodes,
    -                              EntireList aEntireList,
    -                              TouchContent aTouchContent = TouchContent::yes);
    +  nsresult GetPromotedRanges(mozilla::dom::Selection* aSelection, 
    +                             nsTArray>& outArrayOfRanges,
    +                             EditAction inOperationType);
    +  nsresult PromoteRange(nsRange* inRange, EditAction inOperationType);
    +  nsresult GetNodesForOperation(nsTArray>& inArrayOfRanges, 
    +                                nsCOMArray& outArrayOfNodes, 
    +                                EditAction inOperationType,
    +                                bool aDontTouchContent=false);
    +  nsresult GetChildNodesForOperation(nsIDOMNode *inNode, 
    +                                     nsCOMArray& outArrayOfNodes);
    +  nsresult GetNodesFromPoint(::DOMPoint point,
    +                             EditAction operation,
    +                             nsCOMArray& arrayOfNodes,
    +                             bool dontTouchContent);
    +  nsresult GetNodesFromSelection(mozilla::dom::Selection* selection,
    +                                 EditAction operation,
    +                                 nsCOMArray& arrayOfNodes,
    +                                 bool aDontTouchContent=false);
    +  nsresult GetListActionNodes(nsCOMArray &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false);
       void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD);
    -  nsresult GetParagraphFormatNodes(
    -      nsTArray>& outArrayOfNodes,
    -      TouchContent aTouchContent = TouchContent::yes);
    -  void LookInsideDivBQandList(nsTArray>& aNodeArray);
    +  nsresult GetParagraphFormatNodes(nsCOMArray& outArrayOfNodes, bool aDontTouchContent=false);
    +  nsresult LookInsideDivBQandList(nsCOMArray& aNodeArray);
       nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange);
    -  nsresult BustUpInlinesAtBRs(nsINode& aNode,
    -                              nsTArray>& aOutArrayOfNodes);
    +  nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode, 
    +                              nsCOMArray& outArrayOfNodes);
       nsCOMPtr GetHighestInlineParent(nsIDOMNode* aNode);
    -  void MakeTransitionList(nsTArray>& aNodeArray,
    -                          nsTArray& aTransitionArray);
    -  nsresult RemoveBlockStyle(nsTArray>& aNodeArray);
    -  nsresult ApplyBlockStyle(nsTArray>& aNodeArray,
    -                           nsIAtom& aBlockTag);
    -  nsresult MakeBlockquote(nsTArray>& aNodeArray);
    +  nsresult MakeTransitionList(nsCOMArray& inArrayOfNodes, 
    +                              nsTArray &inTransitionArray);
    +  nsresult RemoveBlockStyle(nsCOMArray& arrayOfNodes);
    +  nsresult ApplyBlockStyle(nsCOMArray& arrayOfNodes, const nsAString *aBlockTag);
    +  nsresult MakeBlockquote(nsCOMArray& arrayOfNodes);
       nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr& inOutParent,
                              int32_t& inOutOffset);
       nsresult AddTerminatingBR(nsIDOMNode *aBlock);
    @@ -311,7 +304,7 @@ protected:
       nsresult CacheInlineStyles(nsIDOMNode *aNode);
       nsresult ReapplyCachedStyles();
       void ClearCachedStyles();
    -  void AdjustSpecialBreaks();
    +  nsresult AdjustSpecialBreaks(bool aSafeToAskFrames = false);
       nsresult AdjustWhitespace(mozilla::dom::Selection* aSelection);
       nsresult PinSelectionToNewBlock(mozilla::dom::Selection* aSelection);
       nsresult CheckInterlinePosition(mozilla::dom::Selection* aSelection);
    @@ -336,7 +329,7 @@ protected:
       nsresult ConfirmSelectionInBody();
       nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode);
       bool     IsEmptyInline(nsIDOMNode *aNode);
    -  bool     ListIsEmptyLine(nsTArray>& arrayOfNodes);
    +  bool     ListIsEmptyLine(nsCOMArray &arrayOfNodes);
       nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly);
       nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts);
       nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly);
    diff --git a/editor/libeditor/nsHTMLEditor.cpp b/editor/libeditor/nsHTMLEditor.cpp
    index 04cd9444ac7e..c881907d2323 100644
    --- a/editor/libeditor/nsHTMLEditor.cpp
    +++ b/editor/libeditor/nsHTMLEditor.cpp
    @@ -195,7 +195,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLEditor, nsPlaintextEdito
       NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMouseMotionListenerP)
       NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectionListenerP)
       NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizeEventListenerP)
    -  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObjectResizeEventListeners)
    +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(objectResizeEventListeners)
     
       NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAbsolutelyPositionedObject)
       NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGrabber)
    @@ -2988,6 +2988,8 @@ nsHTMLEditor::GetURLForStyleSheet(CSSStyleSheet* aStyleSheet,
       int32_t foundIndex = mStyleSheets.IndexOf(aStyleSheet);
     
       // Don't fail if we don't find it in our list
    +  // Note: mStyleSheets is nsCOMArray, so its IndexOf() method
    +  // returns -1 on failure.
       if (foundIndex == -1)
         return NS_OK;
     
    @@ -4501,156 +4503,196 @@ nsHTMLEditor::SetIsCSSEnabled(bool aIsCSSPrefChecked)
     nsresult
     nsHTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
     {
    -  NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
    +  if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
       ForceCompositionEnd();
     
       // Protect the edit rules object from dying
       nsCOMPtr kungFuDeathGrip(mRules);
     
       nsRefPtr selection = GetSelection();
    -  NS_ENSURE_STATE(selection);
     
       bool isCollapsed = selection->Collapsed();
     
       nsAutoEditBatch batchIt(this);
    -  nsAutoRules beginRulesSniffing(this, EditAction::insertElement,
    -                                 nsIEditor::eNext);
    +  nsAutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext);
       nsAutoSelectionReset selectionResetter(selection, this);
       nsAutoTxnsConserveSelection dontSpazMySelection(this);
    -
    +  
       bool cancel, handled;
       nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
       nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
       NS_ENSURE_SUCCESS(res, res);
    -  if (!cancel && !handled) {
    -    // Loop through the ranges in the selection
    -    NS_NAMED_LITERAL_STRING(bgcolor, "bgcolor");
    -    for (uint32_t i = 0; i < selection->RangeCount(); i++) {
    -      nsRefPtr range = selection->GetRangeAt(i);
    +  if (!cancel && !handled)
    +  {
    +    // loop thru the ranges in the selection
    +    nsAutoString bgcolor; bgcolor.AssignLiteral("bgcolor");
    +    uint32_t rangeCount = selection->RangeCount();
    +    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
    +      nsCOMPtr cachedBlockParent = nullptr;
    +      nsRefPtr range = selection->GetRangeAt(rangeIdx);
           NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
    -
    -      nsCOMPtr cachedBlockParent;
    -
    -      // Check for easy case: both range endpoints in same text node
    -      nsCOMPtr startNode = range->GetStartParent();
    -      int32_t startOffset = range->StartOffset();
    -      nsCOMPtr endNode = range->GetEndParent();
    -      int32_t endOffset = range->EndOffset();
    -      if (startNode == endNode && IsTextNode(startNode)) {
    -        // Let's find the block container of the text node
    -        nsCOMPtr blockParent = GetBlockNodeParent(startNode);
    -        // And apply the background color to that block container
    +      
    +      // check for easy case: both range endpoints in same text node
    +      nsCOMPtr startNode, endNode;
    +      int32_t startOffset, endOffset;
    +      res = range->GetStartContainer(getter_AddRefs(startNode));
    +      NS_ENSURE_SUCCESS(res, res);
    +      res = range->GetEndContainer(getter_AddRefs(endNode));
    +      NS_ENSURE_SUCCESS(res, res);
    +      res = range->GetStartOffset(&startOffset);
    +      NS_ENSURE_SUCCESS(res, res);
    +      res = range->GetEndOffset(&endOffset);
    +      NS_ENSURE_SUCCESS(res, res);
    +      if ((startNode == endNode) && IsTextNode(startNode))
    +      {
    +        // let's find the block container of the text node
    +        nsCOMPtr blockParent;
    +        blockParent = GetBlockNodeParent(startNode);
    +        // and apply the background color to that block container
             if (blockParent && cachedBlockParent != blockParent) {
               cachedBlockParent = blockParent;
    -          mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
    -                                                     &bgcolor, &aColor, false);
    +          nsCOMPtr element = do_QueryInterface(blockParent);
    +          int32_t count;
    +          res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
    +          NS_ENSURE_SUCCESS(res, res);
             }
    -      } else if (startNode == endNode &&
    -                 startNode->IsHTMLElement(nsGkAtoms::body) && isCollapsed) {
    -        // No block in the document, let's apply the background to the body
    -        mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(startNode->AsElement(),
    -                                                   nullptr, &bgcolor, &aColor,
    -                                                   false);
    -      } else if (startNode == endNode && (endOffset - startOffset == 1 ||
    -                                          (!startOffset && !endOffset))) {
    -        // A unique node is selected, let's also apply the background color to
    -        // the containing block, possibly the node itself
    -        nsCOMPtr selectedNode = startNode->GetChildAt(startOffset);
    -        nsCOMPtr blockParent;
    -        if (NodeIsBlockStatic(selectedNode)) {
    -          blockParent = selectedNode->AsElement();
    -        } else {
    +      }
    +      else if ((startNode == endNode) && nsTextEditUtils::IsBody(startNode) && isCollapsed)
    +      {
    +        // we have no block in the document, let's apply the background to the body 
    +        nsCOMPtr element = do_QueryInterface(startNode);
    +        int32_t count;
    +        res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
    +        NS_ENSURE_SUCCESS(res, res);
    +      }
    +      else if ((startNode == endNode) && (((endOffset-startOffset) == 1) || (!startOffset && !endOffset)))
    +      {
    +        // a unique node is selected, let's also apply the background color
    +        // to the containing block, possibly the node itself
    +        nsCOMPtr selectedNode = GetChildAt(startNode, startOffset);
    +        bool isBlock =false;
    +        res = NodeIsBlockStatic(selectedNode, &isBlock);
    +        NS_ENSURE_SUCCESS(res, res);
    +        nsCOMPtr blockParent = selectedNode;
    +        if (!isBlock) {
               blockParent = GetBlockNodeParent(selectedNode);
             }
             if (blockParent && cachedBlockParent != blockParent) {
               cachedBlockParent = blockParent;
    -          mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
    -                                                     &bgcolor, &aColor, false);
    +          nsCOMPtr element = do_QueryInterface(blockParent);
    +          int32_t count;
    +          res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
    +          NS_ENSURE_SUCCESS(res, res);
             }
    -      } else {
    -        // Not the easy case.  Range not contained in single text node.  There
    -        // are up to three phases here.  There are all the nodes reported by
    -        // the subtree iterator to be processed.  And there are potentially a
    -        // starting textnode and an ending textnode which are only partially
    -        // contained by the range.
    +      }
    +      else
    +      {
    +        // not the easy case.  range not contained in single text node. 
    +        // there are up to three phases here.  There are all the nodes
    +        // reported by the subtree iterator to be processed.  And there
    +        // are potentially a starting textnode and an ending textnode
    +        // which are only partially contained by the range.
    +        
    +        // lets handle the nodes reported by the iterator.  These nodes
    +        // are entirely contained in the selection range.  We build up
    +        // a list of them (since doing operations on the document during
    +        // iteration would perturb the iterator).
     
    -        // Let's handle the nodes reported by the iterator.  These nodes are
    -        // entirely contained in the selection range.  We build up a list of
    -        // them (since doing operations on the document during iteration would
    -        // perturb the iterator).
    +        nsCOMPtr iter =
    +          do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
    +        NS_ENSURE_SUCCESS(res, res);
    +        NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE);
     
    -        OwningNonNull iter =
    -          NS_NewContentSubtreeIterator();
    -
    -        nsTArray> arrayOfNodes;
    -        nsCOMPtr node;
    -
    -        // Iterate range and build up array
    +        nsCOMArray arrayOfNodes;
    +        nsCOMPtr node;
    +                
    +        // iterate range and build up array
             res = iter->Init(range);
    -        // Init returns an error if no nodes in range.  This can easily happen
    -        // with the subtree iterator if the selection doesn't contain any
    -        // *whole* nodes.
    -        if (NS_SUCCEEDED(res)) {
    -          for (; !iter->IsDone(); iter->Next()) {
    +        // init returns an error if no nodes in range.
    +        // this can easily happen with the subtree 
    +        // iterator if the selection doesn't contain
    +        // any *whole* nodes.
    +        if (NS_SUCCEEDED(res))
    +        {
    +          while (!iter->IsDone())
    +          {
                 node = do_QueryInterface(iter->GetCurrentNode());
                 NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
     
    -            if (IsEditable(node)) {
    -              arrayOfNodes.AppendElement(*node);
    +            if (IsEditable(node))
    +            {
    +              arrayOfNodes.AppendObject(node);
                 }
    +
    +            iter->Next();
               }
             }
    -        // First check the start parent of the range to see if it needs to be
    -        // separately handled (it does if it's a text node, due to how the
    +        // first check the start parent of the range to see if it needs to 
    +        // be separately handled (it does if it's a text node, due to how the
             // subtree iterator works - it will not have reported it).
    -        if (IsTextNode(startNode) && IsEditable(startNode)) {
    -          nsCOMPtr blockParent = GetBlockNodeParent(startNode);
    +        if (IsTextNode(startNode) && IsEditable(startNode))
    +        {
    +          nsCOMPtr blockParent;
    +          blockParent = GetBlockNodeParent(startNode);
               if (blockParent && cachedBlockParent != blockParent) {
                 cachedBlockParent = blockParent;
    -            mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
    -                                                       &bgcolor, &aColor,
    -                                                       false);
    +            nsCOMPtr element = do_QueryInterface(blockParent);
    +            int32_t count;
    +            res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
    +            NS_ENSURE_SUCCESS(res, res);
               }
             }
    -
    -        // Then loop through the list, set the property on each node
    -        for (auto& node : arrayOfNodes) {
    -          nsCOMPtr blockParent;
    -          if (NodeIsBlockStatic(node)) {
    -            blockParent = node->AsElement();
    -          } else {
    +        
    +        // then loop through the list, set the property on each node
    +        int32_t listCount = arrayOfNodes.Count();
    +        int32_t j;
    +        for (j = 0; j < listCount; j++)
    +        {
    +          node = arrayOfNodes[j];
    +          // do we have a block here ?
    +          bool isBlock =false;
    +          res = NodeIsBlockStatic(node, &isBlock);
    +          NS_ENSURE_SUCCESS(res, res);
    +          nsCOMPtr blockParent = node;
    +          if (!isBlock) {
    +            // no we don't, let's find the block ancestor
                 blockParent = GetBlockNodeParent(node);
               }
               if (blockParent && cachedBlockParent != blockParent) {
                 cachedBlockParent = blockParent;
    -            mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
    -                                                       &bgcolor, &aColor,
    -                                                       false);
    +            nsCOMPtr element = do_QueryInterface(blockParent);
    +            int32_t count;
    +            // and set the property on it
    +            res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
    +            NS_ENSURE_SUCCESS(res, res);
               }
             }
             arrayOfNodes.Clear();
    -
    -        // Last, check the end parent of the range to see if it needs to be
    -        // separately handled (it does if it's a text node, due to how the
    +        
    +        // last check the end parent of the range to see if it needs to 
    +        // be separately handled (it does if it's a text node, due to how the
             // subtree iterator works - it will not have reported it).
    -        if (IsTextNode(endNode) && IsEditable(endNode)) {
    -          nsCOMPtr blockParent = GetBlockNodeParent(endNode);
    +        if (IsTextNode(endNode) && IsEditable(endNode))
    +        {
    +          nsCOMPtr blockParent;
    +          blockParent = GetBlockNodeParent(endNode);
               if (blockParent && cachedBlockParent != blockParent) {
                 cachedBlockParent = blockParent;
    -            mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
    -                                                       &bgcolor, &aColor,
    -                                                       false);
    +            nsCOMPtr element = do_QueryInterface(blockParent);
    +            int32_t count;
    +            res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
    +            NS_ENSURE_SUCCESS(res, res);
               }
             }
           }
         }
       }
    -  if (!cancel) {
    -    // Post-process
    +  if (!cancel)
    +  {
    +    // post-process
         res = mRules->DidDoAction(selection, &ruleInfo, res);
    -    NS_ENSURE_SUCCESS(res, res);
       }
    -  return NS_OK;
    +  return res;
     }
     
     NS_IMETHODIMP
    diff --git a/editor/libeditor/nsHTMLEditor.h b/editor/libeditor/nsHTMLEditor.h
    index d20da0716520..3fc3765b41b5 100644
    --- a/editor/libeditor/nsHTMLEditor.h
    +++ b/editor/libeditor/nsHTMLEditor.h
    @@ -7,6 +7,7 @@
     #define nsHTMLEditor_h__
     
     #include "nsCOMPtr.h"
    +#include "nsCOMArray.h"
     #include "nsPlaintextEditor.h"
     #include "nsIEditor.h"
     #include "nsIHTMLEditor.h"
    @@ -40,7 +41,6 @@
     #include "mozilla/Attributes.h"
     #include "mozilla/dom/Element.h"
     
    -class nsDocumentFragment;
     class nsIDOMKeyEvent;
     class nsITransferable;
     class nsIClipboard;
    @@ -53,9 +53,6 @@ class nsRange;
     struct PropItem;
     
     namespace mozilla {
    -namespace dom {
    -template class OwningNonNull;
    -}
     namespace widget {
     struct IMEState;
     } // namespace widget
    @@ -594,27 +591,29 @@ protected:
                                nsIDocument* aTargetDoc,
                                nsCOMPtr *outNode,
                                bool aTrustedInput);
    -  void       CreateListOfNodesToPaste(mozilla::dom::DocumentFragment& aFragment,
    -                                      nsTArray>& outNodeList,
    -                                      nsINode* aStartNode,
    +  nsresult   CreateListOfNodesToPaste(nsIDOMNode  *aFragmentAsNode,
    +                                      nsCOMArray& outNodeList,
    +                                      nsIDOMNode *aStartNode,
                                           int32_t aStartOffset,
    -                                      nsINode* aEndNode,
    +                                      nsIDOMNode *aEndNode,
                                           int32_t aEndOffset);
       nsresult CreateTagStack(nsTArray &aTagStack,
                               nsIDOMNode *aNode);
    -  enum class StartOrEnd { start, end };
    -  void GetListAndTableParents(StartOrEnd aStartOrEnd,
    -                              nsTArray>& aNodeList,
    -                              nsTArray>& outArray);
    -  int32_t DiscoverPartialListsAndTables(nsTArray>& aPasteNodes,
    -                                        nsTArray>& aListsAndTables);
    -  nsINode* ScanForListAndTableStructure(StartOrEnd aStartOrEnd,
    -                                        nsTArray>& aNodes,
    -                                        mozilla::dom::Element& aListOrTable);
    -  void ReplaceOrphanedStructure(StartOrEnd aStartOrEnd,
    -                                nsTArray>& aNodeArray,
    -                                nsTArray>& aListAndTableArray,
    -                                int32_t aHighWaterMark);
    +  nsresult GetListAndTableParents( bool aEnd, 
    +                                   nsCOMArray& aListOfNodes,
    +                                   nsCOMArray& outArray);
    +  nsresult DiscoverPartialListsAndTables(nsCOMArray& aPasteNodes,
    +                                         nsCOMArray& aListsAndTables,
    +                                         int32_t *outHighWaterMark);
    +  nsresult ScanForListAndTableStructure(bool aEnd,
    +                                        nsCOMArray& aNodes,
    +                                        nsIDOMNode *aListOrTable,
    +                                        nsCOMPtr *outReplaceNode);
    +  nsresult ReplaceOrphanedStructure( bool aEnd,
    +                                     nsCOMArray& aNodeArray,
    +                                     nsCOMArray& aListAndTableArray,
    +                                     int32_t aHighWaterMark);
    +  nsIDOMNode* GetArrayEndpoint(bool aEnd, nsCOMArray& aNodeArray);
     
       /* small utility routine to test if a break node is visible to user */
       bool     IsVisBreak(nsINode* aNode);
    @@ -634,8 +633,7 @@ protected:
       nsresult InsertBasicBlock(const nsAString & aBlockType);
       
       /* increase/decrease the font size of selection */
    -  enum class FontSize { incr, decr };
    -  nsresult RelativeFontChange(FontSize aDir);
    +  nsresult RelativeFontChange( int32_t aSizeChange);
       
       /* helper routines for font size changing */
       nsresult RelativeFontChangeOnTextNode( int32_t aSizeChange, 
    @@ -652,10 +650,14 @@ protected:
                                            nsIAtom& aProperty,
                                            const nsAString* aAttribute,
                                            const nsAString& aValue);
    -  nsresult SetInlinePropertyOnNode(nsIContent& aNode,
    -                                   nsIAtom& aProperty,
    +  nsresult SetInlinePropertyOnNode( nsIDOMNode *aNode,
    +                                    nsIAtom *aProperty, 
    +                                    const nsAString *aAttribute,
    +                                    const nsAString *aValue);
    +  nsresult SetInlinePropertyOnNode(nsIContent* aNode,
    +                                   nsIAtom* aProperty,
                                        const nsAString* aAttribute,
    -                                   const nsAString& aValue);
    +                                   const nsAString* aValue);
     
       nsresult PromoteInlineRange(nsRange* aRange);
       nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange* aRange);
    @@ -756,7 +758,7 @@ protected:
     // Data members
     protected:
     
    -  nsTArray> mContentFilters;
    +  nsCOMArray mContentFilters;
     
       nsRefPtr        mTypeInState;
     
    @@ -846,7 +848,7 @@ protected:
       nsCOMPtr mSelectionListenerP;
       nsCOMPtr  mResizeEventListenerP;
     
    -  nsTArray> mObjectResizeEventListeners;
    +  nsCOMArray objectResizeEventListeners;
     
       int32_t mOriginalX;
       int32_t mOriginalY;
    @@ -957,10 +959,10 @@ private:
                                   nsIAtom* aProperty,
                                   const nsAString* aAttribute,
                                   const nsAString* aValue);
    -  nsresult SetInlinePropertyOnNodeImpl(nsIContent& aNode,
    -                                       nsIAtom& aProperty,
    +  nsresult SetInlinePropertyOnNodeImpl(nsIContent* aNode,
    +                                       nsIAtom* aProperty,
                                            const nsAString* aAttribute,
    -                                       const nsAString& aValue);
    +                                       const nsAString* aValue);
       typedef enum { eInserted, eAppended } InsertedOrAppended;
       void DoContentInserted(nsIDocument* aDocument, nsIContent* aContainer,
                              nsIContent* aChild, int32_t aIndexInContainer,
    diff --git a/editor/libeditor/nsHTMLEditorStyle.cpp b/editor/libeditor/nsHTMLEditorStyle.cpp
    index c85e4f5f8662..af8bd880aa05 100644
    --- a/editor/libeditor/nsHTMLEditorStyle.cpp
    +++ b/editor/libeditor/nsHTMLEditorStyle.cpp
    @@ -10,6 +10,7 @@
     #include "nsAString.h"
     #include "nsAttrName.h"
     #include "nsAutoPtr.h"
    +#include "nsCOMArray.h"
     #include "nsCOMPtr.h"
     #include "nsCaseTreatment.h"
     #include "nsComponentManagerUtils.h"
    @@ -108,20 +109,23 @@ NS_IMETHODIMP nsHTMLEditor::RemoveAllDefaultProperties()
     
     
     NS_IMETHODIMP
    -nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty,
    +nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
                                     const nsAString& aAttribute,
                                     const nsAString& aValue)
     {
    -  NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER);
    -  NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
    -  nsCOMPtr kungFuDeathGrip(mRules);
    +  if (!aProperty) {
    +    return NS_ERROR_NULL_POINTER;
    +  }
    +  if (!mRules) {
    +    return NS_ERROR_NOT_INITIALIZED;
    +  }
       ForceCompositionEnd();
     
       nsRefPtr selection = GetSelection();
       NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
     
       if (selection->Collapsed()) {
    -    // Manipulating text attributes on a collapsed selection only sets state
    +    // manipulating text attributes on a collapsed selection only sets state
         // for the next text insertion
         mTypeInState->SetProp(aProperty, aAttribute, aValue);
         return NS_OK;
    @@ -135,20 +139,21 @@ nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty,
       bool cancel, handled;
       nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
       // Protect the edit rules object from dying
    +  nsCOMPtr kungFuDeathGrip(mRules);
       nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
       NS_ENSURE_SUCCESS(res, res);
       if (!cancel && !handled) {
    -    // Loop through the ranges in the selection
    +    // loop thru the ranges in the selection
         uint32_t rangeCount = selection->RangeCount();
    -    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; rangeIdx++) {
    +    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
           nsRefPtr range = selection->GetRangeAt(rangeIdx);
     
    -      // Adjust range to include any ancestors whose children are entirely
    +      // adjust range to include any ancestors whose children are entirely
           // selected
           res = PromoteInlineRange(range);
           NS_ENSURE_SUCCESS(res, res);
     
    -      // Check for easy case: both range endpoints in same text node
    +      // check for easy case: both range endpoints in same text node
           nsCOMPtr startNode = range->GetStartParent();
           nsCOMPtr endNode = range->GetEndParent();
           if (startNode && startNode == endNode && startNode->GetAsText()) {
    @@ -171,26 +176,31 @@ nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty,
           // (since doing operations on the document during iteration would perturb
           // the iterator).
     
    -      OwningNonNull iter = NS_NewContentSubtreeIterator();
    +      nsCOMPtr iter =
    +        do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
    +      NS_ENSURE_SUCCESS(res, res);
    +      NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE);
     
    -      nsTArray> arrayOfNodes;
    +      nsCOMArray arrayOfNodes;
     
    -      // Iterate range and build up array
    +      // iterate range and build up array
           res = iter->Init(range);
           // Init returns an error if there are no nodes in range.  This can easily
           // happen with the subtree iterator if the selection doesn't contain any
           // *whole* nodes.
           if (NS_SUCCEEDED(res)) {
    +        nsCOMPtr node;
             for (; !iter->IsDone(); iter->Next()) {
    -          OwningNonNull node = *iter->GetCurrentNode();
    +          node = do_QueryInterface(iter->GetCurrentNode());
    +          NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
     
    -          if (node->IsContent() && IsEditable(node)) {
    -            arrayOfNodes.AppendElement(*node->AsContent());
    +          if (IsEditable(node)) {
    +            arrayOfNodes.AppendObject(node);
               }
             }
           }
    -      // First check the start parent of the range to see if it needs to be
    -      // separately handled (it does if it's a text node, due to how the
    +      // first check the start parent of the range to see if it needs to
    +      // be separately handled (it does if it's a text node, due to how the
           // subtree iterator works - it will not have reported it).
           if (startNode && startNode->GetAsText() && IsEditable(startNode)) {
             res = SetInlinePropertyOnTextNode(*startNode->GetAsText(),
    @@ -200,14 +210,17 @@ nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty,
             NS_ENSURE_SUCCESS(res, res);
           }
     
    -      // Then loop through the list, set the property on each node
    -      for (auto& node : arrayOfNodes) {
    -        res = SetInlinePropertyOnNode(*node, *aProperty, &aAttribute, aValue);
    +      // then loop through the list, set the property on each node
    +      int32_t listCount = arrayOfNodes.Count();
    +      int32_t j;
    +      for (j = 0; j < listCount; j++) {
    +        res = SetInlinePropertyOnNode(arrayOfNodes[j], aProperty,
    +                                      &aAttribute, &aValue);
             NS_ENSURE_SUCCESS(res, res);
           }
     
    -      // Last check the end parent of the range to see if it needs to be
    -      // separately handled (it does if it's a text node, due to how the
    +      // last check the end parent of the range to see if it needs to
    +      // be separately handled (it does if it's a text node, due to how the
           // subtree iterator works - it will not have reported it).
           if (endNode && endNode->GetAsText() && IsEditable(endNode)) {
             res = SetInlinePropertyOnTextNode(*endNode->GetAsText(), 0,
    @@ -218,7 +231,7 @@ nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty,
         }
       }
       if (!cancel) {
    -    // Post-process
    +    // post-process
         return mRules->DidDoAction(selection, &ruleInfo, res);
       }
       return NS_OK;
    @@ -363,37 +376,41 @@ nsHTMLEditor::SetInlinePropertyOnTextNode(Text& aText,
       }
     
       // Reparent the node inside inline node with appropriate {attribute,value}
    -  return SetInlinePropertyOnNode(*text, aProperty, aAttribute, aValue);
    +  return SetInlinePropertyOnNode(text, &aProperty, aAttribute, &aValue);
     }
     
     
     nsresult
    -nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
    -                                          nsIAtom& aProperty,
    +nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode,
    +                                          nsIAtom* aProperty,
                                               const nsAString* aAttribute,
    -                                          const nsAString& aValue)
    +                                          const nsAString* aValue)
     {
    +  MOZ_ASSERT(aNode && aProperty);
    +  MOZ_ASSERT(aValue);
    +
       nsCOMPtr attrAtom = aAttribute ? do_GetAtom(*aAttribute) : nullptr;
     
       // If this is an element that can't be contained in a span, we have to
       // recurse to its children.
    -  if (!TagCanContain(*nsGkAtoms::span, aNode)) {
    -    if (aNode.HasChildren()) {
    -      nsTArray> arrayOfNodes;
    +  if (!TagCanContain(*nsGkAtoms::span, *aNode)) {
    +    if (aNode->HasChildren()) {
    +      nsCOMArray arrayOfNodes;
     
           // Populate the list.
    -      for (nsCOMPtr child = aNode.GetFirstChild();
    +      for (nsIContent* child = aNode->GetFirstChild();
                child;
                child = child->GetNextSibling()) {
             if (IsEditable(child) && !IsEmptyTextNode(this, child)) {
    -          arrayOfNodes.AppendElement(*child);
    +          arrayOfNodes.AppendObject(child);
             }
           }
     
           // Then loop through the list, set the property on each node.
    -      for (auto& node : arrayOfNodes) {
    -        nsresult rv = SetInlinePropertyOnNode(node, aProperty, aAttribute,
    -                                              aValue);
    +      int32_t listCount = arrayOfNodes.Count();
    +      for (int32_t j = 0; j < listCount; ++j) {
    +        nsresult rv = SetInlinePropertyOnNode(arrayOfNodes[j], aProperty,
    +                                              aAttribute, aValue);
             NS_ENSURE_SUCCESS(rv, rv);
           }
         }
    @@ -402,36 +419,36 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
     
       // First check if there's an adjacent sibling we can put our node into.
       nsresult res;
    -  nsCOMPtr previousSibling = GetPriorHTMLSibling(&aNode);
    -  nsCOMPtr nextSibling = GetNextHTMLSibling(&aNode);
    -  if (IsSimpleModifiableNode(previousSibling, &aProperty, aAttribute, &aValue)) {
    -    res = MoveNode(&aNode, previousSibling, -1);
    +  nsCOMPtr previousSibling = GetPriorHTMLSibling(aNode);
    +  nsCOMPtr nextSibling = GetNextHTMLSibling(aNode);
    +  if (IsSimpleModifiableNode(previousSibling, aProperty, aAttribute, aValue)) {
    +    res = MoveNode(aNode, previousSibling, -1);
         NS_ENSURE_SUCCESS(res, res);
    -    if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) {
    +    if (IsSimpleModifiableNode(nextSibling, aProperty, aAttribute, aValue)) {
           res = JoinNodes(*previousSibling, *nextSibling);
           NS_ENSURE_SUCCESS(res, res);
         }
         return NS_OK;
       }
    -  if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) {
    -    res = MoveNode(&aNode, nextSibling, 0);
    +  if (IsSimpleModifiableNode(nextSibling, aProperty, aAttribute, aValue)) {
    +    res = MoveNode(aNode, nextSibling, 0);
         NS_ENSURE_SUCCESS(res, res);
         return NS_OK;
       }
     
    -  // Don't need to do anything if property already set on node
    -  if (mHTMLCSSUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) {
    +  // don't need to do anything if property already set on node
    +  if (mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty, aAttribute)) {
         if (mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(
    -          &aNode, &aProperty, aAttribute, aValue, nsHTMLCSSUtils::eComputed)) {
    +          aNode, aProperty, aAttribute, *aValue, nsHTMLCSSUtils::eComputed)) {
           return NS_OK;
         }
    -  } else if (IsTextPropertySetByContent(&aNode, &aProperty,
    -                                        aAttribute, &aValue)) {
    +  } else if (IsTextPropertySetByContent(aNode, aProperty,
    +                                        aAttribute, aValue)) {
         return NS_OK;
       }
     
       bool useCSS = (IsCSSEnabled() &&
    -                 mHTMLCSSUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) ||
    +                 mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty, aAttribute)) ||
                     // bgcolor is always done using CSS
                     aAttribute->EqualsLiteral("bgcolor");
     
    @@ -439,33 +456,33 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
         nsCOMPtr tmp;
         // We only add style="" to s with no attributes (bug 746515).  If we
         // don't have one, we need to make one.
    -    if (aNode.IsHTMLElement(nsGkAtoms::span) &&
    -        !aNode.AsElement()->GetAttrCount()) {
    -      tmp = aNode.AsElement();
    +    if (aNode->IsHTMLElement(nsGkAtoms::span) &&
    +        !aNode->AsElement()->GetAttrCount()) {
    +      tmp = aNode->AsElement();
         } else {
    -      tmp = InsertContainerAbove(&aNode, nsGkAtoms::span);
    +      tmp = InsertContainerAbove(aNode, nsGkAtoms::span);
           NS_ENSURE_STATE(tmp);
         }
     
         // Add the CSS styles corresponding to the HTML style request
         int32_t count;
         res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(tmp->AsDOMNode(),
    -                                                     &aProperty, aAttribute,
    -                                                     &aValue, &count, false);
    +                                                     aProperty, aAttribute,
    +                                                     aValue, &count, false);
         NS_ENSURE_SUCCESS(res, res);
         return NS_OK;
       }
     
       // is it already the right kind of node, but with wrong attribute?
    -  if (aNode.IsHTMLElement(&aProperty)) {
    +  if (aNode->IsHTMLElement(aProperty)) {
         // Just set the attribute on it.
    -    nsCOMPtr elem = do_QueryInterface(&aNode);
    -    return SetAttribute(elem, *aAttribute, aValue);
    +    nsCOMPtr elem = do_QueryInterface(aNode);
    +    return SetAttribute(elem, *aAttribute, *aValue);
       }
     
       // ok, chuck it in its very own container
    -  nsCOMPtr tmp = InsertContainerAbove(&aNode, &aProperty, attrAtom,
    -                                               &aValue);
    +  nsCOMPtr tmp = InsertContainerAbove(aNode, aProperty, attrAtom,
    +                                               aValue);
       NS_ENSURE_STATE(tmp);
     
       return NS_OK;
    @@ -473,20 +490,42 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
     
     
     nsresult
    -nsHTMLEditor::SetInlinePropertyOnNode(nsIContent& aNode,
    -                                      nsIAtom& aProperty,
    -                                      const nsAString* aAttribute,
    -                                      const nsAString& aValue)
    +nsHTMLEditor::SetInlinePropertyOnNode(nsIDOMNode *aNode,
    +                                      nsIAtom *aProperty,
    +                                      const nsAString *aAttribute,
    +                                      const nsAString *aValue)
     {
    -  nsCOMPtr previousSibling = aNode.GetPreviousSibling(),
    -                       nextSibling = aNode.GetNextSibling();
    -  NS_ENSURE_STATE(aNode.GetParentNode());
    -  OwningNonNull parent = *aNode.GetParentNode();
    +  // Before setting the property, we remove it if it's already set.
    +  // RemoveStyleInside might remove the node we're looking at or some of its
    +  // descendants, however, in which case we want to set the property on
    +  // whatever wound up in its place.  We have to save the original siblings and
    +  // parent to figure this out.
    +  NS_ENSURE_TRUE(aNode && aProperty, NS_ERROR_NULL_POINTER);
     
    -  nsresult res = RemoveStyleInside(aNode.AsDOMNode(), &aProperty, aAttribute);
    +  nsCOMPtr node = do_QueryInterface(aNode);
    +  NS_ENSURE_STATE(node);
    +
    +  return SetInlinePropertyOnNode(node, aProperty, aAttribute, aValue);
    +}
    +
    +nsresult
    +nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode,
    +                                      nsIAtom* aProperty,
    +                                      const nsAString* aAttribute,
    +                                      const nsAString* aValue)
    +{
    +  MOZ_ASSERT(aNode);
    +  MOZ_ASSERT(aProperty);
    +
    +  nsCOMPtr previousSibling = aNode->GetPreviousSibling(),
    +                       nextSibling = aNode->GetNextSibling();
    +  nsCOMPtr parent = aNode->GetParentNode();
    +  NS_ENSURE_STATE(parent);
    +
    +  nsresult res = RemoveStyleInside(aNode->AsDOMNode(), aProperty, aAttribute);
       NS_ENSURE_SUCCESS(res, res);
     
    -  if (aNode.GetParentNode()) {
    +  if (aNode->GetParentNode()) {
         // The node is still where it was
         return SetInlinePropertyOnNodeImpl(aNode, aProperty,
                                            aAttribute, aValue);
    @@ -499,17 +538,20 @@ nsHTMLEditor::SetInlinePropertyOnNode(nsIContent& aNode,
           (nextSibling && nextSibling->GetParentNode() != parent)) {
         return NS_ERROR_UNEXPECTED;
       }
    -  nsTArray> nodesToSet;
    +  nsCOMArray nodesToSet;
       nsCOMPtr cur = previousSibling
         ? previousSibling->GetNextSibling() : parent->GetFirstChild();
    -  for (; cur && cur != nextSibling; cur = cur->GetNextSibling()) {
    +  while (cur && cur != nextSibling) {
         if (IsEditable(cur)) {
    -      nodesToSet.AppendElement(*cur);
    +      nodesToSet.AppendObject(cur);
         }
    +    cur = cur->GetNextSibling();
       }
     
    -  for (auto& node : nodesToSet) {
    -    res = SetInlinePropertyOnNodeImpl(node, aProperty, aAttribute, aValue);
    +  int32_t nodesToSetCount = nodesToSet.Count();
    +  for (int32_t k = 0; k < nodesToSetCount; k++) {
    +    res = SetInlinePropertyOnNodeImpl(nodesToSet[k], aProperty,
    +                                      aAttribute, aValue);
         NS_ENSURE_SUCCESS(res, res);
       }
     
    @@ -1374,8 +1416,8 @@ nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty,
                   // "inverting" the style
                   mHTMLCSSUtils->IsCSSInvertible(*aProperty, aAttribute)) {
                 NS_NAMED_LITERAL_STRING(value, "-moz-editor-invert-value");
    -            SetInlinePropertyOnNode(*node->AsContent(), *aProperty,
    -                                    aAttribute, value);
    +            SetInlinePropertyOnNode(node->AsContent(), aProperty,
    +                                    aAttribute, &value);
               }
             }
           }
    @@ -1391,126 +1433,150 @@ nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty,
     
     NS_IMETHODIMP nsHTMLEditor::IncreaseFontSize()
     {
    -  return RelativeFontChange(FontSize::incr);
    +  return RelativeFontChange(1);
     }
     
     NS_IMETHODIMP nsHTMLEditor::DecreaseFontSize()
     {
    -  return RelativeFontChange(FontSize::decr);
    +  return RelativeFontChange(-1);
     }
     
     nsresult
    -nsHTMLEditor::RelativeFontChange(FontSize aDir)
    +nsHTMLEditor::RelativeFontChange( int32_t aSizeChange)
     {
    +  // Can only change font size by + or - 1
    +  if ( !( (aSizeChange==1) || (aSizeChange==-1) ) )
    +    return NS_ERROR_ILLEGAL_VALUE;
    +  
       ForceCompositionEnd();
     
    -  // Get the selection
    +  // Get the selection 
       nsRefPtr selection = GetSelection();
       NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
    -  // If selection is collapsed, set typing state
    +  // Is the selection collapsed?
    +  // if it's collapsed set typing state
       if (selection->Collapsed()) {
    -    nsIAtom& atom = aDir == FontSize::incr ? *nsGkAtoms::big :
    -                                             *nsGkAtoms::small;
    +    nsCOMPtr atom;
    +    if (aSizeChange == 1) {
    +      atom = nsGkAtoms::big;
    +    } else {
    +      atom = nsGkAtoms::small;
    +    }
     
         // Let's see in what kind of element the selection is
    -    NS_ENSURE_TRUE(selection->RangeCount() &&
    -                   selection->GetRangeAt(0)->GetStartParent(), NS_OK);
    -    OwningNonNull selectedNode =
    -      *selection->GetRangeAt(0)->GetStartParent();
    -    if (IsTextNode(selectedNode)) {
    -      NS_ENSURE_TRUE(selectedNode->GetParentNode(), NS_OK);
    -      selectedNode = *selectedNode->GetParentNode();
    +    int32_t offset;
    +    nsCOMPtr selectedNode;
    +    GetStartNodeAndOffset(selection, getter_AddRefs(selectedNode), &offset);
    +    if (selectedNode && IsTextNode(selectedNode)) {
    +      selectedNode = selectedNode->GetParentNode();
         }
    -    if (!CanContainTag(selectedNode, atom)) {
    +    NS_ENSURE_TRUE(selectedNode, NS_OK);
    +    if (!CanContainTag(*selectedNode, *atom)) {
           return NS_OK;
         }
     
    -    // Manipulating text attributes on a collapsed selection only sets state
    -    // for the next text insertion
    -    mTypeInState->SetProp(&atom, EmptyString(), EmptyString());
    +    // manipulating text attributes on a collapsed selection only sets state for the next text insertion
    +    mTypeInState->SetProp(atom, EmptyString(), EmptyString());
         return NS_OK;
       }
    -
    -  // Wrap with txn batching, rules sniffing, and selection preservation code
    +  
    +  // wrap with txn batching, rules sniffing, and selection preservation code
       nsAutoEditBatch batchIt(this);
    -  nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty,
    -                                 nsIEditor::eNext);
    +  nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty, nsIEditor::eNext);
       nsAutoSelectionReset selectionResetter(selection, this);
       nsAutoTxnsConserveSelection dontSpazMySelection(this);
     
    -  // Loop through the ranges in the selection
    +  // loop thru the ranges in the selection
       uint32_t rangeCount = selection->RangeCount();
       for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
         nsRefPtr range = selection->GetRangeAt(rangeIdx);
     
    -    // Adjust range to include any ancestors with entirely selected children
    +    // adjust range to include any ancestors who's children are entirely selected
         nsresult res = PromoteInlineRange(range);
         NS_ENSURE_SUCCESS(res, res);
    -
    -    // Check for easy case: both range endpoints in same text node
    -    nsCOMPtr startNode = range->GetStartParent();
    -    nsCOMPtr endNode = range->GetEndParent();
    -    if (startNode == endNode && IsTextNode(startNode)) {
    -      res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1,
    -          static_cast(startNode->AsDOMNode()),
    -          range->StartOffset(), range->EndOffset());
    +    
    +    // check for easy case: both range endpoints in same text node
    +    nsCOMPtr startNode, endNode;
    +    res = range->GetStartContainer(getter_AddRefs(startNode));
    +    NS_ENSURE_SUCCESS(res, res);
    +    res = range->GetEndContainer(getter_AddRefs(endNode));
    +    NS_ENSURE_SUCCESS(res, res);
    +    if ((startNode == endNode) && IsTextNode(startNode))
    +    {
    +      int32_t startOffset, endOffset;
    +      range->GetStartOffset(&startOffset);
    +      range->GetEndOffset(&endOffset);
    +      nsCOMPtr nodeAsText = do_QueryInterface(startNode);
    +      res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, startOffset, endOffset);
           NS_ENSURE_SUCCESS(res, res);
    -    } else {
    -      // Not the easy case.  Range not contained in single text node.  There
    -      // are up to three phases here.  There are all the nodes reported by the
    -      // subtree iterator to be processed.  And there are potentially a
    -      // starting textnode and an ending textnode which are only partially
    -      // contained by the range.
    +    }
    +    else
    +    {
    +      // not the easy case.  range not contained in single text node. 
    +      // there are up to three phases here.  There are all the nodes
    +      // reported by the subtree iterator to be processed.  And there
    +      // are potentially a starting textnode and an ending textnode
    +      // which are only partially contained by the range.
    +      
    +      // lets handle the nodes reported by the iterator.  These nodes
    +      // are entirely contained in the selection range.  We build up
    +      // a list of them (since doing operations on the document during
    +      // iteration would perturb the iterator).
     
    -      // Let's handle the nodes reported by the iterator.  These nodes are
    -      // entirely contained in the selection range.  We build up a list of them
    -      // (since doing operations on the document during iteration would perturb
    -      // the iterator).
    +      nsCOMPtr iter =
    +        do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
    +      NS_ENSURE_SUCCESS(res, res);
    +      NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE);
     
    -      OwningNonNull iter = NS_NewContentSubtreeIterator();
    -
    -      // Iterate range and build up array
    +      // iterate range and build up array
           res = iter->Init(range);
           if (NS_SUCCEEDED(res)) {
    -        nsTArray> arrayOfNodes;
    -        for (; !iter->IsDone(); iter->Next()) {
    +        nsCOMArray arrayOfNodes;
    +        while (!iter->IsDone()) {
               NS_ENSURE_TRUE(iter->GetCurrentNode()->IsContent(), NS_ERROR_FAILURE);
    -          OwningNonNull node = *iter->GetCurrentNode()->AsContent();
    +          nsCOMPtr node = iter->GetCurrentNode()->AsContent();
     
               if (IsEditable(node)) {
    -            arrayOfNodes.AppendElement(node);
    +            arrayOfNodes.AppendObject(node);
               }
    -        }
     
    -        // Now that we have the list, do the font size change on each node
    -        for (auto& node : arrayOfNodes) {
    -          res = RelativeFontChangeOnNode(aDir == FontSize::incr ? +1 : -1,
    -                                         node);
    +          iter->Next();
    +        }
    +        
    +        // now that we have the list, do the font size change on each node
    +        int32_t listCount = arrayOfNodes.Count();
    +        for (int32_t j = 0; j < listCount; ++j) {
    +          nsIContent* node = arrayOfNodes[j];
    +          res = RelativeFontChangeOnNode(aSizeChange, node);
               NS_ENSURE_SUCCESS(res, res);
             }
    +        arrayOfNodes.Clear();
           }
    -      // Now check the start and end parents of the range to see if they need
    -      // to be separately handled (they do if they are text nodes, due to how
    -      // the subtree iterator works - it will not have reported them).
    -      if (IsTextNode(startNode) && IsEditable(startNode)) {
    -        res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1,
    -            static_cast(startNode->AsDOMNode()),
    -            range->StartOffset(), startNode->Length());
    +      // now check the start and end parents of the range to see if they need to 
    +      // be separately handled (they do if they are text nodes, due to how the
    +      // subtree iterator works - it will not have reported them).
    +      if (IsTextNode(startNode) && IsEditable(startNode))
    +      {
    +        nsCOMPtr nodeAsText = do_QueryInterface(startNode);
    +        int32_t startOffset;
    +        uint32_t textLen;
    +        range->GetStartOffset(&startOffset);
    +        nodeAsText->GetLength(&textLen);
    +        res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, startOffset, textLen);
             NS_ENSURE_SUCCESS(res, res);
           }
    -      if (IsTextNode(endNode) && IsEditable(endNode)) {
    +      if (IsTextNode(endNode) && IsEditable(endNode))
    +      {
             nsCOMPtr nodeAsText = do_QueryInterface(endNode);
             int32_t endOffset;
             range->GetEndOffset(&endOffset);
    -        res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1,
    -            static_cast(startNode->AsDOMNode()),
    -            0, range->EndOffset());
    +        res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, 0, endOffset);
             NS_ENSURE_SUCCESS(res, res);
           }
         }
       }
    -
    -  return NS_OK;
    +  
    +  return NS_OK;  
     }
     
     nsresult
    diff --git a/editor/libeditor/nsHTMLObjectResizer.cpp b/editor/libeditor/nsHTMLObjectResizer.cpp
    index f0123fe49512..96cca62f4d48 100644
    --- a/editor/libeditor/nsHTMLObjectResizer.cpp
    +++ b/editor/libeditor/nsHTMLObjectResizer.cpp
    @@ -13,6 +13,7 @@
     #include "nsAString.h"
     #include "nsAlgorithm.h"
     #include "nsAutoPtr.h"
    +#include "nsCOMArray.h"
     #include "nsCOMPtr.h"
     #include "nsDebug.h"
     #include "nsEditorUtils.h"
    @@ -498,8 +499,14 @@ nsresult
     nsHTMLEditor::StartResizing(nsIDOMElement *aHandle)
     {
       // First notify the listeners if any
    -  for (auto& listener : mObjectResizeEventListeners) {
    -    listener->OnStartResizing(static_cast(GetAsDOMNode(mResizedObject)));
    +  int32_t listenersCount = objectResizeEventListeners.Count();
    +  if (listenersCount) {
    +    nsCOMPtr listener;
    +    int32_t index;
    +    for (index = 0; index < listenersCount; index++) {
    +      listener = objectResizeEventListeners[index];
    +      listener->OnStartResizing(static_cast(GetAsDOMNode(mResizedObject)));
    +    }
       }
     
       mIsResizing = true;
    @@ -969,10 +976,16 @@ nsHTMLEditor::SetFinalSize(int32_t aX, int32_t aY)
                                            EmptyString());
       }
       // finally notify the listeners if any
    -  for (auto& listener : mObjectResizeEventListeners) {
    -    listener->OnEndResizing(static_cast(GetAsDOMNode(mResizedObject)),
    -                            mResizedObjectWidth, mResizedObjectHeight, width,
    -                            height);
    +  int32_t listenersCount = objectResizeEventListeners.Count();
    +  if (listenersCount) {
    +    nsCOMPtr listener;
    +    int32_t index;
    +    for (index = 0; index < listenersCount; index++) {
    +      listener = objectResizeEventListeners[index];
    +      listener->OnEndResizing(static_cast(GetAsDOMNode(mResizedObject)),
    +                              mResizedObjectWidth, mResizedObjectHeight,
    +                              width, height);
    +    }
       }
     
       // keep track of that size
    @@ -1008,13 +1021,14 @@ NS_IMETHODIMP
     nsHTMLEditor::AddObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener)
     {
       NS_ENSURE_ARG_POINTER(aListener);
    -  if (mObjectResizeEventListeners.Contains(aListener)) {
    +  if (objectResizeEventListeners.Count() &&
    +      objectResizeEventListeners.IndexOf(aListener) != -1) {
         /* listener already registered */
         NS_ASSERTION(false,
                      "trying to register an already registered object resize event listener");
         return NS_OK;
       }
    -  mObjectResizeEventListeners.AppendElement(*aListener);
    +  objectResizeEventListeners.AppendObject(aListener);
       return NS_OK;
     }
     
    @@ -1022,13 +1036,14 @@ NS_IMETHODIMP
     nsHTMLEditor::RemoveObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener)
     {
       NS_ENSURE_ARG_POINTER(aListener);
    -  if (!mObjectResizeEventListeners.Contains(aListener)) {
    +  if (!objectResizeEventListeners.Count() ||
    +      objectResizeEventListeners.IndexOf(aListener) == -1) {
         /* listener was not registered */
         NS_ASSERTION(false,
                      "trying to remove an object resize event listener that was not already registered");
         return NS_OK;
       }
    -  mObjectResizeEventListeners.RemoveElement(aListener);
    +  objectResizeEventListeners.RemoveObject(aListener);
       return NS_OK;
     }
     
    
    From 0a912ae1c79a6ad4650f3994164e3fe9739b2445 Mon Sep 17 00:00:00 2001
    From: Andreas Tolfsen 
    Date: Wed, 8 Apr 2015 19:02:34 +0100
    Subject: [PATCH 154/241] Bug 945729: Replace error number codes with strings
    
    Brings Marionette closer to compliance with the W3C WebDriver standard
    which prescribes that errors should be identified by a string rather
    than a magic number.
    
    r=dburns
    
    --HG--
    extra : rebase_source : 2bdb28f3c05e56b17cc13ceacbf3167dabe89fd0
    extra : source : 2b691bf191db1a83ae489116649602a74e64007a
    ---
     testing/marionette/command.js    |  6 ++---
     testing/marionette/dispatcher.js |  2 +-
     testing/marionette/error.js      | 44 ++++----------------------------
     testing/marionette/listener.js   | 15 ++++++-----
     4 files changed, 17 insertions(+), 50 deletions(-)
    
    diff --git a/testing/marionette/command.js b/testing/marionette/command.js
    index 6b66ccf351bc..4c1477929e31 100644
    --- a/testing/marionette/command.js
    +++ b/testing/marionette/command.js
    @@ -56,7 +56,7 @@ this.Response = function(cmdId, okHandler, respHandler, msg, sanitizer) {
     
       this.data = new Map([
         ["sessionId", msg.sessionId ? msg.sessionId : null],
    -    ["status", msg.status ? msg.status : 0 /* success */],
    +    ["status", msg.status ? msg.status : "success"],
         ["value", msg.value ? msg.value : undefined],
       ]);
     };
    @@ -93,10 +93,10 @@ Response.prototype.send = function() {
     /**
      * @param {(Error|Object)} err
      *     The error to send, either an instance of the Error prototype,
    - *     or an object with the properties "message", "code", and "stack".
    + *     or an object with the properties "message", "status", and "stack".
      */
     Response.prototype.sendError = function(err) {
    -  this.status = "code" in err ? err.code : new UnknownError().code;
    +  this.status = "status" in err ? err.status : new UnknownError().status;
       this.value = error.toJSON(err);
       this.send();
     
    diff --git a/testing/marionette/dispatcher.js b/testing/marionette/dispatcher.js
    index 57edf1f73050..1c5885214ceb 100644
    --- a/testing/marionette/dispatcher.js
    +++ b/testing/marionette/dispatcher.js
    @@ -124,7 +124,7 @@ Dispatcher.prototype.quitApplication = function(msg) {
       if (this.driver.appName != "Firefox") {
         this.sendError({
           "message": "In app initiated quit only supported on Firefox",
    -      "status": 500
    +      "status": "webdriver error",
         }, id);
         return;
       }
    diff --git a/testing/marionette/error.js b/testing/marionette/error.js
    index fd8a7dd9aeb6..347cc6a76789 100644
    --- a/testing/marionette/error.js
    +++ b/testing/marionette/error.js
    @@ -59,26 +59,14 @@ error.toJSON = function(err) {
       return {
         message: err.message,
         stacktrace: err.stack || null,
    -    status: err.code
    +    status: err.status
       };
     };
     
     /**
    - * Determines if the given status code is successful.
    + * Determines if the given status is successful.
      */
    -error.isSuccess = code => code === 0;
    -
    -/**
    - * Old-style errors are objects that has all of the properties
    - * "message", "code", and "stack".
    - *
    - * When listener.js starts forwarding real errors by CPOW
    - * we can remove this.
    - */
    -let isOldStyleError = function(obj) {
    -  return typeof obj == "object" &&
    -    ["message", "code", "stack"].every(c => obj.hasOwnProperty(c));
    -}
    +error.isSuccess = status => status === "success";
     
     /**
      * Checks if obj is an instance of the Error prototype in a safe manner.
    @@ -97,7 +85,7 @@ error.isError = function(val) {
       } else if ("result" in val && val.result in XPCOM_EXCEPTIONS) {
         return true;
       } else {
    -    return Object.getPrototypeOf(val) == "Error" || isOldStyleError(val);
    +    return Object.getPrototypeOf(val) == "Error";
       }
     };
     
    @@ -106,8 +94,7 @@ error.isError = function(val) {
      */
     error.isWebDriverError = function(obj) {
       return error.isError(obj) &&
    -    (("name" in obj && errors.indexOf(obj.name) > 0) ||
    -      isOldStyleError(obj));
    +      ("name" in obj && errors.indexOf(obj.name) > 0);
     };
     
     /**
    @@ -147,7 +134,6 @@ this.WebDriverError = function(msg) {
       this.name = "WebDriverError";
       this.message = msg;
       this.status = "webdriver error";
    -  this.code = 500;  // overridden
     };
     WebDriverError.prototype = Object.create(Error.prototype);
     
    @@ -155,7 +141,6 @@ this.ElementNotAccessibleError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "ElementNotAccessibleError";
       this.status = "element not accessible";
    -  this.code = 56;
     };
     ElementNotAccessibleError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -163,7 +148,6 @@ this.ElementNotVisibleError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "ElementNotVisibleError";
       this.status = "element not visible";
    -  this.code = 11;
     };
     ElementNotVisibleError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -172,7 +156,6 @@ this.FrameSendFailureError = function(frame) {
       WebDriverError.call(this, this.message);
       this.name = "FrameSendFailureError";
       this.status = "frame send failure error";
    -  this.code = 55;
       this.frame = frame;
       this.errMsg = `${this.message} ${this.frame}; frame not responding.`;
     };
    @@ -183,7 +166,6 @@ this.FrameSendNotInitializedError = function(frame) {
       WebDriverError.call(this, this.message);
       this.name = "FrameSendNotInitializedError";
       this.status = "frame send not initialized error";
    -  this.code = 54;
       this.frame = frame;
       this.errMsg = `${this.message} ${this.frame}; frame has closed.`;
     };
    @@ -193,7 +175,6 @@ this.IllegalArgumentError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "IllegalArgumentError";
       this.status = "illegal argument";
    -  this.code = 13;  // unknown error
     };
     IllegalArgumentError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -201,7 +182,6 @@ this.InvalidElementStateError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "InvalidElementStateError";
       this.status = "invalid element state";
    -  this.code = 12;
     };
     InvalidElementStateError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -209,7 +189,6 @@ this.InvalidSelectorError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "InvalidSelectorError";
       this.status = "invalid selector";
    -  this.code = 32;
     };
     InvalidSelectorError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -264,7 +243,6 @@ this.JavaScriptError = function(err, fnName, file, line, script) {
       WebDriverError.call(this, msg);
       this.name = "JavaScriptError";
       this.status = "javascript error";
    -  this.code = 17;
       this.stack = trace;
     };
     JavaScriptError.prototype = Object.create(WebDriverError.prototype);
    @@ -273,7 +251,6 @@ this.NoAlertOpenError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "NoAlertOpenError";
       this.status = "no such alert";
    -  this.code = 27;
     }
     NoAlertOpenError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -281,7 +258,6 @@ this.NoSuchElementError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "NoSuchElementError";
       this.status = "no such element";
    -  this.code = 7;
     };
     NoSuchElementError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -289,7 +265,6 @@ this.NoSuchFrameError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "NoSuchFrameError";
       this.status = "no such frame";
    -  this.code = 8;
     };
     NoSuchFrameError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -297,7 +272,6 @@ this.NoSuchWindowError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "NoSuchWindowError";
       this.status = "no such window";
    -  this.code = 23;
     };
     NoSuchWindowError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -305,7 +279,6 @@ this.ScriptTimeoutError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "ScriptTimeoutError";
       this.status = "script timeout";
    -  this.code = 28;
     };
     ScriptTimeoutError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -313,8 +286,6 @@ this.SessionNotCreatedError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "SessionNotCreatedError";
       this.status = "session not created";
    -  // should be 33 to match Selenium
    -  this.code = 71;
     };
     SessionNotCreatedError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -322,7 +293,6 @@ this.StaleElementReferenceError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "StaleElementReferenceError";
       this.status = "stale element reference";
    -  this.code = 10;
     };
     StaleElementReferenceError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -330,7 +300,6 @@ this.TimeoutError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "TimeoutError";
       this.status = "timeout";
    -  this.code = 21;
     };
     TimeoutError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -346,7 +315,6 @@ this.UnknownCommandError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "UnknownCommandError";
       this.status = "unknown command";
    -  this.code = 9;
     };
     UnknownCommandError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -354,7 +322,6 @@ this.UnknownError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "UnknownError";
       this.status = "unknown error";
    -  this.code = 13;
     };
     UnknownError.prototype = Object.create(WebDriverError.prototype);
     
    @@ -362,6 +329,5 @@ this.UnsupportedOperationError = function(msg) {
       WebDriverError.call(this, msg);
       this.name = "UnsupportedOperationError";
       this.status = "unsupported operation";
    -  this.code = 405;
     };
     UnsupportedOperationError.prototype = Object.create(WebDriverError.prototype);
    diff --git a/testing/marionette/listener.js b/testing/marionette/listener.js
    index 552f2df6094f..2be1b1bebbf9 100644
    --- a/testing/marionette/listener.js
    +++ b/testing/marionette/listener.js
    @@ -522,7 +522,8 @@ function createExecuteContentSandbox(aWindow, timeout) {
           inactivityTimeoutId = null;
         }
       };
    -  sandbox.finish = function sandbox_finish() {
    +
    +  sandbox.finish = function() {
         if (asyncTestRunning) {
           sandbox.asyncComplete(marionette.generate_results(), sandbox.asyncTestCommandId);
         } else {
    @@ -699,11 +700,6 @@ function executeWithCallback(msg, useFinish) {
       }
       sandbox.tag = script;
     
    -  // Error code 28 is scriptTimeout, but spec says execute_async should return 21 (Timeout),
    -  // see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/execute_async.
    -  // However Selenium code returns 28, see
    -  // http://code.google.com/p/selenium/source/browse/trunk/javascript/firefox-driver/js/evaluate.js.
    -  // We'll stay compatible with the Selenium code.
       asyncTestTimeoutId = curFrame.setTimeout(function() {
         sandbox.asyncComplete(new ScriptTimeoutError("timed out"), asyncTestCommandId);
       }, msg.json.timeout);
    @@ -1445,7 +1441,7 @@ function isElementDisplayed(msg) {
      *               the element that will be checked
      *               'propertyName' is the CSS rule that is being requested
      */
    -function getElementValueOfCssProperty(msg){
    +function getElementValueOfCssProperty(msg) {
       let command_id = msg.json.command_id;
       let propertyName = msg.json.propertyName;
       try {
    @@ -1617,6 +1613,11 @@ function clearElement(msg) {
         }
         sendOk(command_id);
       } catch (e) {
    +    // Bug 964738: Newer atoms contain status codes which makes wrapping
    +    // this in an error prototype that has a status property unnecessary
    +    if (e.name == "InvalidElementStateError") {
    +      e = new InvalidElementStateError(e.message);
    +    }
         sendError(e, command_id);
       }
     }
    
    From 02fc2e12be049bd3a768d64e19db119fe9edef08 Mon Sep 17 00:00:00 2001
    From: Kartikaya Gupta 
    Date: Wed, 22 Apr 2015 10:16:27 -0400
    Subject: [PATCH 155/241] Bug 1154478 - Really force-enable the event-regions
     code when APZ is enabled. r=tn
    
    ---
     layout/generic/nsGfxScrollFrame.cpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp
    index 79f33870aeb5..ccb2b30c3f69 100644
    --- a/layout/generic/nsGfxScrollFrame.cpp
    +++ b/layout/generic/nsGfxScrollFrame.cpp
    @@ -3001,7 +3001,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
         if (aBuilder->IsPaintingToWindow() &&
             !mShouldBuildScrollableLayer &&
             shouldBuildLayer &&
    -        gfxPrefs::LayoutEventRegionsEnabled())
    +        aBuilder->IsBuildingLayerEventRegions())
         {
           inactiveRegionItem = new (aBuilder) nsDisplayLayerEventRegions(aBuilder, mScrolledFrame);
           inactiveRegionItem->AddInactiveScrollPort(mScrollPort + aBuilder->ToReferenceFrame(mOuter));
    
    From 57fccccc35411e209c26ecd82b5bb322872d3a7d Mon Sep 17 00:00:00 2001
    From: Kartikaya Gupta 
    Date: Wed, 22 Apr 2015 10:16:33 -0400
    Subject: [PATCH 156/241] Bug 1147038 - Update some tests to pass on desktop
     platforms. r=tn
    
    The test in question sets up an inconsistent state for desktop platforms because
    it intends to simulate what the APZ does, but does it only partially. The APZ
    code would set a CSS viewport (which the test does) but it doesn't set the
    scroll-position-clamping-scroll-port-size which the APZ would always do.
    ---
     layout/reftests/bugs/593243-1.html      | 1 +
     layout/reftests/bugs/593243-2.html      | 1 +
     layout/reftests/bugs/reftest.list       | 4 ++--
     layout/tools/reftest/README.txt         | 8 ++++++++
     layout/tools/reftest/reftest-content.js | 7 +++++++
     5 files changed, 19 insertions(+), 2 deletions(-)
    
    diff --git a/layout/reftests/bugs/593243-1.html b/layout/reftests/bugs/593243-1.html
    index d6db92f97c5f..bb217438a1cd 100644
    --- a/layout/reftests/bugs/593243-1.html
    +++ b/layout/reftests/bugs/593243-1.html
    @@ -1,6 +1,7 @@
     
     
     
    diff --git a/layout/reftests/bugs/593243-2.html b/layout/reftests/bugs/593243-2.html
    index 9b0dcdb619a7..3641d3463452 100644
    --- a/layout/reftests/bugs/593243-2.html
    +++ b/layout/reftests/bugs/593243-2.html
    @@ -1,6 +1,7 @@
     
     
     
    diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list
    index fdffba6edf32..d67325a1591d 100644
    --- a/layout/reftests/bugs/reftest.list
    +++ b/layout/reftests/bugs/reftest.list
    @@ -1593,8 +1593,8 @@ skip-if(B2G||Mulet) fuzzy-if(d2d,52,1051) fuzzy-if(OSX==1008,129,1068) == 586683
     == 589615-1b.html 589615-1-ref.html
     == 589672-1.html 589672-1-ref.html
     != 589682-1.html 589682-1-notref.html
    -skip-if(!asyncPanZoom) == 593243-1.html 593243-1-ref.html # bug 593168
    -skip-if(!asyncPanZoom) == 593243-2.html 593243-2-ref.html # bug 593168
    +skip-if(Android) == 593243-1.html 593243-1-ref.html # bug 593168
    +skip-if(Android) == 593243-2.html 593243-2-ref.html # bug 593168
     == 593544-1.html 593544-1-ref.html
     random-if(Android) == 594333-1.html 594333-1-ref.html
     fuzzy-if(B2G,1,40000) == 594624-1.html 594624-1-ref.html
    diff --git a/layout/tools/reftest/README.txt b/layout/tools/reftest/README.txt
    index 0da7bc85fda0..f68ace1dae3d 100644
    --- a/layout/tools/reftest/README.txt
    +++ b/layout/tools/reftest/README.txt
    @@ -509,6 +509,14 @@ If either of the "reftest-viewport-w" and "reftest-viewport-h" attributes on
     the root element are non-zero, sets the CSS viewport to the given size in
     CSS pixels. This does not affect the size of the snapshot that is taken.
     
    +Setting Scrollport Size: reftest-scrollport-w/h=""
    +=======================================================
    +
    +If either of the "reftest-scrollport-w" and "reftest-scrollport-h" attributes on
    +the root element are non-zero, sets the scroll-position-clamping scroll-port
    +size to the given size in CSS pixels. This does not affect the size of the
    +snapshot that is taken.
    +
     Setting Async Scroll Mode: reftest-async-scroll attribute
     =========================================================
     
    diff --git a/layout/tools/reftest/reftest-content.js b/layout/tools/reftest/reftest-content.js
    index 9151d21d93e2..acf7cf3fff79 100644
    --- a/layout/tools/reftest/reftest-content.js
    +++ b/layout/tools/reftest/reftest-content.js
    @@ -202,6 +202,13 @@ function setupViewport(contentRootElement) {
             windowUtils().setCSSViewport(vw, vh);
         }
     
    +    var sw = attrOrDefault(contentRootElement, "reftest-scrollport-w", 0);
    +    var sh = attrOrDefault(contentRootElement, "reftest-scrollport-h", 0);
    +    if (sw !== 0 || sh !== 0) {
    +        LogInfo("Setting scrollport to ");
    +        windowUtils().setScrollPositionClampingScrollPortSize(sw, sh);
    +    }
    +
         // XXX support resolution when needed
     
         // XXX support viewconfig when needed
    
    From 2046d3ebca65f5e6dedcdf16d95a9fa24e67a663 Mon Sep 17 00:00:00 2001
    From: Tooru Fujisawa 
    Date: Wed, 22 Apr 2015 23:59:01 +0900
    Subject: [PATCH 157/241] Bug 1155985 - Set FieldInto::mType just before
     storing to reserved slot. r=jonco, a=abillings
    
    ---
     js/src/ctypes/CTypes.cpp                   |  8 +++++++-
     js/src/jit-test/tests/ctypes/bug1155985.js | 14 ++++++++++++++
     2 files changed, 21 insertions(+), 1 deletion(-)
     create mode 100644 js/src/jit-test/tests/ctypes/bug1155985.js
    
    diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp
    index 640434db8d6a..2fe4187fbfb0 100644
    --- a/js/src/ctypes/CTypes.cpp
    +++ b/js/src/ctypes/CTypes.cpp
    @@ -4963,7 +4963,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
     
           // Add field name to the hash
           FieldInfo info;
    -      info.mType = fieldType;
    +      info.mType = nullptr; // Value of fields are not yet traceable here.
           info.mIndex = i;
           info.mOffset = fieldOffset;
           ASSERT_OK(fields->add(entryPtr, name, info));
    @@ -4996,6 +4996,12 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
       if (!SizeTojsval(cx, structSize, &sizeVal))
         return false;
     
    +  for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
    +    FieldInfo& field = r.front().value();
    +    MOZ_ASSERT(field.mIndex < fieldRoots.length());
    +    field.mType = &fieldRoots[field.mIndex].toObject();
    +  }
    +
       JS_SetReservedSlot(typeObj, SLOT_FIELDINFO, PRIVATE_TO_JSVAL(fields.release()));
     
       JS_SetReservedSlot(typeObj, SLOT_SIZE, sizeVal);
    diff --git a/js/src/jit-test/tests/ctypes/bug1155985.js b/js/src/jit-test/tests/ctypes/bug1155985.js
    new file mode 100644
    index 000000000000..54c24d4badfe
    --- /dev/null
    +++ b/js/src/jit-test/tests/ctypes/bug1155985.js
    @@ -0,0 +1,14 @@
    +function test() {
    +  for (let i = 0; i < 100; i++) {
    +    let test_struct = ctypes.StructType("test_struct", [{ "x": ctypes.int32_t },
    +                                                        { "bar": ctypes.uint32_t }]);
    +
    +    try {
    +      new test_struct("foo", "x");
    +    } catch (e) {
    +    }
    +  }
    +}
    +
    +if (typeof ctypes === "object")
    +  test();
    
    From ba44c76dcece0291bcdeb7a41a83bb0b9b071d36 Mon Sep 17 00:00:00 2001
    From: Jonathan Kew 
    Date: Fri, 27 Jun 2014 11:22:32 +0100
    Subject: [PATCH 158/241] Bug 1028716 part 1 - Remove the 'auto' value of the
     -moz-orient property, and add 'inline' (new initial value) and 'block'.
     r=dbaron
    
    ---
     layout/forms/nsMeterFrame.cpp          | 3 +--
     layout/forms/nsProgressFrame.cpp       | 3 +--
     layout/style/nsCSSProps.cpp            | 3 ++-
     layout/style/nsRuleNode.cpp            | 2 +-
     layout/style/nsStyleConsts.h           | 7 ++++---
     layout/style/nsStyleStruct.cpp         | 2 +-
     layout/style/test/property_database.js | 4 ++--
     7 files changed, 12 insertions(+), 12 deletions(-)
    
    diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp
    index 6d39d13489c1..629ae987e5df 100644
    --- a/layout/forms/nsMeterFrame.cpp
    +++ b/layout/forms/nsMeterFrame.cpp
    @@ -248,8 +248,7 @@ nsMeterFrame::GetMinISize(nsRenderingContext *aRenderingContext)
     
       nscoord minWidth = fontMet->Font().size; // 1em
     
    -  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_AUTO ||
    -      StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
    +  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
         // The orientation is horizontal
         minWidth *= 5; // 5em
       }
    diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp
    index de572e0ec5a1..759a5ef6ff81 100644
    --- a/layout/forms/nsProgressFrame.cpp
    +++ b/layout/forms/nsProgressFrame.cpp
    @@ -254,8 +254,7 @@ nsProgressFrame::GetMinISize(nsRenderingContext *aRenderingContext)
     
       nscoord minWidth = fontMet->Font().size; // 1em
     
    -  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_AUTO ||
    -      StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
    +  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
         // The orientation is horizontal
         minWidth *= 10; // 10em
       }
    diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp
    index 90e6b8a8fb6d..d9e9e30cfb40 100644
    --- a/layout/style/nsCSSProps.cpp
    +++ b/layout/style/nsCSSProps.cpp
    @@ -1498,9 +1498,10 @@ const KTableValue nsCSSProps::kObjectFitKTable[] = {
     };
     
     const KTableValue nsCSSProps::kOrientKTable[] = {
    +  eCSSKeyword_inline,     NS_STYLE_ORIENT_INLINE,
    +  eCSSKeyword_block,      NS_STYLE_ORIENT_BLOCK,
       eCSSKeyword_horizontal, NS_STYLE_ORIENT_HORIZONTAL,
       eCSSKeyword_vertical,   NS_STYLE_ORIENT_VERTICAL,
    -  eCSSKeyword_auto,       NS_STYLE_ORIENT_AUTO,
       eCSSKeyword_UNKNOWN,    -1
     };
     
    diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
    index 2510be1e500c..407fc93edd64 100644
    --- a/layout/style/nsRuleNode.cpp
    +++ b/layout/style/nsRuleNode.cpp
    @@ -5883,7 +5883,7 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
                   display->mOrient, canStoreInRuleTree,
                   SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
                   parentDisplay->mOrient,
    -              NS_STYLE_ORIENT_AUTO, 0, 0, 0, 0);
    +              NS_STYLE_ORIENT_INLINE, 0, 0, 0, 0);
     
       COMPUTE_END_RESET(Display, display)
     }
    diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
    index 460e76d427f0..59f1fcf9f6e3 100644
    --- a/layout/style/nsStyleConsts.h
    +++ b/layout/style/nsStyleConsts.h
    @@ -147,9 +147,10 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
     #define NS_STYLE_BOX_ORIENT_VERTICAL   1
     
     // orient
    -#define NS_STYLE_ORIENT_HORIZONTAL 0
    -#define NS_STYLE_ORIENT_VERTICAL   1
    -#define NS_STYLE_ORIENT_AUTO       2
    +#define NS_STYLE_ORIENT_INLINE     0
    +#define NS_STYLE_ORIENT_BLOCK      1
    +#define NS_STYLE_ORIENT_HORIZONTAL 2
    +#define NS_STYLE_ORIENT_VERTICAL   3
     
     #define NS_RADIUS_FARTHEST_SIDE 0
     #define NS_RADIUS_CLOSEST_SIDE  1
    diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
    index afc3c2d716ff..da19ec1fc1e0 100644
    --- a/layout/style/nsStyleStruct.cpp
    +++ b/layout/style/nsStyleStruct.cpp
    @@ -2602,7 +2602,7 @@ nsStyleDisplay::nsStyleDisplay()
       mChildPerspective.SetNoneValue();
       mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE;
       mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT;
    -  mOrient = NS_STYLE_ORIENT_AUTO;
    +  mOrient = NS_STYLE_ORIENT_INLINE;
       mMixBlendMode = NS_STYLE_BLEND_NORMAL;
       mIsolation = NS_STYLE_ISOLATION_AUTO;
       mTouchAction = NS_STYLE_TOUCH_ACTION_AUTO;
    diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
    index 72bd491a9ca5..f076849907ab 100644
    --- a/layout/style/test/property_database.js
    +++ b/layout/style/test/property_database.js
    @@ -3021,8 +3021,8 @@ var gCSSProperties = {
         domProp: "MozOrient",
         inherited: false,
         type: CSS_TYPE_LONGHAND,
    -    initial_values: [ "auto" ],
    -    other_values: [ "horizontal", "vertical" ],
    +    initial_values: [ "inline" ],
    +    other_values: [ "horizontal", "vertical", "block" ],
         invalid_values: [ "none" ]
       },
       "orphans": {
    
    From b68965af5af4dfb2b67e922d56226f1ef3015b50 Mon Sep 17 00:00:00 2001
    From: Jonathan Kew 
    Date: Fri, 27 Jun 2014 11:25:11 +0100
    Subject: [PATCH 159/241] Bug 1028716 part 2 - Handle the new orient values in
      and  layout. r=smontagu
    
    ---
     layout/forms/nsMeterFrame.cpp       | 16 ++++++++--------
     layout/forms/nsProgressFrame.cpp    | 16 ++++++++--------
     layout/generic/nsContainerFrame.cpp | 18 ++++++++++++++++++
     layout/generic/nsContainerFrame.h   |  6 ++++++
     4 files changed, 40 insertions(+), 16 deletions(-)
    
    diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp
    index 629ae987e5df..553863fd9868 100644
    --- a/layout/forms/nsMeterFrame.cpp
    +++ b/layout/forms/nsMeterFrame.cpp
    @@ -135,7 +135,7 @@ nsMeterFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
                                  const nsHTMLReflowState& aReflowState,
                                  nsReflowStatus&          aStatus)
     {
    -  bool vertical = StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
    +  bool vertical = ResolvedOrientationIsVertical();
       WritingMode wm = aBarFrame->GetWritingMode();
       LogicalSize availSize = aReflowState.ComputedSize(wm);
       availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
    @@ -158,7 +158,7 @@ nsMeterFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
     
       size = NSToCoordRound(size * position);
     
    -  if (!vertical && StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
    +  if (!vertical && (wm.IsVertical() ? wm.IsVerticalRL() : !wm.IsBidiLTR())) {
         xoffset += aReflowState.ComputedWidth() - size;
       }
     
    @@ -230,7 +230,7 @@ nsMeterFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
       LogicalSize autoSize(wm);
       autoSize.BSize(wm) = autoSize.ISize(wm) = fontMet->Font().size; // 1em
     
    -  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL) {
    +  if (ResolvedOrientationIsVertical()) {
         autoSize.Height(wm) *= 5; // 5em
       } else {
         autoSize.Width(wm) *= 5; // 5em
    @@ -246,14 +246,14 @@ nsMeterFrame::GetMinISize(nsRenderingContext *aRenderingContext)
       NS_ENSURE_SUCCESS(
           nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)), 0);
     
    -  nscoord minWidth = fontMet->Font().size; // 1em
    +  nscoord minISize = fontMet->Font().size; // 1em
     
    -  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
    -    // The orientation is horizontal
    -    minWidth *= 5; // 5em
    +  if (ResolvedOrientationIsVertical() == GetWritingMode().IsVertical()) {
    +    // The orientation is inline
    +    minISize *= 5; // 5em
       }
     
    -  return minWidth;
    +  return minISize;
     }
     
     nscoord
    diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp
    index 759a5ef6ff81..86b030707e62 100644
    --- a/layout/forms/nsProgressFrame.cpp
    +++ b/layout/forms/nsProgressFrame.cpp
    @@ -139,7 +139,7 @@ nsProgressFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
                                     const nsHTMLReflowState& aReflowState,
                                     nsReflowStatus&          aStatus)
     {
    -  bool vertical = StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
    +  bool vertical = ResolvedOrientationIsVertical();
       WritingMode wm = aBarFrame->GetWritingMode();
       LogicalSize availSize = aReflowState.ComputedSize(wm);
       availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
    @@ -158,7 +158,7 @@ nsProgressFrame::ReflowBarFrame(nsIFrame*                aBarFrame,
         size *= position;
       }
     
    -  if (!vertical && StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
    +  if (!vertical && (wm.IsVertical() ? wm.IsVerticalRL() : !wm.IsBidiLTR())) {
         xoffset += aReflowState.ComputedWidth() - size;
       }
     
    @@ -236,7 +236,7 @@ nsProgressFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
         NSToCoordRound(StyleFont()->mFont.size *
                        nsLayoutUtils::FontSizeInflationFor(this)); // 1em
     
    -  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL) {
    +  if (ResolvedOrientationIsVertical()) {
         autoSize.Height(wm) *= 10; // 10em
       } else {
         autoSize.Width(wm) *= 10; // 10em
    @@ -252,14 +252,14 @@ nsProgressFrame::GetMinISize(nsRenderingContext *aRenderingContext)
       NS_ENSURE_SUCCESS(
           nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)), 0);
     
    -  nscoord minWidth = fontMet->Font().size; // 1em
    +  nscoord minISize = fontMet->Font().size; // 1em
     
    -  if (StyleDisplay()->mOrient == NS_STYLE_ORIENT_HORIZONTAL) {
    -    // The orientation is horizontal
    -    minWidth *= 10; // 10em
    +  if (ResolvedOrientationIsVertical() == GetWritingMode().IsVertical()) {
    +    // The orientation is inline
    +    minISize *= 10; // 10em
       }
     
    -  return minWidth;
    +  return minISize;
     }
     
     nscoord
    diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
    index 912f05b94603..dd8d1d35c112 100644
    --- a/layout/generic/nsContainerFrame.cpp
    +++ b/layout/generic/nsContainerFrame.cpp
    @@ -1679,6 +1679,24 @@ nsContainerFrame::PullNextInFlowChild(ContinuationTraversingState& aState)
       return frame;
     }
     
    +bool
    +nsContainerFrame::ResolvedOrientationIsVertical()
    +{
    +  uint8_t orient = StyleDisplay()->mOrient;
    +  switch (orient) {
    +    case NS_STYLE_ORIENT_HORIZONTAL:
    +      return false;
    +    case NS_STYLE_ORIENT_VERTICAL:
    +      return true;
    +    case NS_STYLE_ORIENT_INLINE:
    +      return GetWritingMode().IsVertical();
    +    case NS_STYLE_ORIENT_BLOCK:
    +      return !GetWritingMode().IsVertical();
    +  }
    +  NS_NOTREACHED("unexpected -moz-orient value");
    +  return false;
    +}
    +
     nsOverflowContinuationTracker::nsOverflowContinuationTracker(nsContainerFrame* aFrame,
                                                                  bool              aWalkOOFFrames,
                                                                  bool              aSkipOverflowContainerChildren)
    diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h
    index a638c56ab09c..59bd5bb5335b 100644
    --- a/layout/generic/nsContainerFrame.h
    +++ b/layout/generic/nsContainerFrame.h
    @@ -613,6 +613,12 @@ protected:
     
       // ==========================================================================
     
    +  // Helper used by Progress and Meter frames. Returns true if the bar should
    +  // be rendered vertically, based on writing-mode and -moz-orient properties.
    +  bool ResolvedOrientationIsVertical();
    +
    +  // ==========================================================================
    +
       nsFrameList mFrames;
     };
     
    
    From 3ffbad09c7b8f88cfd15a2df2f5b7135e4225b40 Mon Sep 17 00:00:00 2001
    From: Jonathan Kew 
    Date: Tue, 24 Jun 2014 19:26:13 +0100
    Subject: [PATCH 160/241] Bug 1028716 part 3 - Widget updates to support the
     extended set of -moz-orient values. r=roc
    
    ---
     widget/cocoa/nsNativeThemeCocoa.mm |  2 +-
     widget/gtk/nsNativeThemeGTK.cpp    |  2 +-
     widget/nsNativeTheme.cpp           | 19 ++++++++++++++++---
     3 files changed, 18 insertions(+), 5 deletions(-)
    
    diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm
    index 9378eb5e4fb8..e7d5d3abcf3b 100644
    --- a/widget/cocoa/nsNativeThemeCocoa.mm
    +++ b/widget/cocoa/nsNativeThemeCocoa.mm
    @@ -2672,7 +2672,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
             }
           }
           DrawProgress(cgContext, macRect, IsIndeterminateProgress(aFrame, eventState),
    -                   aFrame->StyleDisplay()->mOrient != NS_STYLE_ORIENT_VERTICAL,
    +                   !IsVerticalProgress(aFrame),
                        value, maxValue, aFrame);
           break;
         }
    diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp
    index a3595009cc22..b77f08823d6c 100644
    --- a/widget/gtk/nsNativeThemeGTK.cpp
    +++ b/widget/gtk/nsNativeThemeGTK.cpp
    @@ -597,7 +597,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
           EventStates eventStates = GetContentState(stateFrame, aWidgetType);
     
           aGtkWidgetType = IsIndeterminateProgress(stateFrame, eventStates)
    -                         ? (stateFrame->StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL)
    +                         ? IsVerticalProgress(stateFrame)
                                ? MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE
                                : MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE
                              : MOZ_GTK_PROGRESS_CHUNK;
    diff --git a/widget/nsNativeTheme.cpp b/widget/nsNativeTheme.cpp
    index e691e28a3727..dc133a45c9a1 100644
    --- a/widget/nsNativeTheme.cpp
    +++ b/widget/nsNativeTheme.cpp
    @@ -557,15 +557,28 @@ nsNativeTheme::IsIndeterminateProgress(nsIFrame* aFrame,
     bool
     nsNativeTheme::IsVerticalProgress(nsIFrame* aFrame)
     {
    -  return aFrame &&
    -         aFrame->StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
    +  if (!aFrame) {
    +    return false;
    +  }
    +  return IsVerticalMeter(aFrame);
     }
     
     bool
     nsNativeTheme::IsVerticalMeter(nsIFrame* aFrame)
     {
       NS_PRECONDITION(aFrame, "You have to pass a non-null aFrame");
    -  return aFrame->StyleDisplay()->mOrient == NS_STYLE_ORIENT_VERTICAL;
    +  switch (aFrame->StyleDisplay()->mOrient) {
    +    case NS_STYLE_ORIENT_HORIZONTAL:
    +      return false;
    +    case NS_STYLE_ORIENT_VERTICAL:
    +      return true;
    +    case NS_STYLE_ORIENT_INLINE:
    +      return aFrame->GetWritingMode().IsVertical();
    +    case NS_STYLE_ORIENT_BLOCK:
    +      return !aFrame->GetWritingMode().IsVertical();
    +  }
    +  NS_NOTREACHED("unexpected -moz-orient value");
    +  return false;
     }
     
     // menupopup:
    
    From 4ae9c9ef1793d2bef4f77ddba75ca16a5a3bfbc5 Mon Sep 17 00:00:00 2001
    From: Mark Banner 
    Date: Wed, 22 Apr 2015 08:51:46 +0100
    Subject: [PATCH 161/241] Bug 1132222 - Add more metrics reporting to the Loop
     standalone UI. r=dmose
    
    ---
     .../loop/content/shared/js/actions.js         |  11 +
     .../loop/standalone/content/index.html        |   2 +
     .../content/js/standaloneMetricsStore.js      | 210 ++++++++++++++++++
     .../content/js/standaloneRoomViews.js         |  54 ++++-
     .../content/js/standaloneRoomViews.jsx        |  54 ++++-
     .../loop/standalone/content/js/webapp.js      |  10 +-
     .../loop/standalone/content/js/webapp.jsx     |  10 +-
     .../loop/test/standalone/index.html           |   2 +
     .../standalone/standaloneMetricsStore_test.js | 142 ++++++++++++
     .../standalone/standaloneRoomViews_test.js    |  47 +++-
     10 files changed, 529 insertions(+), 13 deletions(-)
     create mode 100644 browser/components/loop/standalone/content/js/standaloneMetricsStore.js
     create mode 100644 browser/components/loop/test/standalone/standaloneMetricsStore_test.js
    
    diff --git a/browser/components/loop/content/shared/js/actions.js b/browser/components/loop/content/shared/js/actions.js
    index 434c1e72d0b2..24df6b935093 100644
    --- a/browser/components/loop/content/shared/js/actions.js
    +++ b/browser/components/loop/content/shared/js/actions.js
    @@ -468,6 +468,17 @@ loop.shared.actions = (function() {
         LeaveRoom: Action.define("leaveRoom", {
         }),
     
    +    /**
    +     * Used to record a link click for metrics purposes.
    +     */
    +    RecordClick: Action.define("recordClick", {
    +      // Note: for ToS and Privacy links, this should be the link, for
    +      // other links this should be a generic description so that we don't
    +      // record what users are clicking, just the information about the fact
    +      // they clicked the link in that spot (e.g. "Shared URL").
    +      linkInfo: String
    +    }),
    +
         /**
          * Requires detailed information on sad feedback.
          */
    diff --git a/browser/components/loop/standalone/content/index.html b/browser/components/loop/standalone/content/index.html
    index 10f309ddfe52..2dd9cdc27c2c 100644
    --- a/browser/components/loop/standalone/content/index.html
    +++ b/browser/components/loop/standalone/content/index.html
    @@ -29,6 +29,7 @@
             })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
     
             ga('create', 'UA-36116321-15', 'auto');
    +        ga('set', 'anonymizeIp', true);
             ga('send', 'pageview');
           }
         
    @@ -129,6 +130,7 @@
         
         
         
    +    
         
     
         
       
       
    +  
       
       
       
       
       
       
    +  
       
       
       
    
    From f1d26a537d8630a705ec25d83ff4c4affe6af252 Mon Sep 17 00:00:00 2001
    From: Andreas Pehrson 
    Date: Wed, 22 Apr 2015 11:59:43 +0800
    Subject: [PATCH 190/241] Bug 1155089 - Part 3: Test replacing with WebAudio
     track in track_peerConnection_replaceTrack.html. r=jib
    
    --HG--
    extra : rebase_source : df2ebd47ca3cf0854e8663623d5de18c2e730d3d
    ---
     .../test_peerConnection_replaceTrack.html     | 159 +++++++++++++-----
     1 file changed, 115 insertions(+), 44 deletions(-)
    
    diff --git a/dom/media/tests/mochitest/test_peerConnection_replaceTrack.html b/dom/media/tests/mochitest/test_peerConnection_replaceTrack.html
    index c535ead3e557..e8c44bc14758 100644
    --- a/dom/media/tests/mochitest/test_peerConnection_replaceTrack.html
    +++ b/dom/media/tests/mochitest/test_peerConnection_replaceTrack.html
    @@ -8,62 +8,133 @@
     
    +
    +
    diff --git a/testing/web-platform/tests/encoding/api-replacement-encodings.html b/testing/web-platform/tests/encoding/api-replacement-encodings.html
    index d0accbc8de81..ef0cdb88ec00 100644
    --- a/testing/web-platform/tests/encoding/api-replacement-encodings.html
    +++ b/testing/web-platform/tests/encoding/api-replacement-encodings.html
    @@ -6,8 +6,8 @@
     
    diff --git a/testing/web-platform/tests/websockets/interfaces/WebSocket/url/003.html b/testing/web-platform/tests/websockets/interfaces/WebSocket/url/003.html
    index 12118937123b..3f0a2a289403 100644
    --- a/testing/web-platform/tests/websockets/interfaces/WebSocket/url/003.html
    +++ b/testing/web-platform/tests/websockets/interfaces/WebSocket/url/003.html
    @@ -8,6 +8,8 @@
     test(function() {
       var ws = new WebSocket(SCHEME_DOMAIN_PORT+'/');
       delete ws.url;
    -  assert_equals(ws.url, SCHEME_DOMAIN_PORT+'/');
    +  assert_equals(ws.url, SCHEME_DOMAIN_PORT+'/', 'delete ws.url');
    +  delete WebSocket.prototype.url;
    +  assert_equals(ws.url, undefined, 'delete WebSocket.prototype.url');
     });
     
    diff --git a/testing/web-platform/tests/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js b/testing/web-platform/tests/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js
    index 190452737938..954c46c07eca 100644
    --- a/testing/web-platform/tests/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js
    +++ b/testing/web-platform/tests/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js
    @@ -1,9 +1,9 @@
     importScripts("/resources/testharness.js");
     
    -test(function() {
    +test(function(t) {
         var i = 0;
         addEventListener("message", function listener(evt) {
    -        this.step(function() {
    +        t.step(function() {
                 ++i;
                 removeEventListener("message", listener, true);
             });
    diff --git a/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html b/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html
    index 79adef16014b..4b5af71d516b 100644
    --- a/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html
    +++ b/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html
    @@ -21,7 +21,7 @@ async_test(function() {
         assert_equals(typeof e.message, 'string', 'typeof e.message');
         assert_equals(e.filename, document.URL+'#', 'e.filename');
         assert_equals(typeof e.lineno, 'number', 'typeof e.lineno');
    -    assert_equals(typeof e.column, 'number', 'typeof e.column');
    +    assert_equals(typeof e.colno, 'number', 'typeof e.column');
         e.preventDefault(); // "handled"
         this.done();
       });
    @@ -29,4 +29,4 @@ async_test(function() {
     
     
    \ No newline at end of file
    +//-->
    diff --git a/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html b/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html
    index 96ee06dd207b..f6107ada433f 100644
    --- a/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html
    +++ b/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html
    @@ -21,7 +21,7 @@ async_test(function() {
         assert_equals(typeof e.message, 'string', 'typeof e.message');
         assert_equals(e.filename, document.URL+'#', 'e.filename');
         assert_equals(typeof e.lineno, 'number', 'typeof e.lineno');
    -    assert_equals(typeof e.column, 'number', 'typeof e.column');
    +    assert_equals(typeof e.colno, 'number', 'typeof e.column');
         e.preventDefault(); // "handled"
         this.done();
       });
    @@ -29,4 +29,4 @@ async_test(function() {
     
     
    \ No newline at end of file
    +//-->
    diff --git a/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html b/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html
    index 006321675b6a..b6a61e2355c0 100644
    --- a/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html
    +++ b/testing/web-platform/tests/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html
    @@ -16,15 +16,11 @@ setup({
     });
     async_test(function() {
       var worker = new Worker('#');
    -  var timeout = setTimeout(this.step_func(function() {
    -    assert_unreached();
    -  }, 500));
       window.onerror = this.step_func(function(a, b, c, d) {
    -    assert_true(typeof a, 'string', 'first argument');
    +    assert_equals(typeof a, 'string', 'first argument');
         assert_equals(b, document.URL+'#', 'second argument');
         assert_equals(typeof c, 'number', 'third argument');
         assert_equals(typeof d, 'number', 'fourth argument');
    -    clearTimeout(timeout);
         this.done();
         return true; // "handled"
       });
    
    From 1e1bec5c20a00d9b2a7bfe79e3fd2d07864ed048 Mon Sep 17 00:00:00 2001
    From: James Graham 
    Date: Wed, 22 Apr 2015 09:09:00 +0100
    Subject: [PATCH 202/241] Bug 1157218 - Update to latest wptrunner, a=testonly
    
    ---
     .../harness/wptrunner/browsers/servo.py       |  9 +++----
     .../wptrunner/executors/executorservo.py      | 26 ++++++++++++-------
     .../harness/wptrunner/executors/process.py    |  3 ++-
     .../harness/wptrunner/manifestinclude.py      |  2 +-
     .../harness/wptrunner/wptcommandline.py       |  3 ++-
     5 files changed, 24 insertions(+), 19 deletions(-)
    
    diff --git a/testing/web-platform/harness/wptrunner/browsers/servo.py b/testing/web-platform/harness/wptrunner/browsers/servo.py
    index cbc21e607c78..11499b66b9f4 100644
    --- a/testing/web-platform/harness/wptrunner/browsers/servo.py
    +++ b/testing/web-platform/harness/wptrunner/browsers/servo.py
    @@ -26,8 +26,7 @@ def check_args(**kwargs):
     
     def browser_kwargs(**kwargs):
         return {"binary": kwargs["binary"],
    -            "debug_info": kwargs["debug_info"],
    -            "interactive": kwargs["interactive"]}
    +            "debug_info": kwargs["debug_info"]}
     
     
     def executor_kwargs(test_type, server_config, cache_manager, **kwargs):
    @@ -44,13 +43,11 @@ def env_options():
     
     
     class ServoBrowser(NullBrowser):
    -    def __init__(self, logger, binary, debug_info=None, interactive=False):
    +    def __init__(self, logger, binary, debug_info=None):
             NullBrowser.__init__(self, logger)
             self.binary = binary
             self.debug_info = debug_info
    -        self.interactive = interactive
     
         def executor_browser(self):
             return ExecutorBrowser, {"binary": self.binary,
    -                                 "debug_info": self.debug_info,
    -                                 "interactive": self.interactive}
    +                                 "debug_info": self.debug_info}
    diff --git a/testing/web-platform/harness/wptrunner/executors/executorservo.py b/testing/web-platform/harness/wptrunner/executors/executorservo.py
    index e7b2cd415bc5..ef2bffdb2b32 100644
    --- a/testing/web-platform/harness/wptrunner/executors/executorservo.py
    +++ b/testing/web-platform/harness/wptrunner/executors/executorservo.py
    @@ -21,7 +21,7 @@ from .base import (ExecutorException,
                        testharness_result_converter,
                        reftest_result_converter)
     from .process import ProcessTestExecutor
    -from ..executors.base import browser_command
    +from ..browsers.base import browser_command
     
     hosts_text = """127.0.0.1 web-platform.test
     127.0.0.1 www.web-platform.test
    @@ -75,29 +75,35 @@ class ServoTestharnessExecutor(ProcessTestExecutor):
             env = os.environ.copy()
             env["HOST_FILE"] = self.hosts_path
     
    -        self.proc = ProcessHandler(self.command,
    -                                   processOutputLine=[self.on_output],
    -                                   onFinish=self.on_finish,
    -                                   env=env)
    +
    +
    +        if not self.interactive:
    +            self.proc = ProcessHandler(self.command,
    +                                       processOutputLine=[self.on_output],
    +                                       onFinish=self.on_finish,
    +                                       env=env,
    +                                       storeOutput=False)
    +            self.proc.run()
    +        else:
    +            self.proc = subprocess.Popen(self.command, env=env)
     
             try:
    -            self.proc.run()
    -
                 timeout = test.timeout * self.timeout_multiplier
     
                 # Now wait to get the output we expect, or until we reach the timeout
    -            if self.debug_info is None and not self.pause_after_test:
    +            if not self.interactive and not self.pause_after_test:
                     wait_timeout = timeout + 5
    +                self.result_flag.wait(wait_timeout)
                 else:
                     wait_timeout = None
    -            self.result_flag.wait(wait_timeout)
    +                self.proc.wait()
     
                 proc_is_running = True
                 if self.result_flag.is_set() and self.result_data is not None:
                     self.result_data["test"] = test.url
                     result = self.convert_result(test, self.result_data)
                 else:
    -                if self.proc.proc.poll() is not None:
    +                if self.proc.poll() is not None:
                         result = (test.result_cls("CRASH", None), [])
                         proc_is_running = False
                     else:
    diff --git a/testing/web-platform/harness/wptrunner/executors/process.py b/testing/web-platform/harness/wptrunner/executors/process.py
    index bff8b5bfb536..45f33ab2c75c 100644
    --- a/testing/web-platform/harness/wptrunner/executors/process.py
    +++ b/testing/web-platform/harness/wptrunner/executors/process.py
    @@ -9,7 +9,8 @@ class ProcessTestExecutor(TestExecutor):
         def __init__(self, *args, **kwargs):
             TestExecutor.__init__(self, *args, **kwargs)
             self.binary = self.browser.binary
    -        self.interactive = self.browser.interactive
    +        self.interactive = (False if self.debug_info is None
    +                            else self.debug_info.interactive)
     
         def setup(self, runner):
             self.runner = runner
    diff --git a/testing/web-platform/harness/wptrunner/manifestinclude.py b/testing/web-platform/harness/wptrunner/manifestinclude.py
    index 8a11605169ca..a3cda5a1c990 100644
    --- a/testing/web-platform/harness/wptrunner/manifestinclude.py
    +++ b/testing/web-platform/harness/wptrunner/manifestinclude.py
    @@ -95,7 +95,7 @@ class IncludeManifest(ManifestItem):
                 for manifest, data in test_manifests.iteritems():
                     rel_path = os.path.relpath(maybe_path, data["tests_path"])
                     if ".." not in rel_path.split(os.sep):
    -                    url = "/" + rel_path.replace(os.path.sep, "/") + variant
    +                    url = data["url_base"] + rel_path.replace(os.path.sep, "/") + variant
                         break
     
             assert direction in ("include", "exclude")
    diff --git a/testing/web-platform/harness/wptrunner/wptcommandline.py b/testing/web-platform/harness/wptrunner/wptcommandline.py
    index 18a5367434d6..bf00901ab371 100644
    --- a/testing/web-platform/harness/wptrunner/wptcommandline.py
    +++ b/testing/web-platform/harness/wptrunner/wptcommandline.py
    @@ -276,7 +276,8 @@ def check_args(kwargs):
             debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                     kwargs["debugger_args"])
             if debug_info.interactive:
    -            require_arg(kwargs, "processes", lambda x: x == 1)
    +            if kwargs["processes"] != 1:
    +                kwargs["processes"] = 1
                 kwargs["no_capture_stdio"] = True
             kwargs["debug_info"] = debug_info
         else:
    
    From ce84bb0e7e20fcfe83eb7a6e568057014f1fdfa8 Mon Sep 17 00:00:00 2001
    From: James Graham 
    Date: Wed, 22 Apr 2015 13:41:17 +0100
    Subject: [PATCH 203/241] Bug 1157218 - Update web-platform-tests expected data
     to revision 20aef05e164be1ccbbd8f66192f01e778b5e5c18, a=testonly
    
    ---
     .../meta/html/dom/interfaces.html.ini         | 360 ------------------
     .../relevant-mutations.html.ini               |  31 +-
     .../web-platform/meta/url/a-element.html.ini  |   5 +-
     .../web-platform/meta/url/a-element.xhtml.ini |   5 +-
     .../WebSocket/readyState/003.html.ini         |   5 -
     .../WorkerLocation_hash_encoding.htm.ini      |   1 +
     .../meta/workers/interfaces.worker.js.ini     |   9 -
     .../EventTarget.worker.js.ini                 |   6 -
     .../onerror/exception-in-onerror.html.ini     |   5 -
     .../onerror/not-handled.html.ini              |   5 -
     .../propagate-to-window-onerror.html.ini      |   5 -
     11 files changed, 23 insertions(+), 414 deletions(-)
     delete mode 100644 testing/web-platform/meta/websockets/interfaces/WebSocket/readyState/003.html.ini
     delete mode 100644 testing/web-platform/meta/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js.ini
     delete mode 100644 testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html.ini
     delete mode 100644 testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html.ini
     delete mode 100644 testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html.ini
    
    diff --git a/testing/web-platform/meta/html/dom/interfaces.html.ini b/testing/web-platform/meta/html/dom/interfaces.html.ini
    index 9fe7d423fd6e..ff559aa508b7 100644
    --- a/testing/web-platform/meta/html/dom/interfaces.html.ini
    +++ b/testing/web-platform/meta/html/dom/interfaces.html.ini
    @@ -2277,402 +2277,48 @@
       [Window interface: window must inherit property "self" with the proper type (1)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "name" with the proper type (3)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "history" with the proper type (5)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "locationbar" with the proper type (6)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "menubar" with the proper type (7)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "personalbar" with the proper type (8)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "scrollbars" with the proper type (9)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "statusbar" with the proper type (10)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "toolbar" with the proper type (11)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "status" with the proper type (12)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "close" with the proper type (13)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "closed" with the proper type (14)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "stop" with the proper type (15)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "focus" with the proper type (16)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "blur" with the proper type (17)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "frames" with the proper type (18)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "length" with the proper type (19)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "opener" with the proper type (21)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "parent" with the proper type (22)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "frameElement" with the proper type (23)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "open" with the proper type (24)]
    -    expected: FAIL
    -
    -  [Window interface: calling open(DOMString,DOMString,DOMString,boolean) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "navigator" with the proper type (27)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "external" with the proper type (28)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "applicationCache" with the proper type (29)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "alert" with the proper type (30)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "confirm" with the proper type (31)]
    -    expected: FAIL
    -
    -  [Window interface: calling confirm(DOMString) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "prompt" with the proper type (32)]
    -    expected: FAIL
    -
    -  [Window interface: calling prompt(DOMString,DOMString) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "print" with the proper type (33)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "showModalDialog" with the proper type (34)]
    -    expected: FAIL
    -
    -  [Window interface: calling showModalDialog(DOMString,any) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "postMessage" with the proper type (35)]
    -    expected: FAIL
    -
    -  [Window interface: calling postMessage(any,DOMString,[object Object\]) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "captureEvents" with the proper type (36)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "releaseEvents" with the proper type (37)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onabort" with the proper type (38)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "onautocomplete" with the proper type (39)]
         expected: FAIL
     
       [Window interface: window must inherit property "onautocompleteerror" with the proper type (40)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "onblur" with the proper type (41)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "oncancel" with the proper type (42)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "oncanplay" with the proper type (43)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "oncanplaythrough" with the proper type (44)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onchange" with the proper type (45)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onclick" with the proper type (46)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "onclose" with the proper type (47)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "oncontextmenu" with the proper type (48)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "oncuechange" with the proper type (49)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "ondblclick" with the proper type (50)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ondrag" with the proper type (51)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ondragend" with the proper type (52)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ondragenter" with the proper type (53)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "ondragexit" with the proper type (54)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "ondragleave" with the proper type (55)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ondragover" with the proper type (56)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ondragstart" with the proper type (57)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ondrop" with the proper type (58)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ondurationchange" with the proper type (59)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onemptied" with the proper type (60)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onended" with the proper type (61)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onerror" with the proper type (62)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onfocus" with the proper type (63)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "oninput" with the proper type (64)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "oninvalid" with the proper type (65)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onkeydown" with the proper type (66)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onkeypress" with the proper type (67)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onkeyup" with the proper type (68)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onload" with the proper type (69)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onloadeddata" with the proper type (70)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onloadedmetadata" with the proper type (71)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onloadstart" with the proper type (72)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmousedown" with the proper type (73)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmouseenter" with the proper type (74)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmouseleave" with the proper type (75)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmousemove" with the proper type (76)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmouseout" with the proper type (77)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmouseover" with the proper type (78)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmouseup" with the proper type (79)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "onmousewheel" with the proper type (80)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "onpause" with the proper type (81)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onplay" with the proper type (82)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onplaying" with the proper type (83)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onprogress" with the proper type (84)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onratechange" with the proper type (85)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onreset" with the proper type (86)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onresize" with the proper type (87)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onscroll" with the proper type (88)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onseeked" with the proper type (89)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onseeking" with the proper type (90)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onselect" with the proper type (91)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onshow" with the proper type (92)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "onsort" with the proper type (93)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "onstalled" with the proper type (94)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onsubmit" with the proper type (95)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onsuspend" with the proper type (96)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ontimeupdate" with the proper type (97)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "ontoggle" with the proper type (98)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "onvolumechange" with the proper type (99)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onwaiting" with the proper type (100)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onafterprint" with the proper type (101)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onbeforeprint" with the proper type (102)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onbeforeunload" with the proper type (103)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onhashchange" with the proper type (104)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onlanguagechange" with the proper type (105)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onmessage" with the proper type (106)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onoffline" with the proper type (107)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "ononline" with the proper type (108)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onpagehide" with the proper type (109)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onpageshow" with the proper type (110)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "onpopstate" with the proper type (111)]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "onstorage" with the proper type (112)]
         expected: FAIL
     
    -  [Window interface: window must inherit property "onunload" with the proper type (113)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "btoa" with the proper type (114)]
    -    expected: FAIL
    -
    -  [Window interface: calling btoa(DOMString) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "atob" with the proper type (115)]
    -    expected: FAIL
    -
    -  [Window interface: calling atob(DOMString) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "setTimeout" with the proper type (116)]
    -    expected: FAIL
    -
    -  [Window interface: calling setTimeout(Function,long,any) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "setTimeout" with the proper type (117)]
    -    expected: FAIL
    -
    -  [Window interface: calling setTimeout(DOMString,long,any) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "clearTimeout" with the proper type (118)]
    -    expected: FAIL
    -
    -  [Window interface: calling clearTimeout(long) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "setInterval" with the proper type (119)]
    -    expected: FAIL
    -
    -  [Window interface: calling setInterval(Function,long,any) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "setInterval" with the proper type (120)]
    -    expected: FAIL
    -
    -  [Window interface: calling setInterval(DOMString,long,any) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "clearInterval" with the proper type (121)]
    -    expected: FAIL
    -
    -  [Window interface: calling clearInterval(long) on window with too few arguments must throw TypeError]
    -    expected: FAIL
    -
       [Window interface: window must inherit property "createImageBitmap" with the proper type (122)]
         expected: FAIL
     
       [Window interface: calling createImageBitmap(ImageBitmapSource,long,long,long,long) on window with too few arguments must throw TypeError]
         expected: FAIL
     
    -  [Window interface: window must inherit property "sessionStorage" with the proper type (123)]
    -    expected: FAIL
    -
    -  [Window interface: window must inherit property "localStorage" with the proper type (124)]
    -    expected: FAIL
    -
       [Location interface: operation assign(DOMString)]
         expected: FAIL
     
    @@ -2685,15 +2331,9 @@
       [Location interface: window.location must inherit property "assign" with the proper type (0)]
         expected: FAIL
     
    -  [Location interface: calling assign(DOMString) on window.location with too few arguments must throw TypeError]
    -    expected: FAIL
    -
       [Location interface: window.location must inherit property "replace" with the proper type (1)]
         expected: FAIL
     
    -  [Location interface: calling replace(DOMString) on window.location with too few arguments must throw TypeError]
    -    expected: FAIL
    -
       [Location interface: window.location must inherit property "reload" with the proper type (2)]
         expected: FAIL
     
    diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/relevant-mutations.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/relevant-mutations.html.ini
    index 9718d9d25a51..1d7828ea6ffe 100644
    --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/relevant-mutations.html.ini
    +++ b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/relevant-mutations.html.ini
    @@ -1,49 +1,50 @@
     [relevant-mutations.html]
       type: testharness
    +  expected: TIMEOUT
       [src removed]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [srcset removed]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [sizes set]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [sizes changed]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [sizes removed]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin absent to empty]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin absent to anonymous]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin absent to use-credentials]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin empty to absent]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin empty to use-credentials]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin anonymous to absent]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin anonymous to use-credentials]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin use-credentials to absent]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin use-credentials to empty]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin use-credentials to anonymous]
    -    expected: FAIL
    +    expected: TIMEOUT
     
       [crossorigin state not changed: empty to anonymous]
         expected: FAIL
    diff --git a/testing/web-platform/meta/url/a-element.html.ini b/testing/web-platform/meta/url/a-element.html.ini
    index d1dac0a6df3c..5603b5121b24 100644
    --- a/testing/web-platform/meta/url/a-element.html.ini
    +++ b/testing/web-platform/meta/url/a-element.html.ini
    @@ -345,10 +345,10 @@
       [Parsing:  against ]
         expected: FAIL
     
    -  [Parsing: <#\xce\xb2> against ]
    +  [Parsing: <#β> against ]
         expected: FAIL
     
    -  [Parsing:  against ]
    +  [Parsing:  against ]
         expected: FAIL
     
       [Parsing: <#β> against ]
    @@ -356,3 +356,4 @@
     
       [Parsing:  against ]
         expected: FAIL
    +
    diff --git a/testing/web-platform/meta/url/a-element.xhtml.ini b/testing/web-platform/meta/url/a-element.xhtml.ini
    index f2353e7ef2a8..27520da6072f 100644
    --- a/testing/web-platform/meta/url/a-element.xhtml.ini
    +++ b/testing/web-platform/meta/url/a-element.xhtml.ini
    @@ -364,10 +364,10 @@
       [Parsing:  against ]
         expected: FAIL
     
    -  [Parsing: <#\xce\xb2> against ]
    +  [Parsing: <#β> against ]
         expected: FAIL
     
    -  [Parsing:  against ]
    +  [Parsing:  against ]
         expected: FAIL
     
       [Parsing: <#β> against ]
    @@ -375,3 +375,4 @@
     
       [Parsing:  against ]
         expected: FAIL
    +
    diff --git a/testing/web-platform/meta/websockets/interfaces/WebSocket/readyState/003.html.ini b/testing/web-platform/meta/websockets/interfaces/WebSocket/readyState/003.html.ini
    deleted file mode 100644
    index 8212317fbf74..000000000000
    --- a/testing/web-platform/meta/websockets/interfaces/WebSocket/readyState/003.html.ini
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -[003.html]
    -  type: testharness
    -  [WebSockets: delete readyState]
    -    expected: FAIL
    -
    diff --git a/testing/web-platform/meta/workers/WorkerLocation_hash_encoding.htm.ini b/testing/web-platform/meta/workers/WorkerLocation_hash_encoding.htm.ini
    index b5f8ce62ce3f..f285c02dbe37 100644
    --- a/testing/web-platform/meta/workers/WorkerLocation_hash_encoding.htm.ini
    +++ b/testing/web-platform/meta/workers/WorkerLocation_hash_encoding.htm.ini
    @@ -2,3 +2,4 @@
       type: testharness
       [ WorkerLocation.hash with url encoding string ]
         expected: FAIL
    +
    diff --git a/testing/web-platform/meta/workers/interfaces.worker.js.ini b/testing/web-platform/meta/workers/interfaces.worker.js.ini
    index 2a1d43ee8b53..3f24f681760f 100644
    --- a/testing/web-platform/meta/workers/interfaces.worker.js.ini
    +++ b/testing/web-platform/meta/workers/interfaces.worker.js.ini
    @@ -19,15 +19,6 @@
       [WorkerGlobalScope interface: operation setInterval(DOMString,long,any)]
         expected: FAIL
     
    -  [DedicatedWorkerGlobalScope interface: self must inherit property "postMessage" with the proper type (0)]
    -    expected: FAIL
    -
    -  [DedicatedWorkerGlobalScope interface: calling postMessage(any,[object Object\]) on self with too few arguments must throw TypeError]
    -    expected: FAIL
    -
    -  [DedicatedWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type (1)]
    -    expected: FAIL
    -
       [WorkerGlobalScope interface: self must inherit property "onlanguagechange" with the proper type (4)]
         expected: FAIL
         bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1154779
    diff --git a/testing/web-platform/meta/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js.ini b/testing/web-platform/meta/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js.ini
    deleted file mode 100644
    index eb38f319e054..000000000000
    --- a/testing/web-platform/meta/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js.ini
    +++ /dev/null
    @@ -1,6 +0,0 @@
    -[EventTarget.worker]
    -  type: testharness
    -  expected: ERROR
    -  [removeEventListener]
    -    expected: FAIL
    -
    diff --git a/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html.ini b/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html.ini
    deleted file mode 100644
    index e63e3361573b..000000000000
    --- a/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html.ini
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -[exception-in-onerror.html]
    -  type: testharness
    -  [onerror, "not handled" with an error in the onerror function]
    -    expected: FAIL
    -
    diff --git a/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html.ini b/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html.ini
    deleted file mode 100644
    index 1f7e75448eff..000000000000
    --- a/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html.ini
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -[not-handled.html]
    -  type: testharness
    -  [onerror, "not handled"]
    -    expected: FAIL
    -
    diff --git a/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html.ini b/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html.ini
    deleted file mode 100644
    index 802671023a39..000000000000
    --- a/testing/web-platform/meta/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html.ini
    +++ /dev/null
    @@ -1,5 +0,0 @@
    -[propagate-to-window-onerror.html]
    -  type: testharness
    -  [onerror, "not handled" with only window.onerror defined]
    -    expected: FAIL
    -
    
    From 1bbdc65eb9598f84c89f5cb889d2abe5977da77a Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 09:43:02 -0700
    Subject: [PATCH 204/241] Bug 1150253 - Part 1: SpiderMonkey should call an
     embedder-provided callback instead of running the onGarbageCollection hook
     immediately; r=sfink
    
    ---
     js/public/Debug.h        |  24 ++++-
     js/public/GCAPI.h        |  60 +++++++++++
     js/src/gc/Statistics.cpp |   3 -
     js/src/gc/Zone.cpp       |  15 ++-
     js/src/jsgc.cpp          |   6 ++
     js/src/vm/Debugger.cpp   | 219 ++++++++++++++++++++++++---------------
     js/src/vm/Debugger.h     |  78 ++++----------
     js/src/vm/Runtime.h      |   1 +
     8 files changed, 262 insertions(+), 144 deletions(-)
    
    diff --git a/js/public/Debug.h b/js/public/Debug.h
    index 56300870b8d5..bafd6ce2154e 100644
    --- a/js/public/Debug.h
    +++ b/js/public/Debug.h
    @@ -12,10 +12,11 @@
     #include "mozilla/Assertions.h"
     #include "mozilla/Attributes.h"
     #include "mozilla/MemoryReporting.h"
    -#include "mozilla/Move.h"
    +#include "mozilla/UniquePtr.h"
     
     #include "jspubtd.h"
     
    +#include "js/GCAPI.h"
     #include "js/RootingAPI.h"
     #include "js/TypeDecls.h"
     
    @@ -24,6 +25,9 @@ class Debugger;
     }
     
     namespace JS {
    +
    +using mozilla::UniquePtr;
    +
     namespace dbg {
     
     // Helping embedding code build objects for Debugger
    @@ -261,6 +265,24 @@ class BuilderOrigin : public Builder {
     void SetDebuggerMallocSizeOf(JSRuntime* runtime, mozilla::MallocSizeOf mallocSizeOf);
     
     
    +
    +// Debugger and Garbage Collection Events
    +// --------------------------------------
    +//
    +// The Debugger wants to report about its debuggees' GC cycles, however entering
    +// JS after a GC is troublesome since SpiderMonkey will often do something like
    +// force a GC and then rely on the nursery being empty. If we call into some
    +// Debugger's hook after the GC, then JS runs and the nursery won't be
    +// empty. Instead, we rely on embedders to call back into SpiderMonkey after a
    +// GC and notify Debuggers to call their onGarbageCollection hook.
    +
    +
    +// For each Debugger that observed a debuggee involved in the given GC event,
    +// call its `onGarbageCollection` hook.
    +JS_PUBLIC_API(bool)
    +FireOnGarbageCollectionHook(JSContext* cx, GarbageCollectionEvent::Ptr&& data);
    +
    +
     
     // Handlers for observing Promises
     // -------------------------------
    diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h
    index c8cd4da035b5..23eaf429716e 100644
    --- a/js/public/GCAPI.h
    +++ b/js/public/GCAPI.h
    @@ -7,12 +7,18 @@
     #ifndef js_GCAPI_h
     #define js_GCAPI_h
     
    +#include "mozilla/UniquePtr.h"
    +#include "mozilla/Vector.h"
    +
     #include "js/HeapAPI.h"
     
     namespace js {
     namespace gc {
     class GCRuntime;
     }
    +namespace gcstats {
    +struct Statistics;
    +}
     }
     
     typedef enum JSGCMode {
    @@ -42,6 +48,8 @@ typedef enum JSGCInvocationKind {
     
     namespace JS {
     
    +using mozilla::UniquePtr;
    +
     #define GCREASONS(D)                            \
         /* Reasons internal to the JS engine */     \
         D(API)                                      \
    @@ -254,6 +262,56 @@ FinishIncrementalGC(JSRuntime* rt, gcreason::Reason reason);
     extern JS_PUBLIC_API(void)
     AbortIncrementalGC(JSRuntime* rt);
     
    +namespace dbg {
    +
    +// The `JS::dbg::GarbageCollectionEvent` class is essentially a view of the
    +// `js::gcstats::Statistics` data without the uber implementation-specific bits.
    +// It should generally be palatable for web developers.
    +class GarbageCollectionEvent
    +{
    +    // The major GC number of the GC cycle this data pertains to.
    +    uint64_t majorGCNumber_;
    +
    +    // Reference to a non-owned, statically allocated C string. This is a very
    +    // short reason explaining why a GC was triggered.
    +    const char* reason;
    +
    +    // Reference to a nullable, non-owned, statically allocated C string. If the
    +    // collection was forced to be non-incremental, this is a short reason of
    +    // why the GC could not perform an incremental collection.
    +    const char* nonincrementalReason;
    +
    +    // Represents a single slice of a possibly multi-slice incremental garbage
    +    // collection.
    +    struct Collection {
    +        int64_t startTimestamp;
    +        int64_t endTimestamp;
    +    };
    +
    +    // The set of garbage collection slices that made up this GC cycle.
    +    mozilla::Vector collections;
    +
    +    GarbageCollectionEvent(const GarbageCollectionEvent& rhs) = delete;
    +    GarbageCollectionEvent& operator=(const GarbageCollectionEvent& rhs) = delete;
    +
    +  public:
    +    explicit GarbageCollectionEvent(uint64_t majorGCNum)
    +        : majorGCNumber_(majorGCNum)
    +        , reason(nullptr)
    +        , nonincrementalReason(nullptr)
    +        , collections()
    +    { }
    +
    +    using Ptr = UniquePtr>;
    +    static Ptr Create(JSRuntime* rt, ::js::gcstats::Statistics& stats, uint64_t majorGCNumber);
    +
    +    JSObject* toJSObject(JSContext* cx) const;
    +
    +    uint64_t majorGCNumber() const { return majorGCNumber_; }
    +};
    +
    +} // namespace dbg
    +
     enum GCProgress {
         /*
          * During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END
    @@ -280,6 +338,8 @@ struct JS_PUBLIC_API(GCDescription) {
     
         char16_t* formatMessage(JSRuntime* rt) const;
         char16_t* formatJSON(JSRuntime* rt, uint64_t timestamp) const;
    +
    +    JS::dbg::GarbageCollectionEvent::Ptr toGCEvent(JSRuntime* rt) const;
     };
     
     typedef void
    diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp
    index 05e88bc3cb04..39186d41d12a 100644
    --- a/js/src/gc/Statistics.cpp
    +++ b/js/src/gc/Statistics.cpp
    @@ -974,9 +974,6 @@ Statistics::endGC()
         if (fp)
             printStats();
     
    -    if (!aborted)
    -        Debugger::onGarbageCollection(runtime, *this);
    -
         // Clear the timers at the end of a GC because we accumulate time in
         // between GCs for some (which come before PHASE_GC_BEGIN in the list.)
         PodZero(&phaseStartTimes[PHASE_GC_BEGIN], PHASE_LIMIT - PHASE_GC_BEGIN);
    diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp
    index 30d5a4b4112a..9c0e00dc4f6b 100644
    --- a/js/src/gc/Zone.cpp
    +++ b/js/src/gc/Zone.cpp
    @@ -264,7 +264,8 @@ void
     Zone::notifyObservingDebuggers()
     {
         for (CompartmentsInZoneIter comps(this); !comps.done(); comps.next()) {
    -        RootedGlobalObject global(runtimeFromAnyThread(), comps->maybeGlobal());
    +        JSRuntime* rt = runtimeFromAnyThread();
    +        RootedGlobalObject global(rt, comps->maybeGlobal());
             if (!global)
                 continue;
     
    @@ -272,8 +273,16 @@ Zone::notifyObservingDebuggers()
             if (!dbgs)
                 continue;
     
    -        for (GlobalObject::DebuggerVector::Range r = dbgs->all(); !r.empty(); r.popFront())
    -            r.front()->debuggeeIsBeingCollected();
    +        for (GlobalObject::DebuggerVector::Range r = dbgs->all(); !r.empty(); r.popFront()) {
    +            if (!r.front()->debuggeeIsBeingCollected(rt->gc.majorGCCount())) {
    +#ifdef DEBUG
    +                fprintf(stderr,
    +                        "OOM while notifying observing Debuggers of a GC: The onGarbageCollection\n"
    +                        "hook will not be fired for this GC for some Debuggers!\n");
    +#endif
    +                return;
    +            }
    +        }
         }
     }
     
    diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
    index adbda4c42310..f3b17559f46f 100644
    --- a/js/src/jsgc.cpp
    +++ b/js/src/jsgc.cpp
    @@ -7029,6 +7029,12 @@ JS::GCDescription::formatMessage(JSRuntime* rt) const
         return rt->gc.stats.formatMessage();
     }
     
    +JS::dbg::GarbageCollectionEvent::Ptr
    +JS::GCDescription::toGCEvent(JSRuntime* rt) const
    +{
    +    return JS::dbg::GarbageCollectionEvent::Create(rt, rt->gc.stats, rt->gc.majorGCCount());
    +}
    +
     char16_t*
     JS::GCDescription::formatJSON(JSRuntime* rt, uint64_t timestamp) const
     {
    diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
    index b6ac3fc5ab8f..566c48cb4f73 100644
    --- a/js/src/vm/Debugger.cpp
    +++ b/js/src/vm/Debugger.cpp
    @@ -44,6 +44,7 @@ using js::frontend::IsIdentifier;
     using mozilla::ArrayLength;
     using mozilla::DebugOnly;
     using mozilla::Maybe;
    +using mozilla::UniquePtr;
     
     
     /*** Forward declarations ************************************************************************/
    @@ -358,9 +359,8 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg)
       : object(dbg),
         uncaughtExceptionHook(nullptr),
         enabled(true),
    +    observedGCs(cx),
         allowUnobservedAsmJS(false),
    -    debuggeeWasCollected(false),
    -    inOnGCHook(false),
         trackingAllocationSites(false),
         allocationSamplingProbability(1.0),
         allocationsLogLength(0),
    @@ -408,6 +408,7 @@ Debugger::init(JSContext* cx)
                   scripts.init() &&
                   sources.init() &&
                   objects.init() &&
    +              observedGCs.init() &&
                   environments.init();
         if (!ok)
             ReportOutOfMemory(cx);
    @@ -878,71 +879,6 @@ Debugger::wrapDebuggeeValue(JSContext* cx, MutableHandleValue vp)
         return true;
     }
     
    -JSObject*
    -Debugger::translateGCStatistics(JSContext* cx, const gcstats::Statistics& stats)
    -{
    -    // If this functions triggers a GC then the statistics object will change
    -    // underneath us.
    -    gc::AutoSuppressGC suppressGC(cx);
    -
    -    RootedObject obj(cx, NewBuiltinClassInstance(cx));
    -    if (!obj)
    -        return nullptr;
    -
    -    const char* nonincrementalReason = stats.nonincrementalReason();
    -    RootedValue nonincrementalReasonValue(cx, NullValue());
    -    if (nonincrementalReason) {
    -        JSAtom* atomized = Atomize(cx, nonincrementalReason, strlen(nonincrementalReason));
    -        if (!atomized)
    -            return nullptr;
    -        nonincrementalReasonValue.setString(atomized);
    -    }
    -
    -    if (!DefineProperty(cx, obj, cx->names().nonincrementalReason, nonincrementalReasonValue))
    -        return nullptr;
    -
    -    RootedArrayObject slicesArray(cx, NewDenseEmptyArray(cx));
    -    if (!slicesArray)
    -        return nullptr;
    -
    -    size_t idx = 0;
    -    for (auto range = stats.sliceRange(); !range.empty(); range.popFront()) {
    -        if (idx == 0) {
    -            // There is only one GC reason for the whole cycle, but for legacy
    -            // reasons, this data is stored and replicated on each slice.
    -            const char* reason = gcstats::ExplainReason(range.front().reason);
    -            JSAtom* atomized = Atomize(cx, reason, strlen(reason));
    -            if (!atomized)
    -                return nullptr;
    -            RootedValue reasonVal(cx, StringValue(atomized));
    -            if (!DefineProperty(cx, obj, cx->names().reason, reasonVal))
    -                return nullptr;
    -        }
    -
    -        RootedPlainObject collectionObj(cx, NewBuiltinClassInstance(cx));
    -        if (!collectionObj)
    -            return nullptr;
    -
    -        RootedValue start(cx, NumberValue(range.front().start));
    -        RootedValue end(cx, NumberValue(range.front().end));
    -        if (!DefineProperty(cx, collectionObj, cx->names().startTimestamp, start) ||
    -            !DefineProperty(cx, collectionObj, cx->names().endTimestamp, end))
    -        {
    -            return nullptr;
    -        }
    -
    -        RootedValue collectionVal(cx, ObjectValue(*collectionObj));
    -        if (!DefineElement(cx, slicesArray, idx++, collectionVal))
    -            return nullptr;
    -    }
    -
    -    RootedValue slicesValue(cx, ObjectValue(*slicesArray));
    -    if (!DefineProperty(cx, obj, cx->names().collections, slicesValue))
    -        return nullptr;
    -
    -    return obj.get();
    -}
    -
     bool
     Debugger::unwrapDebuggeeObject(JSContext* cx, MutableHandleObject obj)
     {
    @@ -1334,18 +1270,11 @@ Debugger::fireNewScript(JSContext* cx, HandleScript script)
     }
     
     void
    -Debugger::fireOnGarbageCollectionHook(JSRuntime* rt, const gcstats::Statistics& stats)
    +Debugger::fireOnGarbageCollectionHook(JSContext* cx,
    +                                      const JS::dbg::GarbageCollectionEvent::Ptr& gcData)
     {
    -    if (inOnGCHook)
    -        return;
    -
    -    AutoOnGCHookReentrancyGuard guard(*this);
    -
    -    MOZ_ASSERT(debuggeeWasCollected);
    -    debuggeeWasCollected = false;
    -
    -    JSContext* cx = DefaultJSContext(rt);
    -    MOZ_ASSERT(cx);
    +    MOZ_ASSERT(observedGC(gcData->majorGCNumber()));
    +    observedGCs.remove(gcData->majorGCNumber());
     
         RootedObject hook(cx, getHook(OnGarbageCollection));
         MOZ_ASSERT(hook);
    @@ -1354,15 +1283,15 @@ Debugger::fireOnGarbageCollectionHook(JSRuntime* rt, const gcstats::Statistics&
         Maybe ac;
         ac.emplace(cx, object);
     
    -    JSObject* statsObj = translateGCStatistics(cx, stats);
    -    if (!statsObj) {
    +    JSObject* dataObj = gcData->toJSObject(cx);
    +    if (!dataObj) {
             handleUncaughtException(ac, false);
             return;
         }
     
    -    RootedValue statsVal(cx, ObjectValue(*statsObj));
    +    RootedValue dataVal(cx, ObjectValue(*dataObj));
         RootedValue rv(cx);
    -    if (!Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, statsVal.address(), &rv))
    +    if (!Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, dataVal.address(), &rv))
             handleUncaughtException(ac, true);
     }
     
    @@ -7865,3 +7794,129 @@ JS::dbg::IsDebugger(JS::Value val)
     
         return js::Debugger::fromJSObject(&obj) != nullptr;
     }
    +
    +
    +/*** JS::dbg::GarbageCollectionEvent **************************************************************/
    +
    +namespace JS {
    +namespace dbg {
    +
    +/* static */ GarbageCollectionEvent::Ptr
    +GarbageCollectionEvent::Create(JSRuntime* rt, ::js::gcstats::Statistics& stats, uint64_t gcNumber)
    +{
    +    auto data = rt->make_unique(gcNumber);
    +    if (!data)
    +        return nullptr;
    +
    +    data->nonincrementalReason = stats.nonincrementalReason();
    +
    +    for (auto range = stats.sliceRange(); !range.empty(); range.popFront()) {
    +        if (!data->reason) {
    +            // There is only one GC reason for the whole cycle, but for legacy
    +            // reasons this data is stored and replicated on each slice. Each
    +            // slice used to have its own GCReason, but now they are all the
    +            // same.
    +            data->reason = gcstats::ExplainReason(range.front().reason);
    +            MOZ_ASSERT(data->reason);
    +        }
    +
    +        if (!data->collections.growBy(1))
    +            return nullptr;
    +
    +        data->collections.back().startTimestamp = range.front().start;
    +        data->collections.back().endTimestamp = range.front().end;
    +    }
    +
    +
    +    return data;
    +}
    +
    +static bool
    +DefineStringProperty(JSContext* cx, HandleObject obj, PropertyName* propName, const char* strVal)
    +{
    +    RootedValue val(cx, UndefinedValue());
    +    if (strVal) {
    +        JSAtom* atomized = Atomize(cx, strVal, strlen(strVal));
    +        if (!atomized)
    +            return false;
    +        val = StringValue(atomized);
    +    }
    +    return DefineProperty(cx, obj, propName, val);
    +}
    +
    +JSObject*
    +GarbageCollectionEvent::toJSObject(JSContext* cx) const
    +{
    +    RootedObject obj(cx, NewBuiltinClassInstance(cx));
    +    if (!obj ||
    +        !DefineStringProperty(cx, obj, cx->names().nonincrementalReason, nonincrementalReason) ||
    +        !DefineStringProperty(cx, obj, cx->names().reason, reason))
    +    {
    +        return nullptr;
    +    }
    +
    +    RootedArrayObject slicesArray(cx, NewDenseEmptyArray(cx));
    +    if (!slicesArray)
    +        return nullptr;
    +
    +    size_t idx = 0;
    +    for (auto range = collections.all(); !range.empty(); range.popFront()) {
    +        RootedPlainObject collectionObj(cx, NewBuiltinClassInstance(cx));
    +        if (!collectionObj)
    +            return nullptr;
    +
    +        RootedValue start(cx, NumberValue(range.front().startTimestamp));
    +        RootedValue end(cx, NumberValue(range.front().endTimestamp));
    +        if (!DefineProperty(cx, collectionObj, cx->names().startTimestamp, start) ||
    +            !DefineProperty(cx, collectionObj, cx->names().endTimestamp, end))
    +        {
    +            return nullptr;
    +        }
    +
    +        RootedValue collectionVal(cx, ObjectValue(*collectionObj));
    +        if (!DefineElement(cx, slicesArray, idx++, collectionVal))
    +            return nullptr;
    +    }
    +
    +    RootedValue slicesValue(cx, ObjectValue(*slicesArray));
    +    if (!DefineProperty(cx, obj, cx->names().collections, slicesValue))
    +        return nullptr;
    +
    +    return obj;
    +}
    +
    +JS_PUBLIC_API(bool)
    +FireOnGarbageCollectionHook(JSContext* cx, JS::dbg::GarbageCollectionEvent::Ptr&& data)
    +{
    +    AutoObjectVector triggered(cx);
    +
    +    {
    +        // We had better not GC (and potentially get a dangling Debugger
    +        // pointer) while finding all Debuggers observing a debuggee that
    +        // participated in this GC.
    +        AutoCheckCannotGC noGC;
    +
    +        for (Debugger* dbg = cx->runtime()->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
    +            if (dbg->enabled &&
    +                dbg->observedGC(data->majorGCNumber()) &&
    +                dbg->getHook(Debugger::OnGarbageCollection))
    +            {
    +                if (!triggered.append(dbg->object)) {
    +                    JS_ReportOutOfMemory(cx);
    +                    return false;
    +                }
    +            }
    +        }
    +    }
    +
    +    for ( ; !triggered.empty(); triggered.popBack()) {
    +        Debugger* dbg = Debugger::fromJSObject(triggered.back());
    +        dbg->fireOnGarbageCollectionHook(cx, data);
    +        MOZ_ASSERT(!cx->isExceptionPending());
    +    }
    +
    +    return true;
    +}
    +
    +} // namespace dbg
    +} // namespace JS
    diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
    index d1944a90eb92..4cfd9801b58c 100644
    --- a/js/src/vm/Debugger.h
    +++ b/js/src/vm/Debugger.h
    @@ -10,6 +10,8 @@
     #include "mozilla/GuardObjects.h"
     #include "mozilla/LinkedList.h"
     #include "mozilla/Range.h"
    +#include "mozilla/UniquePtr.h"
    +#include "mozilla/Vector.h"
     
     #include "jsclist.h"
     #include "jscntxt.h"
    @@ -190,6 +192,8 @@ class Debugger : private mozilla::LinkedListElement
         friend JSObject* SavedStacksMetadataCallback(JSContext* cx);
         friend void JS::dbg::onNewPromise(JSContext* cx, HandleObject promise);
         friend void JS::dbg::onPromiseSettled(JSContext* cx, HandleObject promise);
    +    friend bool JS::dbg::FireOnGarbageCollectionHook(JSContext* cx,
    +                                                     JS::dbg::GarbageCollectionEvent::Ptr&& data);
     
       public:
         enum Hook {
    @@ -242,9 +246,17 @@ class Debugger : private mozilla::LinkedListElement
         // false otherwise.
         bool isDebuggee(const JSCompartment* compartment) const;
     
    -    // Notify this Debugger that one of its debuggee compartments' zones is
    -    // being collected.
    -    void debuggeeIsBeingCollected() { debuggeeWasCollected = true; }
    +    // Return true if this Debugger observed a debuggee that participated in the
    +    // GC identified by the given GC number. Return false otherwise.
    +    bool observedGC(uint64_t majorGCNumber) const {
    +        return observedGCs.has(majorGCNumber);
    +    }
    +
    +    // Notify this Debugger that one or more of its debuggees is participating
    +    // in the GC identified by the given GC number.
    +    bool debuggeeIsBeingCollected(uint64_t majorGCNumber) {
    +        return observedGCs.put(majorGCNumber);
    +    }
     
       private:
         HeapPtrNativeObject object;         /* The Debugger object. Strong reference. */
    @@ -253,6 +265,10 @@ class Debugger : private mozilla::LinkedListElement
         bool enabled;
         JSCList breakpoints;                /* Circular list of all js::Breakpoints in this debugger */
     
    +    // The set of GC numbers for which one or more of this Debugger's observed
    +    // debuggees participated in.
    +    js::HashSet observedGCs;
    +
         struct AllocationSite : public mozilla::LinkedListElement
         {
             AllocationSite(HandleObject frame, int64_t when, const char* className)
    @@ -270,38 +286,6 @@ class Debugger : private mozilla::LinkedListElement
         typedef mozilla::LinkedList AllocationSiteList;
     
         bool allowUnobservedAsmJS;
    -
    -    // During a GC cycle, this is true if one of this Debugger's debuggees was
    -    // collected. When the GC cycle completes, this flag is reset.
    -    bool debuggeeWasCollected;
    -
    -    // True while we are executing the onGarbageCollection hook, and therefore
    -    // should not fire the hook for this Debugger instance again if there is a
    -    // GC while we are executing the hook. See also
    -    // `AutoOnGCHookReentrancyGuard` below.
    -    bool inOnGCHook;
    -
    -    // RAII class to automatically guard against reentrancy into the
    -    // OnGarbageCollection hook.
    -    class MOZ_STACK_CLASS AutoOnGCHookReentrancyGuard {
    -        MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
    -        Debugger& dbg;
    -
    -    public:
    -        explicit AutoOnGCHookReentrancyGuard(Debugger& dbg MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    -            : dbg(dbg)
    -        {
    -            MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    -            MOZ_ASSERT(!dbg.inOnGCHook);
    -            dbg.inOnGCHook = true;
    -        }
    -
    -        ~AutoOnGCHookReentrancyGuard() {
    -            MOZ_ASSERT(dbg.inOnGCHook);
    -            dbg.inOnGCHook = false;
    -        }
    -    };
    -
         bool trackingAllocationSites;
         double allocationSamplingProbability;
         AllocationSiteList allocationsLog;
    @@ -554,9 +538,10 @@ class Debugger : private mozilla::LinkedListElement
     
         /*
          * Receive a "garbage collection" event from the engine. A GC cycle with the
    -     * given statistics was just completed.
    +     * given data was recently completed.
          */
    -    void fireOnGarbageCollectionHook(JSRuntime* rt, const gcstats::Statistics& stats);
    +    void fireOnGarbageCollectionHook(JSContext* cx,
    +                                     const JS::dbg::GarbageCollectionEvent::Ptr& gcData);
     
         /*
          * Gets a Debugger.Frame object. If maybeIter is non-null, we eagerly copy
    @@ -675,7 +660,6 @@ class Debugger : private mozilla::LinkedListElement
         static inline void onNewGlobalObject(JSContext* cx, Handle global);
         static inline bool onLogAllocationSite(JSContext* cx, JSObject* obj, HandleSavedFrame frame,
                                                int64_t when);
    -    static inline void onGarbageCollection(JSRuntime* rt, const gcstats::Statistics& stats);
         static JSTrapStatus onTrap(JSContext* cx, MutableHandleValue vp);
         static JSTrapStatus onSingleStep(JSContext* cx, MutableHandleValue vp);
         static bool handleBaselineOsr(JSContext* cx, InterpreterFrame* from, jit::BaselineFrame* to);
    @@ -724,13 +708,6 @@ class Debugger : private mozilla::LinkedListElement
          */
         bool wrapDebuggeeValue(JSContext* cx, MutableHandleValue vp);
     
    -    /*
    -     * Converts an implementor level of detail gcstats::Statistics object into a
    -     * JSObject that web developers should be able to make sense of. Returns
    -     * nullptr on failure.
    -     */
    -    JSObject* translateGCStatistics(JSContext* cx, const gcstats::Statistics& stats);
    -
         /*
          * Unwrap a Debug.Object, without rewrapping it for any particular debuggee
          * compartment.
    @@ -992,18 +969,9 @@ Debugger::onLogAllocationSite(JSContext* cx, JSObject* obj, HandleSavedFrame fra
         return Debugger::slowPathOnLogAllocationSite(cx, hobj, frame, when, *dbgs);
     }
     
    -/* static */ void
    -Debugger::onGarbageCollection(JSRuntime* rt, const gcstats::Statistics& stats)
    -{
    -    for (Debugger* dbg = rt->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) {
    -        if (dbg->debuggeeWasCollected && dbg->getHook(OnGarbageCollection)) {
    -            dbg->fireOnGarbageCollectionHook(rt, stats);
    -        }
    -    }
    -}
    -
     bool ReportObjectRequired(JSContext* cx);
     
     } /* namespace js */
     
    +
     #endif /* vm_Debugger_h */
    diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h
    index 1edbf8ccc89d..83c3a4e63b1c 100644
    --- a/js/src/vm/Runtime.h
    +++ b/js/src/vm/Runtime.h
    @@ -31,6 +31,7 @@
     #include "gc/GCRuntime.h"
     #include "gc/Tracer.h"
     #include "irregexp/RegExpStack.h"
    +#include "js/Debug.h"
     #include "js/HashTable.h"
     #ifdef DEBUG
     # include "js/Proxy.h" // For AutoEnterPolicy
    
    From d67ed8553a9931279e760027fc059f8cf6c9aed6 Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 09:43:02 -0700
    Subject: [PATCH 205/241] Bug 1150253 - Part 2: Gecko should provide a callback
     for SpiderMonkey to enqueue the onGarbageCollection hook runnable; r=mccr8
    
    ---
     xpcom/base/CycleCollectedJSRuntime.cpp | 20 +++++++++++
     xpcom/base/CycleCollectedJSRuntime.h   |  4 +++
     xpcom/base/DebuggerOnGCRunnable.cpp    | 47 ++++++++++++++++++++++++++
     xpcom/base/DebuggerOnGCRunnable.h      | 35 +++++++++++++++++++
     xpcom/base/moz.build                   |  2 ++
     5 files changed, 108 insertions(+)
     create mode 100644 xpcom/base/DebuggerOnGCRunnable.cpp
     create mode 100644 xpcom/base/DebuggerOnGCRunnable.h
    
    diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp
    index 405bf3d79757..f4a810e24272 100644
    --- a/xpcom/base/CycleCollectedJSRuntime.cpp
    +++ b/xpcom/base/CycleCollectedJSRuntime.cpp
    @@ -60,6 +60,7 @@
     #include "mozilla/AutoRestore.h"
     #include "mozilla/MemoryReporting.h"
     #include "mozilla/dom/BindingUtils.h"
    +#include "mozilla/DebuggerOnGCRunnable.h"
     #include "mozilla/dom/DOMJSClass.h"
     #include "mozilla/dom/ScriptSettings.h"
     #include "jsprf.h"
    @@ -466,6 +467,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
       : mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal)
       , mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal)
       , mJSRuntime(nullptr)
    +  , mPrevGCSliceCallback(nullptr)
       , mJSHolders(256)
       , mOutOfMemoryState(OOMState::OK)
       , mLargeAllocationFailureState(OOMState::OK)
    @@ -482,6 +484,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
       }
       JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this);
       JS_SetGCCallback(mJSRuntime, GCCallback, this);
    +  mPrevGCSliceCallback = JS::SetGCSliceCallback(mJSRuntime, GCSliceCallback);
       JS::SetOutOfMemoryCallback(mJSRuntime, OutOfMemoryCallback, this);
       JS::SetLargeAllocationFailureCallback(mJSRuntime,
                                             LargeAllocationFailureCallback, this);
    @@ -745,6 +748,23 @@ CycleCollectedJSRuntime::GCCallback(JSRuntime* aRuntime,
       self->OnGC(aStatus);
     }
     
    +/* static */ void
    +CycleCollectedJSRuntime::GCSliceCallback(JSRuntime* aRuntime,
    +                                         JS::GCProgress aProgress,
    +                                         const JS::GCDescription& aDesc)
    +{
    +  CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get();
    +  MOZ_ASSERT(self->Runtime() == aRuntime);
    +
    +  if (aProgress == JS::GC_CYCLE_END) {
    +    NS_WARN_IF(NS_FAILED(DebuggerOnGCRunnable::Enqueue(aRuntime, aDesc)));
    +  }
    +
    +  if (self->mPrevGCSliceCallback) {
    +    self->mPrevGCSliceCallback(aRuntime, aProgress, aDesc);
    +  }
    +}
    +
     /* static */ void
     CycleCollectedJSRuntime::OutOfMemoryCallback(JSContext* aContext,
                                                  void* aData)
    diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h
    index a06663f46a22..c344b13b2fd6 100644
    --- a/xpcom/base/CycleCollectedJSRuntime.h
    +++ b/xpcom/base/CycleCollectedJSRuntime.h
    @@ -194,6 +194,8 @@ private:
       static void TraceBlackJS(JSTracer* aTracer, void* aData);
       static void TraceGrayJS(JSTracer* aTracer, void* aData);
       static void GCCallback(JSRuntime* aRuntime, JSGCStatus aStatus, void* aData);
    +  static void GCSliceCallback(JSRuntime* aRuntime, JS::GCProgress aProgress,
    +                              const JS::GCDescription& aDesc);
       static void OutOfMemoryCallback(JSContext* aContext, void* aData);
       static void LargeAllocationFailureCallback(void* aData);
       static bool ContextCallback(JSContext* aCx, unsigned aOperation,
    @@ -308,6 +310,8 @@ private:
     
       JSRuntime* mJSRuntime;
     
    +  JS::GCSliceCallback mPrevGCSliceCallback;
    +
       nsDataHashtable, nsScriptObjectTracer*> mJSHolders;
     
       typedef nsDataHashtable, void*>
    diff --git a/xpcom/base/DebuggerOnGCRunnable.cpp b/xpcom/base/DebuggerOnGCRunnable.cpp
    new file mode 100644
    index 000000000000..7eeff9bbb8ef
    --- /dev/null
    +++ b/xpcom/base/DebuggerOnGCRunnable.cpp
    @@ -0,0 +1,47 @@
    +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
    +/* vim: set ts=8 sts=2 et sw=2 tw=80: */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +#include "mozilla/DebuggerOnGCRunnable.h"
    +
    +#include "mozilla/dom/ScriptSettings.h"
    +#include "mozilla/CycleCollectedJSRuntime.h"
    +#include "mozilla/Move.h"
    +#include "js/Debug.h"
    +
    +namespace mozilla {
    +
    +/* static */ NS_METHOD
    +DebuggerOnGCRunnable::Enqueue(JSRuntime* aRt, const JS::GCDescription& aDesc)
    +{
    +  auto gcEvent = aDesc.toGCEvent(aRt);
    +  if (!gcEvent) {
    +    return NS_ERROR_OUT_OF_MEMORY;
    +  }
    +
    +  nsRefPtr runOnGC =
    +    new DebuggerOnGCRunnable(Move(gcEvent));
    +  return NS_DispatchToCurrentThread(runOnGC);
    +}
    +
    +NS_IMETHODIMP
    +DebuggerOnGCRunnable::Run()
    +{
    +  AutoJSAPI jsapi;
    +  jsapi.Init();
    +  if (!JS::dbg::FireOnGarbageCollectionHook(jsapi.cx(), Move(mGCData))) {
    +    return NS_ERROR_OUT_OF_MEMORY;
    +  }
    +  return NS_OK;
    +}
    +
    +NS_IMETHODIMP
    +DebuggerOnGCRunnable::Cancel()
    +{
    +  mGCData = nullptr;
    +  return NS_OK;
    +}
    +
    +} // namespace mozilla
    diff --git a/xpcom/base/DebuggerOnGCRunnable.h b/xpcom/base/DebuggerOnGCRunnable.h
    new file mode 100644
    index 000000000000..1f036441fccf
    --- /dev/null
    +++ b/xpcom/base/DebuggerOnGCRunnable.h
    @@ -0,0 +1,35 @@
    +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
    +/* vim: set ts=8 sts=2 et sw=2 tw=80: */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +#ifndef mozilla_DebuggerOnGCRunnable_h
    +#define mozilla_DebuggerOnGCRunnable_h
    +
    +#include "nsThreadUtils.h"
    +#include "js/GCAPI.h"
    +#include "mozilla/Move.h"
    +#include "mozilla/UniquePtr.h"
    +
    +namespace mozilla {
    +
    +// Runnable to fire the SpiderMonkey Debugger API's onGarbageCollection hook.
    +class DebuggerOnGCRunnable : public nsCancelableRunnable
    +{
    +  JS::dbg::GarbageCollectionEvent::Ptr mGCData;
    +
    +  explicit DebuggerOnGCRunnable(JS::dbg::GarbageCollectionEvent::Ptr&& aGCData)
    +    : mGCData(Move(aGCData))
    +  { }
    +
    +public:
    +  static NS_METHOD Enqueue(JSRuntime* aRt, const JS::GCDescription& aDesc);
    +
    +  NS_DECL_NSIRUNNABLE
    +  NS_DECL_NSICANCELABLERUNNABLE
    +};
    +
    +} // namespace mozilla
    +
    +#endif // ifdef mozilla_dom_DebuggerOnGCRunnable_h
    diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build
    index 34e4c4e8bf48..8e71c7b79081 100644
    --- a/xpcom/base/moz.build
    +++ b/xpcom/base/moz.build
    @@ -77,6 +77,7 @@ EXPORTS.mozilla += [
         'CountingAllocatorBase.h',
         'CycleCollectedJSRuntime.h',
         'Debug.h',
    +    'DebuggerOnGCRunnable.h',
         'DeferredFinalize.h',
         'ErrorNames.h',
         'HoldDropJSObjects.h',
    @@ -101,6 +102,7 @@ UNIFIED_SOURCES += [
         'ClearOnShutdown.cpp',
         'CycleCollectedJSRuntime.cpp',
         'Debug.cpp',
    +    'DebuggerOnGCRunnable.cpp',
         'DeferredFinalize.cpp',
         'ErrorNames.cpp',
         'HoldDropJSObjects.cpp',
    
    From a97c81d4d88f19d2cc18235d816dbfe93b31d0a1 Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 09:43:02 -0700
    Subject: [PATCH 206/241] Bug 1150253 - Part 3: Migrate onGarbageCollection
     tests; r=sfink
    
    --HG--
    rename : js/src/jit-test/tests/debug/Memory-onGarbageCollection-04.js => js/xpconnect/tests/unit/test_onGarbageCollection-04.js
    ---
     .../debug/Memory-onGarbageCollection-01.js    | 57 -----------
     .../debug/Memory-onGarbageCollection-02.js    | 69 --------------
     .../debug/Memory-onGarbageCollection-03.js    | 18 ----
     js/xpconnect/tests/chrome/chrome.ini          |  1 +
     .../chrome/test_onGarbageCollection.html      | 35 +++++++
     js/xpconnect/tests/unit/head_ongc.js          | 41 ++++++++
     .../tests/unit/test_onGarbageCollection-01.js | 64 +++++++++++++
     .../tests/unit/test_onGarbageCollection-02.js | 94 +++++++++++++++++++
     .../tests/unit/test_onGarbageCollection-03.js | 35 +++++++
     .../unit/test_onGarbageCollection-04.js}      | 50 ++++++----
     js/xpconnect/tests/unit/xpcshell.ini          |  8 ++
     11 files changed, 311 insertions(+), 161 deletions(-)
     delete mode 100644 js/src/jit-test/tests/debug/Memory-onGarbageCollection-01.js
     delete mode 100644 js/src/jit-test/tests/debug/Memory-onGarbageCollection-02.js
     delete mode 100644 js/src/jit-test/tests/debug/Memory-onGarbageCollection-03.js
     create mode 100644 js/xpconnect/tests/chrome/test_onGarbageCollection.html
     create mode 100644 js/xpconnect/tests/unit/head_ongc.js
     create mode 100644 js/xpconnect/tests/unit/test_onGarbageCollection-01.js
     create mode 100644 js/xpconnect/tests/unit/test_onGarbageCollection-02.js
     create mode 100644 js/xpconnect/tests/unit/test_onGarbageCollection-03.js
     rename js/{src/jit-test/tests/debug/Memory-onGarbageCollection-04.js => xpconnect/tests/unit/test_onGarbageCollection-04.js} (52%)
    
    diff --git a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-01.js b/js/src/jit-test/tests/debug/Memory-onGarbageCollection-01.js
    deleted file mode 100644
    index 8604ef40ba9b..000000000000
    --- a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-01.js
    +++ /dev/null
    @@ -1,57 +0,0 @@
    -// Test basic usage of onGarbageCollection
    -
    -const root = newGlobal();
    -const dbg = new Debugger();
    -const wrappedRoot = dbg.addDebuggee(root)
    -
    -const NUM_SLICES = root.NUM_SLICES = 10;
    -
    -let fired = false;
    -let slicesFound = 0;
    -
    -dbg.memory.onGarbageCollection = data => {
    -  fired = true;
    -
    -  print("Got onGarbageCollection: " + JSON.stringify(data, null, 2));
    -
    -  assertEq(typeof data.reason, "string");
    -  assertEq(typeof data.nonincrementalReason == "string" || data.nonincrementalReason === null,
    -           true);
    -
    -  let lastStartTimestamp = 0;
    -  for (let i = 0; i < data.collections.length; i++) {
    -    let slice = data.collections[i];
    -
    -    assertEq(slice.startTimestamp >= lastStartTimestamp, true);
    -    assertEq(slice.startTimestamp <= slice.endTimestamp, true);
    -
    -    lastStartTimestamp = slice.startTimestamp;
    -  }
    -
    -  assertEq(data.collections.length >= 1, true);
    -  slicesFound += data.collections.length;
    -}
    -
    -root.eval(
    -  `
    -  this.allocs = [];
    -
    -  // GC slices
    -  for (var i = 0; i < NUM_SLICES; i++) {
    -    this.allocs.push({});
    -    gcslice();
    -  }
    -
    -  // Full GC
    -  this.allocs.push({});
    -  gc();
    -  `
    -);
    -
    -// The hook should have been fired at least once.
    -assertEq(fired, true);
    -
    -// NUM_SLICES + 1 full gc + however many were triggered naturally (due to
    -// whatever zealousness setting).
    -print("Found " + slicesFound + " slices");
    -assertEq(slicesFound >= NUM_SLICES + 1, true);
    diff --git a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-02.js b/js/src/jit-test/tests/debug/Memory-onGarbageCollection-02.js
    deleted file mode 100644
    index 41e15de27c46..000000000000
    --- a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-02.js
    +++ /dev/null
    @@ -1,69 +0,0 @@
    -// Test multiple debuggers, GCs, and zones interacting with each other.
    -
    -gczeal(0);
    -
    -const root1 = newGlobal();
    -const dbg1 = new Debugger();
    -dbg1.addDebuggee(root1)
    -
    -const root2 = newGlobal();
    -const dbg2 = new Debugger();
    -dbg2.addDebuggee(root2)
    -
    -let fired1 = false;
    -let fired2 = false;
    -dbg1.memory.onGarbageCollection = _ => fired1 = true;
    -dbg2.memory.onGarbageCollection = _ => fired2 = true;
    -
    -function reset() {
    -  fired1 = false;
    -  fired2 = false;
    -}
    -
    -// GC 1 only
    -root1.eval(`gc(this)`);
    -assertEq(fired1, true);
    -assertEq(fired2, false);
    -
    -// GC 2 only
    -reset();
    -root2.eval(`gc(this)`);
    -assertEq(fired1, false);
    -assertEq(fired2, true);
    -
    -// Full GC
    -reset();
    -gc();
    -assertEq(fired1, true);
    -assertEq(fired2, true);
    -
    -// Full GC with no debuggees
    -reset();
    -dbg1.removeAllDebuggees();
    -dbg2.removeAllDebuggees();
    -gc();
    -assertEq(fired1, false);
    -assertEq(fired2, false);
    -
    -// One debugger with multiple debuggees in different zones.
    -
    -dbg1.addDebuggee(root1);
    -dbg1.addDebuggee(root2);
    -
    -// Just debuggee 1
    -reset();
    -root1.eval(`gc(this)`);
    -assertEq(fired1, true);
    -assertEq(fired2, false);
    -
    -// Just debuggee 2
    -reset();
    -root2.eval(`gc(this)`);
    -assertEq(fired1, true);
    -assertEq(fired2, false);
    -
    -// All debuggees
    -reset();
    -gc();
    -assertEq(fired1, true);
    -assertEq(fired2, false);
    diff --git a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-03.js b/js/src/jit-test/tests/debug/Memory-onGarbageCollection-03.js
    deleted file mode 100644
    index 7a748bd151ae..000000000000
    --- a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-03.js
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -// Test that the onGarbageCollection hook is not reentrant.
    -
    -gczeal(0);
    -
    -const root = newGlobal();
    -const dbg = new Debugger();
    -const wrappedRoot = dbg.addDebuggee(root)
    -
    -let timesFired = 0;
    -
    -dbg.memory.onGarbageCollection = _ => {
    -  timesFired++;
    -  root.eval(`gc()`);
    -}
    -
    -root.eval(`gc()`);
    -
    -assertEq(timesFired, 1);
    diff --git a/js/xpconnect/tests/chrome/chrome.ini b/js/xpconnect/tests/chrome/chrome.ini
    index 716838cbe0ed..1b1189ebadee 100644
    --- a/js/xpconnect/tests/chrome/chrome.ini
    +++ b/js/xpconnect/tests/chrome/chrome.ini
    @@ -92,6 +92,7 @@ skip-if = buildapp == 'mulet'
     [test_localstorage_with_nsEp.xul]
     [test_matches.xul]
     [test_nodelists.xul]
    +[test_onGarbageCollection.html]
     [test_paris_weakmap_keys.xul]
     [test_precisegc.xul]
     [test_sandboxImport.xul]
    diff --git a/js/xpconnect/tests/chrome/test_onGarbageCollection.html b/js/xpconnect/tests/chrome/test_onGarbageCollection.html
    new file mode 100644
    index 000000000000..06cb3fdf418f
    --- /dev/null
    +++ b/js/xpconnect/tests/chrome/test_onGarbageCollection.html
    @@ -0,0 +1,35 @@
    +
    +
    +  
    +    Bug 1150253 - Sanity test for the SpiderMonkey Debugger API's onGarbageCollection hook
    +    
    +  
    +  
    +    Mozilla Bug 1150253
    +
    +    
    +  
    +
    diff --git a/js/xpconnect/tests/unit/head_ongc.js b/js/xpconnect/tests/unit/head_ongc.js
    new file mode 100644
    index 000000000000..85989f1d9d4b
    --- /dev/null
    +++ b/js/xpconnect/tests/unit/head_ongc.js
    @@ -0,0 +1,41 @@
    +const Cc = Components.classes;
    +const Ci = Components.interfaces;
    +const Cu = Components.utils;
    +
    +Cu.import("resource://gre/modules/Services.jsm");
    +Cu.import("resource://gre/modules/jsdebugger.jsm");
    +
    +const testingFunctions = Cu.getJSTestingFunctions();
    +const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
    +
    +function addTestingFunctionsToGlobal(global) {
    +  for (let k in testingFunctions) {
    +    global[k] = testingFunctions[k];
    +  }
    +  global.print = do_print;
    +  global.newGlobal = newGlobal;
    +  addDebuggerToGlobal(global);
    +}
    +
    +function newGlobal() {
    +  const global = new Cu.Sandbox(systemPrincipal, { freshZone: true });
    +  addTestingFunctionsToGlobal(global);
    +  return global;
    +}
    +
    +addTestingFunctionsToGlobal(this);
    +
    +function executeSoon(f) {
    +  Services.tm.mainThread.dispatch({ run: f },
    +                                  Ci.nsIThread.DISPATCH_NORMAL);
    +}
    +
    +// The onGarbageCollection tests don't play well gczeal settings and lead to
    +// intermittents.
    +if (typeof gczeal == "function") {
    +  gczeal(0);
    +}
    +
    +// Make sure to GC before we start the test, so that no zones are scheduled for
    +// GC before we start testing onGarbageCollection hooks.
    +gc();
    diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-01.js b/js/xpconnect/tests/unit/test_onGarbageCollection-01.js
    new file mode 100644
    index 000000000000..138f699f941d
    --- /dev/null
    +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-01.js
    @@ -0,0 +1,64 @@
    +// Test basic usage of onGarbageCollection
    +
    +const root = newGlobal();
    +const dbg = new Debugger();
    +const wrappedRoot = dbg.addDebuggee(root)
    +
    +const NUM_SLICES = root.NUM_SLICES = 10;
    +
    +let fired = false;
    +let slicesFound = 0;
    +
    +dbg.memory.onGarbageCollection = data => {
    +  fired = true;
    +
    +  print("Got onGarbageCollection: " + JSON.stringify(data, null, 2));
    +
    +  equal(typeof data.reason, "string");
    +  equal(typeof data.nonincrementalReason == "string" || data.nonincrementalReason === null,
    +        true);
    +
    +  let lastStartTimestamp = 0;
    +  for (let i = 0; i < data.collections.length; i++) {
    +    let slice = data.collections[i];
    +
    +    equal(slice.startTimestamp >= lastStartTimestamp, true);
    +    equal(slice.startTimestamp <= slice.endTimestamp, true);
    +
    +    lastStartTimestamp = slice.startTimestamp;
    +  }
    +
    +  equal(data.collections.length >= 1, true);
    +  slicesFound += data.collections.length;
    +}
    +
    +function run_test() {
    +  do_test_pending();
    +
    +  root.eval(
    +    `
    +    this.allocs = [];
    +
    +    // GC slices
    +    for (var i = 0; i < NUM_SLICES; i++) {
    +      this.allocs.push({});
    +      gcslice();
    +    }
    +
    +    // Full GC
    +    this.allocs.push({});
    +    gc();
    +    `
    +  );
    +
    +  executeSoon(() => {
    +    equal(fired, true, "The GC hook should have fired at least once");
    +
    +    // NUM_SLICES + 1 full gc + however many were triggered naturally (due to
    +    // whatever zealousness setting).
    +    print("Found " + slicesFound + " slices");
    +    equal(slicesFound >= NUM_SLICES + 1, true);
    +
    +    do_test_finished();
    +  });
    +}
    diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-02.js b/js/xpconnect/tests/unit/test_onGarbageCollection-02.js
    new file mode 100644
    index 000000000000..a8bf22c675b8
    --- /dev/null
    +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-02.js
    @@ -0,0 +1,94 @@
    +// Test multiple debuggers, GCs, and zones interacting with each other.
    +//
    +// Note: when observing both globals, but GC'ing in only one, we don't test that
    +// we *didn't* GC in the other zone because GCs are finicky and unreliable. That
    +// used to work when this was a jit-test, but in the process of migrating to
    +// xpcshell, we lost some amount of reliability and determinism.
    +
    +const root1 = newGlobal();
    +const dbg1 = new Debugger();
    +dbg1.addDebuggee(root1)
    +
    +const root2 = newGlobal();
    +const dbg2 = new Debugger();
    +dbg2.addDebuggee(root2)
    +
    +let fired1 = false;
    +let fired2 = false;
    +dbg1.memory.onGarbageCollection = _ => fired1 = true;
    +dbg2.memory.onGarbageCollection = _ => fired2 = true;
    +
    +function reset() {
    +  fired1 = false;
    +  fired2 = false;
    +}
    +
    +function run_test() {
    +  do_test_pending();
    +
    +  gc();
    +  executeSoon(() => {
    +    reset();
    +
    +    // GC 1 only
    +    root1.eval(`gc(this)`);
    +    executeSoon(() => {
    +      equal(fired1, true);
    +
    +      // GC 2 only
    +      reset();
    +      root2.eval(`gc(this)`);
    +      executeSoon(() => {
    +        equal(fired2, true);
    +
    +        // Full GC
    +        reset();
    +        gc();
    +        executeSoon(() => {
    +          equal(fired1, true);
    +          equal(fired2, true);
    +
    +          // Full GC with no debuggees
    +          reset();
    +          dbg1.removeAllDebuggees();
    +          dbg2.removeAllDebuggees();
    +          gc();
    +          executeSoon(() => {
    +            equal(fired1, false);
    +            equal(fired2, false);
    +
    +            // One debugger with multiple debuggees in different zones.
    +
    +            dbg1.addDebuggee(root1);
    +            dbg1.addDebuggee(root2);
    +
    +            // Just debuggee 1
    +            reset();
    +            root1.eval(`gc(this)`);
    +            executeSoon(() => {
    +              equal(fired1, true);
    +              equal(fired2, false);
    +
    +              // Just debuggee 2
    +              reset();
    +              root2.eval(`gc(this)`);
    +              executeSoon(() => {
    +                equal(fired1, true);
    +                equal(fired2, false);
    +
    +                // All debuggees
    +                reset();
    +                gc();
    +                executeSoon(() => {
    +                  equal(fired1, true);
    +                  equal(fired2, false);
    +                  do_test_finished();
    +                });
    +              });
    +            });
    +          });
    +        });
    +      });
    +    });
    +  });
    +}
    diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-03.js b/js/xpconnect/tests/unit/test_onGarbageCollection-03.js
    new file mode 100644
    index 000000000000..1c7f158a76fa
    --- /dev/null
    +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-03.js
    @@ -0,0 +1,35 @@
    +// Test that the onGarbageCollection hook is not reentrant.
    +
    +
    +function run_test() {
    +  do_test_pending();
    +
    +  const root = newGlobal();
    +  const dbg = new Debugger();
    +  const wrappedRoot = dbg.addDebuggee(root)
    +
    +  let fired = true;
    +  let depth = 0;
    +
    +  dbg.memory.onGarbageCollection = _ => {
    +    fired = true;
    +
    +    equal(depth, 0);
    +    depth++;
    +    try {
    +      root.eval(`gc()`);
    +    } finally {
    +      equal(depth, 1);
    +      depth--;
    +    }
    +  }
    +
    +  root.eval(`gc()`);
    +
    +  executeSoon(() => {
    +    ok(fired);
    +    equal(depth, 0);
    +    dbg.memory.onGarbageCollection = undefined;
    +    do_test_finished();
    +  });
    +}
    diff --git a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-04.js b/js/xpconnect/tests/unit/test_onGarbageCollection-04.js
    similarity index 52%
    rename from js/src/jit-test/tests/debug/Memory-onGarbageCollection-04.js
    rename to js/xpconnect/tests/unit/test_onGarbageCollection-04.js
    index 53a70f4e5371..146ed687028b 100644
    --- a/js/src/jit-test/tests/debug/Memory-onGarbageCollection-04.js
    +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-04.js
    @@ -23,29 +23,45 @@
     // same time that we are preventing reentrancy into debuggeree's
     // onGarbageCollection hook.
     
    -gczeal(0);
    +function run_test() {
    +  do_test_pending();
     
    -const debuggeree = newGlobal();
    -const debuggee = debuggeree.debuggee = newGlobal();
    +  const debuggeree = newGlobal();
    +  const debuggee = debuggeree.debuggee = newGlobal();
     
    -debuggeree.eval(
    -  `
    -  const dbg = new Debugger(this.debuggee);
    +  debuggeree.eval(
    +    `
    +    const dbg = new Debugger(this.debuggee);
    +    let fired = 0;
    +    dbg.memory.onGarbageCollection = _ => {
    +      fired++;
    +      gc(this);
    +    };
    +    `
    +  );
    +
    +  const dbg = new Debugger(debuggeree);
       let fired = 0;
       dbg.memory.onGarbageCollection = _ => {
         fired++;
    -    gc(this);
       };
    -  `
    -);
     
    -const dbg = new Debugger(debuggeree);
    -let fired = 0;
    -dbg.memory.onGarbageCollection = _ => {
    -  fired++;
    -};
    +  debuggee.eval(`gc(this)`);
     
    -debuggee.eval(`gc(this)`);
    +  // Let first onGarbageCollection runnable get run.
    +  executeSoon(() => {
     
    -assertEq(debuggeree.fired, 1);
    -assertEq(fired, 1);
    +    // Let second onGarbageCollection runnable get run.
    +    executeSoon(() => {
    +
    +      // Even though we request GC'ing a single zone, we can't rely on that
    +      // behavior and both zones could have been scheduled for gc for both
    +      // gc(this) calls.
    +      ok(debuggeree.fired >= 1);
    +      ok(fired >= 1);
    +
    +      debuggeree.dbg.enabled = dbg.enabled = false;
    +      do_test_finished();
    +    });
    +  });
    +}
    diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini
    index 5c446da9f8d6..6d3d4b15771d 100644
    --- a/js/xpconnect/tests/unit/xpcshell.ini
    +++ b/js/xpconnect/tests/unit/xpcshell.ini
    @@ -66,6 +66,14 @@ support-files =
     [test_interposition.js]
     [test_isModuleLoaded.js]
     [test_js_weak_references.js]
    +[test_onGarbageCollection-01.js]
    +head = head_ongc.js
    +[test_onGarbageCollection-02.js]
    +head = head_ongc.js
    +[test_onGarbageCollection-03.js]
    +head = head_ongc.js
    +[test_onGarbageCollection-04.js]
    +head = head_ongc.js
     [test_reflect_parse.js]
     [test_localeCompare.js]
     # Bug 676965: test fails consistently on Android
    
    From 966e2c0ec18edeed59ecc87042ad2481cc0f8e7b Mon Sep 17 00:00:00 2001
    From: "Byron Campen [:bwc]" 
    Date: Wed, 22 Apr 2015 10:18:33 -0700
    Subject: [PATCH 207/241] Bug 1155089: Fix hazard analysis bustage on a CLOSED
     TREE. r=bustage
    
    ---
     media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
    index 06d007cabdb1..7e15811343c6 100644
    --- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
    +++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
    @@ -860,7 +860,7 @@ UnsetTrackId(MediaStreamGraphImpl* graph) {
     #ifndef USE_FAKE_MEDIA_STREAMS
       class Message : public ControlMessage {
       public:
    -    Message(PipelineListener* listener) :
    +    explicit Message(PipelineListener* listener) :
           ControlMessage(nullptr), listener_(listener) {}
         virtual void Run() override
         {
    
    From ca0017ff2462b8b94a24890a85cc2f40326c2d87 Mon Sep 17 00:00:00 2001
    From: Ryan VanderMeulen 
    Date: Wed, 22 Apr 2015 13:52:36 -0400
    Subject: [PATCH 208/241] Bug 1028716 - Adjust the OSX fails-if condition for
     progress-orient-vertical.html to only apply to 10.6. CLOSED TREE
    
    ---
     layout/reftests/forms/progress/reftest.list | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/layout/reftests/forms/progress/reftest.list b/layout/reftests/forms/progress/reftest.list
    index 3c7d13828b3b..cedb76656441 100644
    --- a/layout/reftests/forms/progress/reftest.list
    +++ b/layout/reftests/forms/progress/reftest.list
    @@ -30,7 +30,7 @@ skip-if(B2G||Mulet) == bar-pseudo-element-vertical.html bar-pseudo-element-verti
     #     it the default for all channels
     default-preferences pref(layout.css.vertical-text.enabled,true)
     != progress-orient-horizontal.html progress-orient-vertical.html
    -fails-if(!cocoaWidget) != progress-orient-vertical.html progress-orient-vertical-rtl.html # only OS X currently has direction-dependent rendering here
    +fails-if(!cocoaWidget||OSX==1010) != progress-orient-vertical.html progress-orient-vertical-rtl.html # only OS X currently has direction-dependent rendering here
     == progress-orient-block.html progress-orient-vertical.html
     == progress-orient-inline.html progress-orient-horizontal.html
     == progress-vlr.html progress-orient-vertical.html
    
    From 2579661679228923838eac20bd250edb628eb201 Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 09:49:07 -0700
    Subject: [PATCH 209/241] Bug 1065657 - Allow multiple Debuggers to track
     allocations at the same time; r=shu
    
    ---
     js/src/doc/Debugger/Debugger.Memory.md        |  18 ++
     js/src/doc/Debugger/config.sh                 |  12 +-
     .../Memory-trackingAllocationSites-03.js      | 133 +++++++++-----
     js/src/jscompartment.h                        |   1 +
     js/src/vm/Debugger.cpp                        | 163 ++++++++++++++----
     js/src/vm/Debugger.h                          |  33 ++++
     js/src/vm/DebuggerMemory.cpp                  |  54 +++---
     js/src/vm/GlobalObject.cpp                    |   2 +-
     js/src/vm/GlobalObject.h                      |   2 +-
     js/src/vm/SavedStacks.cpp                     |  14 +-
     10 files changed, 310 insertions(+), 122 deletions(-)
    
    diff --git a/js/src/doc/Debugger/Debugger.Memory.md b/js/src/doc/Debugger/Debugger.Memory.md
    index 106e8e043f08..6362fedfbf63 100644
    --- a/js/src/doc/Debugger/Debugger.Memory.md
    +++ b/js/src/doc/Debugger/Debugger.Memory.md
    @@ -31,6 +31,12 @@ allocated, if:
     - dbg.memory.[trackingAllocationSites][tracking-allocs] is
       set to `true`.
     
    +- A [Bernoulli trial][bernoulli-trial] succeeds, with probability equal to the
    +  maximum of
    +  [`d.memory.allocationSamplingProbability`][alloc-sampling-probability] of all
    +  `Debugger` instances `d` that are observing the global that this object is
    +  allocated within the scope of.
    +
     Given a [`Debugger.Object`][object] instance dobj referring to some
     object, dobj.[allocationSite][allocation-site] returns a
     [saved call stack][saved-frame] indicating where dobj's referent was
    @@ -80,6 +86,18 @@ following accessor properties from its prototype:
         [`Debugger.Object.prototype.allocationSite`][allocation-site] accessor
         property.
     
    +allocationSamplingProbability
    +:   A number between 0 and 1 that indicates the probability with which each new
    +    allocation should be entered into the allocations log. 0 is equivalent to
    +    "never", 1 is "always", and .05 would be "one out of twenty".
    +
    +    The default is 1, or logging every allocation.
    +
    +    Note that in the presence of multiple Debugger instances
    +    observing the same allocations within a global's scope, the maximum
    +    allocationSamplingProbability of all the
    +    Debuggers is used.
    +
     maxAllocationsLogLength
     :   The maximum number of allocation sites to accumulate in the allocations log
         at a time. This accessor can be both fetched and stored to. Its default
    diff --git a/js/src/doc/Debugger/config.sh b/js/src/doc/Debugger/config.sh
    index 9f041a21dab7..a15fa87e0bcf 100644
    --- a/js/src/doc/Debugger/config.sh
    +++ b/js/src/doc/Debugger/config.sh
    @@ -39,11 +39,12 @@ markdown Debugger.Source.md Debugger-API/Debugger.Source
       label 'source'                                "Debugger.Source"
     
     markdown Debugger.Memory.md Debugger-API/Debugger.Memory
    -  label 'memory'                                "Debugger.Memory"
    -  label 'tracking-allocs' '#trackingallocationsites' "Debugger.Memory: trackingAllocationSites"
    -  label 'drain-alloc-log' '#drain-alloc-log'    "Debugger.Memory: drainAllocationsLog"
    -  label 'max-alloc-log' '#max-alloc-log'        "Debugger.Memory: maxAllocationsLogLength"
    -  label 'take-census'   '#take-census'          "Debugger.Memory: takeCensus"
    +  label 'memory'                                                   "Debugger.Memory"
    +  label 'tracking-allocs'            '#trackingallocationsites'    "Debugger.Memory: trackingAllocationSites"
    +  label 'drain-alloc-log'            '#drain-alloc-log'            "Debugger.Memory: drainAllocationsLog"
    +  label 'max-alloc-log'              '#max-alloc-log'              "Debugger.Memory: maxAllocationsLogLength"
    +  label 'alloc-sampling-probability' '#alloc-sampling-probability' "Debugger.Memory: allocationSamplingProbability"
    +  label 'take-census'                '#take-census'                "Debugger.Memory: takeCensus"
     
     markdown Tutorial-Debugger-Statement.md Debugger-API/Tutorial-Debugger-Statement
       label 'tut debugger'                          "Tutorial: the debugger; statement"
    @@ -62,3 +63,4 @@ resource 'img-alloc-plot'         alloc-plot-console.png             $RBASE/8461
     # External links:
     absolute-label 'protocol' https://wiki.mozilla.org/Remote_Debugging_Protocol "Remote Debugging Protocol"
     absolute-label 'saved-frame' https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/SavedFrame "SavedFrame"
    +absolute-label 'bernoulli-trial' https://en.wikipedia.org/wiki/Bernoulli_trial "Bernoulli Trial"
    diff --git a/js/src/jit-test/tests/debug/Memory-trackingAllocationSites-03.js b/js/src/jit-test/tests/debug/Memory-trackingAllocationSites-03.js
    index 48150bccd1d3..08b904777150 100644
    --- a/js/src/jit-test/tests/debug/Memory-trackingAllocationSites-03.js
    +++ b/js/src/jit-test/tests/debug/Memory-trackingAllocationSites-03.js
    @@ -1,20 +1,10 @@
    -// Test that multiple Debuggers behave reasonably. Since we're not keeping a
    -// per-compartment count of how many Debuggers have requested allocation
    -// tracking, assert that attempts to request allocation tracking from multiple
    -// debuggers throws.
    +// Test that multiple Debuggers behave reasonably.
     
     load(libdir + "asserts.js");
     
    -let root1 = newGlobal();
    -let root2 = newGlobal();
    +let dbg1, dbg2, root1, root2;
     
    -let dbg1 = new Debugger();
    -let dbg2 = new Debugger();
    -
    -let d1r1 = dbg1.addDebuggee(root1);
    -let d2r1 = dbg2.addDebuggee(root1);
    -
    -let wrappedObj, allocationSite;
    +function FakeMetadata() {}
     
     function isTrackingAllocations(global, dbgObj) {
       const site = dbgObj.makeDebuggeeValue(global.eval("({})")).allocationSite;
    @@ -24,41 +14,94 @@ function isTrackingAllocations(global, dbgObj) {
       return !!site;
     }
     
    -// Can't track allocations if a different debugger is already tracking them.
    -dbg1.memory.trackingAllocationSites = true;
    -assertThrowsInstanceOf(() => dbg2.memory.trackingAllocationSites = true,
    -                       Error);
    +function test(name, fn) {
    +  print();
    +  print(name);
     
    -// Removing root as a debuggee from dbg1 should disable the allocation hook.
    -dbg1.removeDebuggee(root1);
    -assertEq(isTrackingAllocations(root1, d1r1), false);
    +  // Reset state.
    +  root1 = newGlobal();
    +  root2 = newGlobal();
    +  dbg1 = new Debugger;
    +  dbg2 = new Debugger;
     
    -// Tracking allocations in dbg2 should work now that dbg1 isn't debugging root1.
    -dbg2.memory.trackingAllocationSites = true;
    -assertEq(isTrackingAllocations(root1, d2r1), true);
    +  // Run the test.
    +  fn();
     
    -// Adding root back as a debuggee in dbg1 should fail now because it will
    -// attempt to track allocations in root, but dbg2 is already doing that.
    -assertThrowsInstanceOf(() => dbg1.addDebuggee(root1),
    -                       Error);
    -assertEq(dbg1.hasDebuggee(root1), false);
    +  print("  OK");
    +}
     
    -// Adding a new debuggee to a debugger that is tracking allocations should
    -// enable the hook for the new debuggee.
    -dbg2.removeDebuggee(root1);
    -d1r1 = dbg1.addDebuggee(root1);
    -assertEq(isTrackingAllocations(root1, d1r1), true);
    +test("Can track allocations even if a different debugger is already tracking " +
    +     "them.",
    +     () => {
    +       let d1r1 = dbg1.addDebuggee(root1);
    +       let d2r1 = dbg2.addDebuggee(root1);
    +       dbg1.memory.trackingAllocationSites = true;
    +       dbg2.memory.trackingAllocationSites = true;
    +       assertEq(isTrackingAllocations(root1, d1r1), true);
    +       assertEq(isTrackingAllocations(root1, d2r1), true);
    +     });
     
    -// Setting trackingAllocationSites to true should throw if the debugger cannot
    -// install the allocation hooks for *every* debuggee.
    -dbg1.memory.trackingAllocationSites = true;
    -dbg1.addDebuggee(root1);
    -dbg2.memory.trackingAllocationSites = false;
    -let d2r2 = dbg2.addDebuggee(root2);
    -dbg2.addDebuggee(root1);
    -assertThrowsInstanceOf(() => dbg2.memory.trackingAllocationSites = true,
    -                       Error);
    +test("Removing root1 as a debuggee from all debuggers should disable the " +
    +     "allocation hook.",
    +     () => {
    +       dbg1.memory.trackingAllocationSites = true;
    +       let d1r1 = dbg1.addDebuggee(root1);
    +       dbg1.removeAllDebuggees();
    +       assertEq(isTrackingAllocations(root1, d1r1), false);
    +     });
     
    -// And after it throws, its trackingAllocationSites accessor should reflect that
    -// allocation site tracking is still disabled in that Debugger.
    -assertEq(isTrackingAllocations(root2, d2r2), false);
    +test("Adding a new debuggee to a debugger that is tracking allocations should " +
    +     "enable the hook for the new debuggee.",
    +     () => {
    +       dbg1.memory.trackingAllocationSites = true;
    +       let d1r1 = dbg1.addDebuggee(root1);
    +       assertEq(isTrackingAllocations(root1, d1r1), true);
    +     });
    +
    +test("Setting trackingAllocationSites to true should throw if the debugger " +
    +     "cannot install the allocation hooks for *every* debuggee.",
    +     () => {
    +       let d1r1 = dbg1.addDebuggee(root1);
    +       let d1r2 = dbg1.addDebuggee(root2);
    +
    +       // Can't install allocation hooks for root2 with this set.
    +       root2.setObjectMetadataCallback(function () { return new FakeMetadata; });
    +
    +       assertThrowsInstanceOf(() => dbg1.memory.trackingAllocationSites = true,
    +                              Error);
    +
    +       // And after it throws, its trackingAllocationSites accessor should reflect that
    +       // allocation site tracking is still disabled in that Debugger.
    +       assertEq(dbg1.memory.trackingAllocationSites, false);
    +       assertEq(isTrackingAllocations(root1, d1r1), false);
    +       assertEq(isTrackingAllocations(root2, d1r2), false);
    +     });
    +
    +test("A Debugger isn't tracking allocation sites when disabled.",
    +     () => {
    +       dbg1.memory.trackingAllocationSites = true;
    +       let d1r1 = dbg1.addDebuggee(root1);
    +
    +       assertEq(isTrackingAllocations(root1, d1r1), true);
    +       dbg1.enabled = false;
    +       assertEq(isTrackingAllocations(root1, d1r1), false);
    +     });
    +
    +test("Re-enabling throws an error if we can't reinstall allocations tracking " +
    +     "for all debuggees.",
    +     () => {
    +       dbg1.enabled = false
    +       dbg1.memory.trackingAllocationSites = true;
    +       let d1r1 = dbg1.addDebuggee(root1);
    +       let d1r2 = dbg1.addDebuggee(root2);
    +
    +       // Can't install allocation hooks for root2 with this set.
    +       root2.setObjectMetadataCallback(function () { return new FakeMetadata; });
    +
    +       assertThrowsInstanceOf(() => dbg1.enabled = true,
    +                              Error);
    +
    +       assertEq(dbg1.enabled, false);
    +       assertEq(isTrackingAllocations(root1, d1r1), false);
    +       assertEq(isTrackingAllocations(root2, d1r2), false);
    +     });
    diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h
    index b9c3c94e2643..efe69ee9c970 100644
    --- a/js/src/jscompartment.h
    +++ b/js/src/jscompartment.h
    @@ -435,6 +435,7 @@ struct JSCompartment
         void fixupGlobal();
     
         bool hasObjectMetadataCallback() const { return objectMetadataCallback; }
    +    js::ObjectMetadataCallback getObjectMetadataCallback() const { return objectMetadataCallback; }
         void setObjectMetadataCallback(js::ObjectMetadataCallback callback);
         void forgetObjectMetadataCallback() {
             objectMetadataCallback = nullptr;
    diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
    index 566c48cb4f73..46eb86dbaf4d 100644
    --- a/js/src/vm/Debugger.cpp
    +++ b/js/src/vm/Debugger.cpp
    @@ -1659,6 +1659,8 @@ bool
     Debugger::appendAllocationSite(JSContext* cx, HandleObject obj, HandleSavedFrame frame,
                                    int64_t when)
     {
    +    MOZ_ASSERT(trackingAllocationSites);
    +
         AutoCompartment ac(cx, object);
         RootedObject wrappedFrame(cx, frame);
         if (!cx->compartment()->wrap(cx, &wrappedFrame))
    @@ -2128,6 +2130,96 @@ Debugger::updateObservesAsmJSOnDebuggees(IsObserving observing)
     }
     
     
    +
    +/*** Allocations Tracking *************************************************************************/
    +
    +/* static */ bool
    +Debugger::cannotTrackAllocations(const GlobalObject& global)
    +{
    +    auto existingCallback = global.compartment()->getObjectMetadataCallback();
    +    return existingCallback && existingCallback != SavedStacksMetadataCallback;
    +}
    +
    +/* static */ bool
    +Debugger::isObservedByDebuggerTrackingAllocations(const GlobalObject& debuggee)
    +{
    +    if (auto* v = debuggee.getDebuggers()) {
    +        Debugger** p;
    +        for (p = v->begin(); p != v->end(); p++) {
    +            if ((*p)->trackingAllocationSites) {
    +                return true;
    +            }
    +        }
    +    }
    +
    +    return false;
    +}
    +
    +/* static */ bool
    +Debugger::addAllocationsTracking(JSContext* cx, GlobalObject& debuggee)
    +{
    +    // Precondition: the given global object is being observed by at least one
    +    // Debugger that is tracking allocations.
    +    MOZ_ASSERT(isObservedByDebuggerTrackingAllocations(debuggee));
    +
    +    if (Debugger::cannotTrackAllocations(debuggee)) {
    +        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
    +                             JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET);
    +        return false;
    +    }
    +
    +    debuggee.compartment()->setObjectMetadataCallback(SavedStacksMetadataCallback);
    +    return true;
    +}
    +
    +/* static */ void
    +Debugger::removeAllocationsTracking(GlobalObject& global)
    +{
    +    // If there are still Debuggers that are observing allocations, we cannot
    +    // remove the metadata callback yet.
    +    if (isObservedByDebuggerTrackingAllocations(global))
    +        return;
    +
    +    global.compartment()->forgetObjectMetadataCallback();
    +}
    +
    +bool
    +Debugger::addAllocationsTrackingForAllDebuggees(JSContext* cx)
    +{
    +    MOZ_ASSERT(trackingAllocationSites);
    +
    +    // We don't want to end up in a state where we added allocations
    +    // tracking to some of our debuggees, but failed to do so for
    +    // others. Before attempting to start tracking allocations in *any* of
    +    // our debuggees, ensure that we will be able to track allocations for
    +    // *all* of our debuggees.
    +    for (WeakGlobalObjectSet::Range r = debuggees.all(); !r.empty(); r.popFront()) {
    +        if (Debugger::cannotTrackAllocations(*r.front().get())) {
    +            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
    +                                 JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET);
    +            return false;
    +        }
    +    }
    +
    +    for (WeakGlobalObjectSet::Range r = debuggees.all(); !r.empty(); r.popFront()) {
    +        // This should always succeed, since we already checked for the
    +        // error case above.
    +        MOZ_ALWAYS_TRUE(Debugger::addAllocationsTracking(cx, *r.front().get()));
    +    }
    +
    +    return true;
    +}
    +
    +void
    +Debugger::removeAllocationsTrackingForAllDebuggees()
    +{
    +    for (WeakGlobalObjectSet::Range r = debuggees.all(); !r.empty(); r.popFront()) {
    +        Debugger::removeAllocationsTracking(*r.front().get());
    +    }
    +    emptyAllocationsLog();
    +}
    +
    +
     
     /*** Debugger JSObjects **************************************************************************/
     
    @@ -2465,6 +2557,17 @@ Debugger::setEnabled(JSContext* cx, unsigned argc, Value* vp)
         dbg->enabled = ToBoolean(args[0]);
     
         if (wasEnabled != dbg->enabled) {
    +        if (dbg->trackingAllocationSites) {
    +            if (wasEnabled) {
    +                dbg->removeAllocationsTrackingForAllDebuggees();
    +            } else {
    +                if (!dbg->addAllocationsTrackingForAllDebuggees(cx)) {
    +                    dbg->enabled = false;
    +                    return false;
    +                }
    +            }
    +        }
    +
             for (Breakpoint* bp = dbg->firstBreakpoint(); bp; bp = bp->nextInDebugger()) {
                 if (!wasEnabled)
                     bp->site->inc(cx->runtime()->defaultFreeOp());
    @@ -3052,28 +3155,14 @@ Debugger::addDebuggeeGlobal(JSContext* cx, Handle global)
             }
         }
     
    -    /*
    -     * If we are tracking allocation sites, we need to add the object metadata
    -     * callback to this debuggee compartment.
    -     */
    -    bool setMetadataCallback = false;
    -    if (trackingAllocationSites) {
    -        if (debuggeeCompartment->hasObjectMetadataCallback()) {
    -            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
    -                                 JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET);
    -            return false;
    -        }
    -
    -        debuggeeCompartment->setObjectMetadataCallback(SavedStacksMetadataCallback);
    -        setMetadataCallback = true;
    -    }
    -
         /*
          * For global to become this js::Debugger's debuggee:
          * - global must be in this->debuggees,
          * - this js::Debugger must be in global->getDebuggers(), and
          * - JSCompartment::isDebuggee()'s bit must be set.
    -     * All three indications must be kept consistent.
    +     * - If we are tracking allocations, the SavedStacksMetadataCallback must be
    +     *   installed for this compartment.
    +     * All four indications must be kept consistent.
          */
         AutoCompartment ac(cx, global);
         GlobalObject::DebuggerVector* v = GlobalObject::getOrCreateDebuggers(cx, global);
    @@ -3083,12 +3172,14 @@ Debugger::addDebuggeeGlobal(JSContext* cx, Handle global)
             if (!debuggees.put(global)) {
                 ReportOutOfMemory(cx);
             } else {
    -            debuggeeCompartment->setIsDebuggee();
    -            debuggeeCompartment->updateDebuggerObservesAsmJS();
    -            if (!observesAllExecution())
    -                return true;
    -            if (ensureExecutionObservabilityOfCompartment(cx, debuggeeCompartment))
    -                return true;
    +            if (!trackingAllocationSites || Debugger::addAllocationsTracking(cx, *global)) {
    +                debuggeeCompartment->setIsDebuggee();
    +                debuggeeCompartment->updateDebuggerObservesAsmJS();
    +                if (!observesAllExecution())
    +                    return true;
    +                if (ensureExecutionObservabilityOfCompartment(cx, debuggeeCompartment))
    +                    return true;
    +            }
     
                 /* Maintain consistency on error. */
                 debuggees.remove(global);
    @@ -3098,10 +3189,6 @@ Debugger::addDebuggeeGlobal(JSContext* cx, Handle global)
             v->popBack();
         }
     
    -    /* Don't leave the object metadata hook set if we OOM'd. */
    -    if (setMetadataCallback)
    -        debuggeeCompartment->forgetObjectMetadataCallback();
    -
         return false;
     }
     
    @@ -3168,10 +3255,7 @@ Debugger::removeDebuggeeGlobal(FreeOp* fop, GlobalObject* global,
          * metadata callback from this global's compartment.
          */
         if (trackingAllocationSites)
    -        global->compartment()->forgetObjectMetadataCallback();
    -
    -    // Clear out all object metadata in the compartment.
    -    global->compartment()->clearObjectMetadata();
    +        Debugger::removeAllocationsTracking(*global);
     
         if (global->getDebuggers()->empty()) {
             global->compartment()->unsetIsDebuggee();
    @@ -3181,6 +3265,7 @@ Debugger::removeDebuggeeGlobal(FreeOp* fop, GlobalObject* global,
         }
     }
     
    +
     static inline ScriptSourceObject* GetSourceReferent(JSObject* obj);
     
     /*
    @@ -6687,15 +6772,29 @@ DebuggerObject_getGlobal(JSContext* cx, unsigned argc, Value* vp)
         return true;
     }
     
    +static bool
    +null(CallArgs& args)
    +{
    +    args.rval().setNull();
    +    return true;
    +}
    +
     static bool
     DebuggerObject_getAllocationSite(JSContext* cx, unsigned argc, Value* vp)
     {
         THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, "get allocationSite", args, obj);
     
         RootedObject metadata(cx, GetObjectMetadata(obj));
    +    if (!metadata)
    +        return null(args);
    +
    +    metadata = CheckedUnwrap(metadata);
    +    if (!metadata || !SavedFrame::isSavedFrameAndNotProto(*metadata))
    +        return null(args);
    +
         if (!cx->compartment()->wrap(cx, &metadata))
             return false;
    -    args.rval().setObjectOrNull(metadata);
    +    args.rval().setObject(*metadata);
         return true;
     }
     
    diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
    index 4cfd9801b58c..a9e664402ca3 100644
    --- a/js/src/vm/Debugger.h
    +++ b/js/src/vm/Debugger.h
    @@ -299,6 +299,39 @@ class Debugger : private mozilla::LinkedListElement
                                   int64_t when);
         void emptyAllocationsLog();
     
    +    /*
    +     * Return true if there is an existing object metadata callback for the
    +     * given global's compartment that will prevent our instrumentation of
    +     * allocations.
    +     */
    +    static bool cannotTrackAllocations(const GlobalObject& global);
    +
    +    /*
    +     * Return true if the given global is being observed by at least one
    +     * Debugger that is tracking allocations.
    +     */
    +    static bool isObservedByDebuggerTrackingAllocations(const GlobalObject& global);
    +
    +    /*
    +     * Add allocations tracking for objects allocated within the given
    +     * debuggee's compartment. The given debuggee global must be observed by at
    +     * least one Debugger that is enabled and tracking allocations.
    +     */
    +    static bool addAllocationsTracking(JSContext* cx, GlobalObject& debuggee);
    +
    +    /*
    +     * Remove allocations tracking for objects allocated within the given
    +     * global's compartment. This is a no-op if there are still Debuggers
    +     * observing this global and who are tracking allocations.
    +     */
    +    static void removeAllocationsTracking(GlobalObject& global);
    +
    +    /*
    +     * Add or remove allocations tracking for all debuggees.
    +     */
    +    bool addAllocationsTrackingForAllDebuggees(JSContext* cx);
    +    void removeAllocationsTrackingForAllDebuggees();
    +
         /*
          * If this Debugger is enabled, and has a onNewGlobalObject handler, then
          * this link is inserted into the circular list headed by
    diff --git a/js/src/vm/DebuggerMemory.cpp b/js/src/vm/DebuggerMemory.cpp
    index a8e588b5e02d..5d5a59a4a4c4 100644
    --- a/js/src/vm/DebuggerMemory.cpp
    +++ b/js/src/vm/DebuggerMemory.cpp
    @@ -117,10 +117,17 @@ DebuggerMemory::checkThis(JSContext* cx, CallArgs& args, const char* fnName)
      */
     #define THIS_DEBUGGER_MEMORY(cx, argc, vp, fnName, args, memory)        \
         CallArgs args = CallArgsFromVp(argc, vp);                           \
    -    Rooted memory(cx, checkThis(cx, args, fnName));   \
    +    Rooted memory(cx, checkThis(cx, args, fnName));    \
         if (!memory)                                                        \
             return false
     
    +static bool
    +undefined(CallArgs& args)
    +{
    +    args.rval().setUndefined();
    +    return true;
    +}
    +
     /* static */ bool
     DebuggerMemory::setTrackingAllocationSites(JSContext* cx, unsigned argc, Value* vp)
     {
    @@ -131,37 +138,24 @@ DebuggerMemory::setTrackingAllocationSites(JSContext* cx, unsigned argc, Value*
         Debugger* dbg = memory->getDebugger();
         bool enabling = ToBoolean(args[0]);
     
    -    if (enabling == dbg->trackingAllocationSites) {
    -        // Nothing to do here...
    -        args.rval().setUndefined();
    -        return true;
    -    }
    -
    -    if (enabling) {
    -        for (WeakGlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront()) {
    -            JSCompartment* compartment = r.front()->compartment();
    -            if (compartment->hasObjectMetadataCallback()) {
    -                JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
    -                                     JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET);
    -                return false;
    -            }
    -        }
    -    }
    -
    -    for (WeakGlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront()) {
    -        if (enabling) {
    -            r.front()->compartment()->setObjectMetadataCallback(SavedStacksMetadataCallback);
    -        } else {
    -            r.front()->compartment()->forgetObjectMetadataCallback();
    -        }
    -    }
    -
    -    if (!enabling)
    -        dbg->emptyAllocationsLog();
    +    if (enabling == dbg->trackingAllocationSites)
    +        return undefined(args);
     
         dbg->trackingAllocationSites = enabling;
    -    args.rval().setUndefined();
    -    return true;
    +
    +    if (!dbg->enabled)
    +        return undefined(args);
    +
    +    if (enabling) {
    +        if (!dbg->addAllocationsTrackingForAllDebuggees(cx)) {
    +            dbg->trackingAllocationSites = false;
    +            return false;
    +        }
    +    } else {
    +        dbg->removeAllocationsTrackingForAllDebuggees();
    +    }
    +
    +    return undefined(args);
     }
     
     /* static */ bool
    diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp
    index 39c20a3ce7d3..e4da04865631 100644
    --- a/js/src/vm/GlobalObject.cpp
    +++ b/js/src/vm/GlobalObject.cpp
    @@ -511,7 +511,7 @@ GlobalDebuggees_class = {
     };
     
     GlobalObject::DebuggerVector*
    -GlobalObject::getDebuggers()
    +GlobalObject::getDebuggers() const
     {
         Value debuggers = getReservedSlot(DEBUGGERS);
         if (debuggers.isUndefined())
    diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h
    index f90d1bbd1eca..cbc661b6b2c6 100644
    --- a/js/src/vm/GlobalObject.h
    +++ b/js/src/vm/GlobalObject.h
    @@ -690,7 +690,7 @@ class GlobalObject : public NativeObject
          * The collection of Debugger objects debugging this global. If this global
          * is not a debuggee, this returns either nullptr or an empty vector.
          */
    -    DebuggerVector* getDebuggers();
    +    DebuggerVector* getDebuggers() const;
     
         /*
          * The same, but create the empty vector if one does not already
    diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp
    index da1819c8111e..52e5b5aaabe4 100644
    --- a/js/src/vm/SavedStacks.cpp
    +++ b/js/src/vm/SavedStacks.cpp
    @@ -10,6 +10,7 @@
     #include "mozilla/DebugOnly.h"
     #include "mozilla/Maybe.h"
     
    +#include 
     #include 
     
     #include "jsapi.h"
    @@ -1161,22 +1162,19 @@ SavedStacks::chooseSamplingProbability(JSContext* cx)
         if (!dbgs || dbgs->empty())
             return;
     
    -    Debugger* allocationTrackingDbg = nullptr;
         mozilla::DebugOnly begin = dbgs->begin();
     
    +    allocationSamplingProbability = 0;
         for (Debugger** dbgp = dbgs->begin(); dbgp < dbgs->end(); dbgp++) {
             // The set of debuggers had better not change while we're iterating,
             // such that the vector gets reallocated.
             MOZ_ASSERT(dbgs->begin() == begin);
     
    -        if ((*dbgp)->trackingAllocationSites && (*dbgp)->enabled)
    -            allocationTrackingDbg = *dbgp;
    +        if ((*dbgp)->trackingAllocationSites && (*dbgp)->enabled) {
    +            allocationSamplingProbability = std::max((*dbgp)->allocationSamplingProbability,
    +                                                     allocationSamplingProbability);
    +        }
         }
    -
    -    if (!allocationTrackingDbg)
    -        return;
    -
    -    allocationSamplingProbability = allocationTrackingDbg->allocationSamplingProbability;
     }
     
     JSObject*
    
    From 43a628f9e32f0bdd4a12b8c36c9d7f06f6cce132 Mon Sep 17 00:00:00 2001
    From: Andrew McCreight 
    Date: Wed, 22 Apr 2015 11:06:50 -0700
    Subject: [PATCH 210/241] Bug 1156982 - Add separators to BloatView output.
     r=froydnj
    
    This will ensure we properly parse class names containing spaces.
    
    Note that if a class name somehow ends up containing operator| then this will end up again silently failing.
    ---
     build/automationutils.py     | 17 ++++++++++-------
     xpcom/base/nsTraceRefcnt.cpp |  4 ++--
     2 files changed, 12 insertions(+), 9 deletions(-)
    
    diff --git a/build/automationutils.py b/build/automationutils.py
    index baf2e297a42c..61dd75780bf8 100644
    --- a/build/automationutils.py
    +++ b/build/automationutils.py
    @@ -101,12 +101,15 @@ def processSingleLeakFile(leakLogFileName, processType, leakThreshold, ignoreMis
       """Process a single leak log.
       """
     
    -  #                  Per-Inst  Leaked      Total  Rem ...
    -  #   0 TOTAL              17     192  419115886    2 ...
    -  # 833 nsTimerImpl        60     120      24726    2 ...
    -  lineRe = re.compile(r"^\s*\d+\s+(?P\S+)\s+"
    -                      r"(?P-?\d+)\s+(?P-?\d+)\s+"
    -                      r"-?\d+\s+(?P-?\d+)")
    +  #     |              |Per-Inst  Leaked|     Total  Rem|
    +  #   0 |TOTAL         |      17     192| 419115886    2|
    +  # 833 |nsTimerImpl   |      60     120|     24726    2|
    +  # 930 |Foo |      32       8|       100    1|
    +  lineRe = re.compile(r"^\s*\d+ \|"
    +                      r"(?P[^|]+)\|"
    +                      r"\s*(?P-?\d+)\s+(?P-?\d+)\s*\|"
    +                      r"\s*-?\d+\s+(?P-?\d+)")
    +  # The class name can contain spaces. We remove trailing whitespace later.
     
       processString = "%s process:" % processType
       crashedOnPurpose = False
    @@ -125,7 +128,7 @@ def processSingleLeakFile(leakLogFileName, processType, leakThreshold, ignoreMis
             # eg: the leak table header row
             log.info(line.rstrip())
             continue
    -      name = matches.group("name")
    +      name = matches.group("name").rstrip()
           size = int(matches.group("size"))
           bytesLeaked = int(matches.group("bytesLeaked"))
           numLeaked = int(matches.group("numLeaked"))
    diff --git a/xpcom/base/nsTraceRefcnt.cpp b/xpcom/base/nsTraceRefcnt.cpp
    index 5b64361c0821..ee9618633c5d 100644
    --- a/xpcom/base/nsTraceRefcnt.cpp
    +++ b/xpcom/base/nsTraceRefcnt.cpp
    @@ -346,7 +346,7 @@ public:
         fprintf(aOut,
                 "\n" \
                 "     |<----------------Class--------------->|<-----Bytes------>|<----Objects---->|\n" \
    -            "                                              Per-Inst   Leaked    Total      Rem\n");
    +            "     |                                      | Per-Inst   Leaked|   Total      Rem|\n");
     
         this->DumpTotal(aOut);
     
    @@ -363,7 +363,7 @@ public:
     
         if ((stats->mCreates - stats->mDestroys) != 0 ||
             stats->mCreates != 0) {
    -      fprintf(aOut, "%4d %-40.40s %8d %8" PRIu64 " %8" PRIu64 " %8" PRIu64 "\n",
    +      fprintf(aOut, "%4d |%-38.38s| %8d %8" PRIu64 "|%8" PRIu64 " %8" PRIu64"|\n",
                   aIndex + 1, mClassName,
                   (int32_t)mClassSize,
                   (nsCRT::strcmp(mClassName, "TOTAL"))
    
    From 7c042bbbe26de6df364b069b876a6783ac593a4a Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:53 -0700
    Subject: [PATCH 211/241] Bug 1149397 - JS::ubi::Node::edges should return a
     mozilla::UniquePtr; r=jimb
    
    ---
     js/public/UbiNode.h         | 33 ++++++++++++++++++++++-----------
     js/public/UbiNodeTraverse.h |  2 +-
     js/src/vm/UbiNode.cpp       | 25 +++++++++++++++----------
     3 files changed, 38 insertions(+), 22 deletions(-)
    
    diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h
    index 604404c6a383..dadeed3c33d8 100644
    --- a/js/public/UbiNode.h
    +++ b/js/public/UbiNode.h
    @@ -13,6 +13,7 @@
     #include "mozilla/Maybe.h"
     #include "mozilla/MemoryReporting.h"
     #include "mozilla/Move.h"
    +#include "mozilla/UniquePtr.h"
     
     #include "jspubtd.h"
     
    @@ -92,7 +93,7 @@
     // represented by a "rope", a structure that points to the two original
     // strings.
     //
    -
    +//
     // We intend to use ubi::Node to write tools that report memory usage, so it's
     // important that ubi::Node accurately portray how much memory nodes consume.
     // Thus, for example, when data that apparently belongs to multiple nodes is
    @@ -141,11 +142,23 @@
     namespace JS {
     namespace ubi {
     
    -using mozilla::Maybe;
    -
     class Edge;
     class EdgeRange;
     
    +}
    +}
    +
    +namespace mozilla {
    +template<>
    +class DefaultDelete : public JS::DeletePolicy { };
    +}
    +
    +namespace JS {
    +namespace ubi {
    +
    +using mozilla::Maybe;
    +using mozilla::UniquePtr;
    +
     // The base class implemented by each ubi::Node referent type. Subclasses must
     // not add data members to this class.
     class Base {
    @@ -188,13 +201,11 @@ class Base {
         virtual size_t size(mozilla::MallocSizeOf mallocSizeof) const { return 0; }
     
         // Return an EdgeRange that initially contains all the referent's outgoing
    -    // edges. The EdgeRange should be freed with 'js_delete'. (You could use
    -    // ScopedDJSeletePtr to manage it.) On OOM, report an exception
    -    // on |cx| and return nullptr.
    +    // edges. The caller takes ownership of the EdgeRange.
         //
         // If wantNames is true, compute names for edges. Doing so can be expensive
         // in time and memory.
    -    virtual EdgeRange* edges(JSContext* cx, bool wantNames) const = 0;
    +    virtual UniquePtr edges(JSContext* cx, bool wantNames) const = 0;
     
         // Return the Zone to which this node's referent belongs, or nullptr if the
         // referent is not of a type allocated in SpiderMonkey Zones.
    @@ -341,7 +352,7 @@ class Node {
             return base()->size(mallocSizeof);
         }
     
    -    EdgeRange* edges(JSContext* cx, bool wantNames = true) const {
    +    UniquePtr edges(JSContext* cx, bool wantNames = true) const {
             return base()->edges(cx, wantNames);
         }
     
    @@ -521,7 +532,7 @@ class MOZ_STACK_CLASS RootList {
     
     template<>
     struct Concrete : public Base {
    -    EdgeRange* edges(JSContext* cx, bool wantNames) const override;
    +    UniquePtr edges(JSContext* cx, bool wantNames) const override;
         const char16_t* typeName() const override { return concreteTypeName; }
     
       protected:
    @@ -538,7 +549,7 @@ struct Concrete : public Base {
     template
     class TracerConcrete : public Base {
         const char16_t* typeName() const override { return concreteTypeName; }
    -    EdgeRange* edges(JSContext*, bool wantNames) const override;
    +    UniquePtr edges(JSContext*, bool wantNames) const override;
         JS::Zone* zone() const override;
     
       protected:
    @@ -591,7 +602,7 @@ template<>
     class Concrete : public Base {
         const char16_t* typeName() const override;
         size_t size(mozilla::MallocSizeOf mallocSizeOf) const override;
    -    EdgeRange* edges(JSContext* cx, bool wantNames) const override;
    +    UniquePtr edges(JSContext* cx, bool wantNames) const override;
         JS::Zone* zone() const override;
         JSCompartment* compartment() const override;
     
    diff --git a/js/public/UbiNodeTraverse.h b/js/public/UbiNodeTraverse.h
    index 363a7f6b0b89..159de27e7d5c 100644
    --- a/js/public/UbiNodeTraverse.h
    +++ b/js/public/UbiNodeTraverse.h
    @@ -126,7 +126,7 @@ struct BreadthFirst {
                 pending.popFront();
     
                 // Get a range containing all origin's outgoing edges.
    -            js::ScopedJSDeletePtr range(origin.edges(cx, wantNames));
    +            auto range = origin.edges(cx, wantNames);
                 if (!range)
                     return false;
     
    diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp
    index 16d2687eaaad..576e9be08a7c 100644
    --- a/js/src/vm/UbiNode.cpp
    +++ b/js/src/vm/UbiNode.cpp
    @@ -9,7 +9,6 @@
     #include "mozilla/Assertions.h"
     #include "mozilla/Attributes.h"
     #include "mozilla/Scoped.h"
    -#include "mozilla/UniquePtr.h"
     
     #include "jscntxt.h"
     #include "jsobj.h"
    @@ -32,6 +31,7 @@
     #include "vm/Debugger-inl.h"
     
     using mozilla::Some;
    +using mozilla::UniquePtr;
     using JS::HandleValue;
     using JS::Value;
     using JS::ZoneSet;
    @@ -46,10 +46,14 @@ using JS::ubi::TracerConcreteWithCompartment;
     
     // All operations on null ubi::Nodes crash.
     const char16_t* Concrete::typeName() const          { MOZ_CRASH("null ubi::Node"); }
    -EdgeRange* Concrete::edges(JSContext*, bool) const { MOZ_CRASH("null ubi::Node"); }
     JS::Zone* Concrete::zone() const                    { MOZ_CRASH("null ubi::Node"); }
     JSCompartment* Concrete::compartment() const        { MOZ_CRASH("null ubi::Node"); }
     
    +UniquePtr
    +Concrete::edges(JSContext*, bool) const {
    +    MOZ_CRASH("null ubi::Node");
    +}
    +
     size_t
     Concrete::size(mozilla::MallocSizeOf mallocSizeof) const
     {
    @@ -203,16 +207,17 @@ TracerConcrete::zone() const
     }
     
     template
    -EdgeRange*
    +UniquePtr
     TracerConcrete::edges(JSContext* cx, bool wantNames) const {
    -    js::ScopedJSDeletePtr r(js_new(cx));
    -    if (!r)
    +    UniquePtr> range(
    +      cx->new_(cx));
    +    if (!range)
             return nullptr;
     
    -    if (!r->init(cx, ptr, ::js::gc::MapTypeToTraceKind::kind, wantNames))
    +    if (!range->init(cx, ptr, ::js::gc::MapTypeToTraceKind::kind, wantNames))
             return nullptr;
     
    -    return r.forget();
    +    return UniquePtr(range.release());
     }
     
     template
    @@ -347,7 +352,7 @@ RootList::addRoot(Node node, const char16_t* edgeName)
         MOZ_ASSERT(noGC.isSome());
         MOZ_ASSERT_IF(wantNames, edgeName);
     
    -    mozilla::UniquePtr name;
    +    UniquePtr name;
         if (edgeName) {
             name = DuplicateString(cx, edgeName);
             if (!name)
    @@ -379,10 +384,10 @@ class PreComputedEdgeRange : public EdgeRange {
     
     const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("RootList");
     
    -EdgeRange*
    +UniquePtr
     Concrete::edges(JSContext* cx, bool wantNames) const {
         MOZ_ASSERT_IF(wantNames, get().wantNames);
    -    return js_new(cx, get().edges);
    +    return UniquePtr(cx->new_(cx, get().edges));
     }
     
     } // namespace ubi
    
    From 21c2d145e36c632206db77ee0fcb2c0699b7ff18 Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:54 -0700
    Subject: [PATCH 212/241] Bug 1024774 - Part 0: Upgrade the protobuf library.
     r=mmc,glandium
    
    --HG--
    rename : toolkit/components/protobuf/google/protobuf/extension_set.cc => toolkit/components/protobuf/src/google/protobuf/extension_set.cc
    rename : toolkit/components/protobuf/google/protobuf/extension_set.h => toolkit/components/protobuf/src/google/protobuf/extension_set.h
    rename : toolkit/components/protobuf/google/protobuf/generated_message_util.cc => toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc
    rename : toolkit/components/protobuf/google/protobuf/generated_message_util.h => toolkit/components/protobuf/src/google/protobuf/generated_message_util.h
    rename : toolkit/components/protobuf/google/protobuf/io/coded_stream.cc => toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc
    rename : toolkit/components/protobuf/google/protobuf/io/coded_stream.h => toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h
    rename : toolkit/components/protobuf/google/protobuf/io/coded_stream_inl.h => toolkit/components/protobuf/src/google/protobuf/io/coded_stream_inl.h
    rename : toolkit/components/protobuf/google/protobuf/io/package_info.h => toolkit/components/protobuf/src/google/protobuf/io/package_info.h
    rename : toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.cc => toolkit/components/protobuf/src/google/protobuf/io/strtod.h
    rename : toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.cc => toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc
    rename : toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.h => toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h
    rename : toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl.h => toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
    rename : toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.cc => toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
    rename : toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.h => toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
    rename : toolkit/components/protobuf/google/protobuf/message_lite.cc => toolkit/components/protobuf/src/google/protobuf/message_lite.cc
    rename : toolkit/components/protobuf/google/protobuf/message_lite.h => toolkit/components/protobuf/src/google/protobuf/message_lite.h
    rename : toolkit/components/protobuf/google/protobuf/package_info.h => toolkit/components/protobuf/src/google/protobuf/package_info.h
    rename : toolkit/components/protobuf/google/protobuf/generated_message_util.h => toolkit/components/protobuf/src/google/protobuf/reflection_ops.h
    rename : toolkit/components/protobuf/google/protobuf/repeated_field.cc => toolkit/components/protobuf/src/google/protobuf/repeated_field.cc
    rename : toolkit/components/protobuf/google/protobuf/repeated_field.h => toolkit/components/protobuf/src/google/protobuf/repeated_field.h
    rename : toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.cc => toolkit/components/protobuf/src/google/protobuf/service.cc
    rename : toolkit/components/protobuf/google/protobuf/generated_message_util.cc => toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h
    rename : toolkit/components/protobuf/google/protobuf/stubs/common.cc => toolkit/components/protobuf/src/google/protobuf/stubs/common.cc
    rename : toolkit/components/protobuf/google/protobuf/stubs/common.h => toolkit/components/protobuf/src/google/protobuf/stubs/common.h
    rename : toolkit/components/protobuf/google/protobuf/stubs/hash.h => toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
    rename : toolkit/components/protobuf/google/protobuf/stubs/once.cc => toolkit/components/protobuf/src/google/protobuf/stubs/once.cc
    rename : toolkit/components/protobuf/google/protobuf/stubs/once.h => toolkit/components/protobuf/src/google/protobuf/stubs/once.h
    rename : toolkit/components/protobuf/google/protobuf/stubs/stl_util-inl.h => toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h
    rename : toolkit/components/protobuf/google/protobuf/generated_message_util.h => toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h
    rename : toolkit/components/protobuf/google/protobuf/wire_format_lite.cc => toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc
    rename : toolkit/components/protobuf/google/protobuf/wire_format_lite.h => toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
    rename : toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h => toolkit/components/protobuf/src/google/protobuf/wire_format_lite_inl.h
    ---
     configure.in                                  |     1 +
     gfx/layers/protobuf/LayerScopePacket.pb.cc    |  1630 ++-
     gfx/layers/protobuf/LayerScopePacket.pb.h     |  1227 +-
     toolkit/components/downloads/csd.pb.cc        | 10046 ++++++++++++++-
     toolkit/components/downloads/csd.pb.h         | 10618 +++++++++++++++-
     toolkit/components/downloads/csd.proto        |   487 +
     toolkit/components/downloads/generate_csd.sh  |    23 +-
     toolkit/components/downloads/moz.build        |     1 +
     toolkit/components/protobuf/README.txt        |    30 +-
     .../protobuf/google/protobuf/stubs/map-util.h |   119 -
     toolkit/components/protobuf/m-c-changes.patch |   365 +
     toolkit/components/protobuf/moz.build         |   131 +-
     toolkit/components/protobuf/r512.patch        |    13 -
     .../src/google/protobuf/descriptor.cc         |  5420 ++++++++
     .../protobuf/src/google/protobuf/descriptor.h |  1691 +++
     .../src/google/protobuf/descriptor.pb.cc      |  9135 +++++++++++++
     .../src/google/protobuf/descriptor.pb.h       |  6761 ++++++++++
     .../src/google/protobuf/descriptor.proto      |   687 +
     .../google/protobuf/descriptor_database.cc    |   543 +
     .../src/google/protobuf/descriptor_database.h |   369 +
     .../src/google/protobuf/dynamic_message.cc    |   764 ++
     .../src/google/protobuf/dynamic_message.h     |   148 +
     .../google/protobuf/extension_set.cc          |   637 +-
     .../{ => src}/google/protobuf/extension_set.h |   484 +-
     .../google/protobuf/extension_set_heavy.cc    |   734 ++
     .../protobuf/generated_enum_reflection.h      |    91 +
     .../protobuf/generated_message_reflection.cc  |  1683 +++
     .../protobuf/generated_message_reflection.h   |   504 +
     .../google/protobuf/generated_message_util.cc |    14 +-
     .../google/protobuf/generated_message_util.h  |   113 +
     .../google/protobuf/io/coded_stream.cc        |   153 +-
     .../google/protobuf/io/coded_stream.h         |   156 +-
     .../google/protobuf/io/coded_stream_inl.h     |    13 +-
     .../src/google/protobuf/io/gzip_stream.cc     |   325 +
     .../src/google/protobuf/io/gzip_stream.h      |   209 +
     .../google/protobuf/io/package_info.h         |     2 +-
     .../src/google/protobuf/io/printer.cc         |   198 +
     .../protobuf/src/google/protobuf/io/printer.h |   136 +
     .../protobuf/src/google/protobuf/io/strtod.cc |   113 +
     .../protobuf/src/google/protobuf/io/strtod.h  |    50 +
     .../src/google/protobuf/io/tokenizer.cc       |  1127 ++
     .../src/google/protobuf/io/tokenizer.h        |   402 +
     .../google/protobuf/io/zero_copy_stream.cc    |    11 +-
     .../google/protobuf/io/zero_copy_stream.h     |    12 +-
     .../protobuf/io/zero_copy_stream_impl.cc      |   473 +
     .../protobuf/io/zero_copy_stream_impl.h       |     3 +-
     .../protobuf/io/zero_copy_stream_impl_lite.cc |    24 +-
     .../protobuf/io/zero_copy_stream_impl_lite.h  |    16 +-
     .../protobuf/src/google/protobuf/message.cc   |   358 +
     .../protobuf/src/google/protobuf/message.h    |   866 ++
     .../{ => src}/google/protobuf/message_lite.cc |     7 +-
     .../{ => src}/google/protobuf/message_lite.h  |    14 +-
     .../{ => src}/google/protobuf/package_info.h  |     2 +-
     .../src/google/protobuf/reflection_ops.cc     |   269 +
     .../src/google/protobuf/reflection_ops.h      |    81 +
     .../google/protobuf/repeated_field.cc         |    23 +-
     .../google/protobuf/repeated_field.h          |   474 +-
     .../google/protobuf/service.cc}               |    46 +-
     .../protobuf/src/google/protobuf/service.h    |   291 +
     .../src/google/protobuf/stubs/atomicops.h     |   227 +
     .../stubs/atomicops_internals_arm64_gcc.h     |   325 +
     .../stubs/atomicops_internals_arm_gcc.h       |   151 +
     .../stubs/atomicops_internals_arm_qnx.h       |   146 +
     .../atomicops_internals_atomicword_compat.h   |   122 +
     .../stubs/atomicops_internals_generic_gcc.h   |   137 +
     .../stubs/atomicops_internals_macosx.h        |   225 +
     .../stubs/atomicops_internals_mips_gcc.h      |   313 +
     .../stubs/atomicops_internals_pnacl.h         |    73 +
     .../stubs/atomicops_internals_solaris.h       |   188 +
     .../protobuf/stubs/atomicops_internals_tsan.h |   219 +
     .../stubs/atomicops_internals_x86_gcc.cc      |   137 +
     .../stubs/atomicops_internals_x86_gcc.h       |   293 +
     .../stubs/atomicops_internals_x86_msvc.cc     |   112 +
     .../stubs/atomicops_internals_x86_msvc.h      |   150 +
     .../{ => src}/google/protobuf/stubs/common.cc |    47 +-
     .../{ => src}/google/protobuf/stubs/common.h  |   121 +-
     .../{ => src}/google/protobuf/stubs/hash.h    |    14 +-
     .../src/google/protobuf/stubs/map_util.h      |   771 ++
     .../{ => src}/google/protobuf/stubs/once.cc   |    89 +-
     .../{ => src}/google/protobuf/stubs/once.h    |   103 +-
     .../google/protobuf/stubs/platform_macros.h   |   103 +
     .../src/google/protobuf/stubs/shared_ptr.h    |   470 +
     .../google/protobuf/stubs/stl_util.h}         |    10 +-
     .../src/google/protobuf/stubs/stringprintf.cc |   174 +
     .../src/google/protobuf/stubs/stringprintf.h  |    76 +
     .../protobuf/stubs/structurally_valid.cc      |   536 +
     .../src/google/protobuf/stubs/strutil.cc      |  1280 ++
     .../src/google/protobuf/stubs/strutil.h       |   563 +
     .../src/google/protobuf/stubs/substitute.cc   |   134 +
     .../src/google/protobuf/stubs/substitute.h    |   170 +
     .../src/google/protobuf/stubs/template_util.h |   138 +
     .../src/google/protobuf/stubs/type_traits.h   |   334 +
     .../src/google/protobuf/text_format.cc        |  1746 +++
     .../src/google/protobuf/text_format.h         |   473 +
     .../src/google/protobuf/unknown_field_set.cc  |   265 +
     .../src/google/protobuf/unknown_field_set.h   |   318 +
     .../src/google/protobuf/wire_format.cc        |  1106 ++
     .../src/google/protobuf/wire_format.h         |   336 +
     .../google/protobuf/wire_format_lite.cc       |   126 +-
     .../google/protobuf/wire_format_lite.h        |    58 +-
     .../google/protobuf/wire_format_lite_inl.h    |   131 +-
     toolkit/components/protobuf/update.sh         |     2 -
     .../components/protobuf/upgrade_protobuf.sh   |    71 +
     toolkit/components/protobuf/vs2013.patch      |    21 -
     104 files changed, 70293 insertions(+), 2634 deletions(-)
     create mode 100644 toolkit/components/downloads/csd.proto
     delete mode 100644 toolkit/components/protobuf/google/protobuf/stubs/map-util.h
     create mode 100644 toolkit/components/protobuf/m-c-changes.patch
     delete mode 100644 toolkit/components/protobuf/r512.patch
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.proto
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor_database.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/dynamic_message.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/extension_set.cc (76%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/extension_set.h (63%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/generated_message_util.cc (87%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/generated_message_util.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/coded_stream.cc (85%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/coded_stream.h (87%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/coded_stream_inl.h (85%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/package_info.h (97%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/printer.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/printer.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/strtod.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/strtod.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream.cc (82%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream.h (93%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream_impl.h (99%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream_impl_lite.cc (93%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream_impl_lite.h (95%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/message.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/message.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/message_lite.cc (98%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/message_lite.h (97%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/package_info.h (98%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/reflection_ops.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/repeated_field.cc (79%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/repeated_field.h (74%)
     rename toolkit/components/protobuf/{google/protobuf/generated_message_util.h => src/google/protobuf/service.cc} (60%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/service.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/common.cc (90%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/common.h (93%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/hash.h (96%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/once.cc (56%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/once.h (61%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/shared_ptr.h
     rename toolkit/components/protobuf/{google/protobuf/stubs/stl_util-inl.h => src/google/protobuf/stubs/stl_util.h} (95%)
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/type_traits.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/text_format.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/text_format.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/wire_format.cc
     create mode 100644 toolkit/components/protobuf/src/google/protobuf/wire_format.h
     rename toolkit/components/protobuf/{ => src}/google/protobuf/wire_format_lite.cc (76%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/wire_format_lite.h (92%)
     rename toolkit/components/protobuf/{ => src}/google/protobuf/wire_format_lite_inl.h (86%)
     delete mode 100644 toolkit/components/protobuf/update.sh
     create mode 100755 toolkit/components/protobuf/upgrade_protobuf.sh
     delete mode 100644 toolkit/components/protobuf/vs2013.patch
    
    diff --git a/configure.in b/configure.in
    index 94e1694fc7dd..8222f08b9cc0 100644
    --- a/configure.in
    +++ b/configure.in
    @@ -3017,6 +3017,7 @@ then
         esac
         LDFLAGS="${_PTHREAD_LDFLAGS} ${LDFLAGS}"
         AC_SUBST(MOZ_USE_PTHREADS)
    +    MOZ_CHECK_HEADERS(pthread.h)
     fi
     
     
    diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.cc b/gfx/layers/protobuf/LayerScopePacket.pb.cc
    index 3c07257b296f..a73b9672a72f 100644
    --- a/gfx/layers/protobuf/LayerScopePacket.pb.cc
    +++ b/gfx/layers/protobuf/LayerScopePacket.pb.cc
    @@ -1,13 +1,16 @@
     // Generated by the protocol buffer compiler.  DO NOT EDIT!
    +// source: LayerScopePacket.proto
     
     #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
     #include "LayerScopePacket.pb.h"
     
     #include 
     
    +#include 
     #include 
     #include 
     #include 
    +#include 
     // @@protoc_insertion_point(includes)
     
     namespace mozilla {
    @@ -30,12 +33,18 @@ void protobuf_ShutdownFile_LayerScopePacket_2eproto() {
       delete CommandPacket::default_instance_;
     }
     
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +void protobuf_AddDesc_LayerScopePacket_2eproto_impl() {
    +  GOOGLE_PROTOBUF_VERIFY_VERSION;
    +
    +#else
     void protobuf_AddDesc_LayerScopePacket_2eproto() {
       static bool already_here = false;
       if (already_here) return;
       already_here = true;
       GOOGLE_PROTOBUF_VERIFY_VERSION;
     
    +#endif
       FramePacket::default_instance_ = new FramePacket();
       ColorPacket::default_instance_ = new ColorPacket();
       TexturePacket::default_instance_ = new TexturePacket();
    @@ -65,13 +74,20 @@ void protobuf_AddDesc_LayerScopePacket_2eproto() {
       ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_LayerScopePacket_2eproto);
     }
     
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AddDesc_LayerScopePacket_2eproto_once_);
    +void protobuf_AddDesc_LayerScopePacket_2eproto() {
    +  ::google::protobuf::GoogleOnceInit(&protobuf_AddDesc_LayerScopePacket_2eproto_once_,
    +                 &protobuf_AddDesc_LayerScopePacket_2eproto_impl);
    +}
    +#else
     // Force AddDescriptors() to be called at static initialization time.
     struct StaticDescriptorInitializer_LayerScopePacket_2eproto {
       StaticDescriptorInitializer_LayerScopePacket_2eproto() {
         protobuf_AddDesc_LayerScopePacket_2eproto();
       }
     } static_descriptor_initializer_LayerScopePacket_2eproto_;
    -
    +#endif
     
     // ===================================================================
     
    @@ -82,6 +98,7 @@ const int FramePacket::kValueFieldNumber;
     FramePacket::FramePacket()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.FramePacket)
     }
     
     void FramePacket::InitAsDefaultInstance() {
    @@ -91,6 +108,7 @@ FramePacket::FramePacket(const FramePacket& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.FramePacket)
     }
     
     void FramePacket::SharedCtor() {
    @@ -100,11 +118,16 @@ void FramePacket::SharedCtor() {
     }
     
     FramePacket::~FramePacket() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.FramePacket)
       SharedDtor();
     }
     
     void FramePacket::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -114,7 +137,12 @@ void FramePacket::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const FramePacket& FramePacket::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     FramePacket* FramePacket::default_instance_ = NULL;
    @@ -124,60 +152,77 @@ FramePacket* FramePacket::New() const {
     }
     
     void FramePacket::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    value_ = GOOGLE_ULONGLONG(0);
    -  }
    +  value_ = GOOGLE_ULONGLONG(0);
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool FramePacket::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.FramePacket)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional uint64 value = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &value_)));
               set_has_value();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.FramePacket)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.FramePacket)
    +  return false;
     #undef DO_
     }
     
     void FramePacket::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.FramePacket)
       // optional uint64 value = 1;
       if (has_value()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.FramePacket)
     }
     
     int FramePacket::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional uint64 value = 1;
         if (has_value()) {
    @@ -185,8 +230,10 @@ int FramePacket::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->value());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -205,6 +252,7 @@ void FramePacket::MergeFrom(const FramePacket& from) {
           set_value(from.value());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void FramePacket::CopyFrom(const FramePacket& from) {
    @@ -214,7 +262,7 @@ void FramePacket::CopyFrom(const FramePacket& from) {
     }
     
     bool FramePacket::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -222,6 +270,7 @@ void FramePacket::Swap(FramePacket* other) {
       if (other != this) {
         std::swap(value_, other->value_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -243,6 +292,7 @@ const int ColorPacket::kColorFieldNumber;
     ColorPacket::ColorPacket()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.ColorPacket)
     }
     
     void ColorPacket::InitAsDefaultInstance() {
    @@ -252,6 +302,7 @@ ColorPacket::ColorPacket(const ColorPacket& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.ColorPacket)
     }
     
     void ColorPacket::SharedCtor() {
    @@ -264,11 +315,16 @@ void ColorPacket::SharedCtor() {
     }
     
     ColorPacket::~ColorPacket() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.ColorPacket)
       SharedDtor();
     }
     
     void ColorPacket::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -278,7 +334,12 @@ void ColorPacket::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ColorPacket& ColorPacket::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ColorPacket* ColorPacket::default_instance_ = NULL;
    @@ -288,126 +349,151 @@ ColorPacket* ColorPacket::New() const {
     }
     
     void ColorPacket::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    layerref_ = GOOGLE_ULONGLONG(0);
    -    width_ = 0u;
    -    height_ = 0u;
    -    color_ = 0u;
    -  }
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(layerref_, color_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ColorPacket::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.ColorPacket)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required uint64 layerref = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &layerref_)));
               set_has_layerref();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_width;
             break;
           }
    -      
    +
           // optional uint32 width = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_width:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &width_)));
               set_has_width();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(24)) goto parse_height;
             break;
           }
    -      
    +
           // optional uint32 height = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 24) {
              parse_height:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &height_)));
               set_has_height();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(32)) goto parse_color;
             break;
           }
    -      
    +
           // optional uint32 color = 4;
           case 4: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 32) {
              parse_color:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &color_)));
               set_has_color();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.ColorPacket)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.ColorPacket)
    +  return false;
     #undef DO_
     }
     
     void ColorPacket::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.ColorPacket)
       // required uint64 layerref = 1;
       if (has_layerref()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->layerref(), output);
       }
    -  
    +
       // optional uint32 width = 2;
       if (has_width()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->width(), output);
       }
    -  
    +
       // optional uint32 height = 3;
       if (has_height()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->height(), output);
       }
    -  
    +
       // optional uint32 color = 4;
       if (has_color()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->color(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.ColorPacket)
     }
     
     int ColorPacket::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required uint64 layerref = 1;
         if (has_layerref()) {
    @@ -415,29 +501,31 @@ int ColorPacket::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->layerref());
         }
    -    
    +
         // optional uint32 width = 2;
         if (has_width()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->width());
         }
    -    
    +
         // optional uint32 height = 3;
         if (has_height()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->height());
         }
    -    
    +
         // optional uint32 color = 4;
         if (has_color()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->color());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -465,6 +553,7 @@ void ColorPacket::MergeFrom(const ColorPacket& from) {
           set_color(from.color());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ColorPacket::CopyFrom(const ColorPacket& from) {
    @@ -475,7 +564,7 @@ void ColorPacket::CopyFrom(const ColorPacket& from) {
     
     bool ColorPacket::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    -  
    +
       return true;
     }
     
    @@ -486,6 +575,7 @@ void ColorPacket::Swap(ColorPacket* other) {
         std::swap(height_, other->height_);
         std::swap(color_, other->color_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -512,6 +602,7 @@ const int TexturePacket::kDataFieldNumber;
     TexturePacket::TexturePacket()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.TexturePacket)
     }
     
     void TexturePacket::InitAsDefaultInstance() {
    @@ -521,9 +612,11 @@ TexturePacket::TexturePacket(const TexturePacket& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.TexturePacket)
     }
     
     void TexturePacket::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
       layerref_ = GOOGLE_ULONGLONG(0);
       width_ = 0u;
    @@ -533,19 +626,24 @@ void TexturePacket::SharedCtor() {
       target_ = 0u;
       dataformat_ = 0u;
       glcontext_ = GOOGLE_ULONGLONG(0);
    -  data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     TexturePacket::~TexturePacket() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.TexturePacket)
       SharedDtor();
     }
     
     void TexturePacket::SharedDtor() {
    -  if (data_ != &::google::protobuf::internal::kEmptyString) {
    +  if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete data_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -555,7 +653,12 @@ void TexturePacket::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const TexturePacket& TexturePacket::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     TexturePacket* TexturePacket::default_instance_ = NULL;
    @@ -565,241 +668,257 @@ TexturePacket* TexturePacket::New() const {
     }
     
     void TexturePacket::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    layerref_ = GOOGLE_ULONGLONG(0);
    -    width_ = 0u;
    -    height_ = 0u;
    -    stride_ = 0u;
    -    name_ = 0u;
    -    target_ = 0u;
    -    dataformat_ = 0u;
    -    glcontext_ = GOOGLE_ULONGLONG(0);
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 255) {
    +    ZR_(layerref_, glcontext_);
       }
    -  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    -    if (has_data()) {
    -      if (data_ != &::google::protobuf::internal::kEmptyString) {
    -        data_->clear();
    -      }
    +  if (has_data()) {
    +    if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +      data_->clear();
         }
       }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool TexturePacket::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.TexturePacket)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required uint64 layerref = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &layerref_)));
               set_has_layerref();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_width;
             break;
           }
    -      
    +
           // optional uint32 width = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_width:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &width_)));
               set_has_width();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(24)) goto parse_height;
             break;
           }
    -      
    +
           // optional uint32 height = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 24) {
              parse_height:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &height_)));
               set_has_height();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(32)) goto parse_stride;
             break;
           }
    -      
    +
           // optional uint32 stride = 4;
           case 4: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 32) {
              parse_stride:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &stride_)));
               set_has_stride();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(40)) goto parse_name;
             break;
           }
    -      
    +
           // optional uint32 name = 5;
           case 5: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 40) {
              parse_name:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &name_)));
               set_has_name();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(48)) goto parse_target;
             break;
           }
    -      
    +
           // optional uint32 target = 6;
           case 6: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 48) {
              parse_target:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &target_)));
               set_has_target();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(56)) goto parse_dataformat;
             break;
           }
    -      
    +
           // optional uint32 dataformat = 7;
           case 7: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 56) {
              parse_dataformat:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &dataformat_)));
               set_has_dataformat();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(64)) goto parse_glcontext;
             break;
           }
    -      
    +
           // optional uint64 glcontext = 8;
           case 8: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 64) {
              parse_glcontext:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &glcontext_)));
               set_has_glcontext();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(74)) goto parse_data;
             break;
           }
    -      
    +
           // optional bytes data = 9;
           case 9: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 74) {
              parse_data:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_data()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.TexturePacket)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.TexturePacket)
    +  return false;
     #undef DO_
     }
     
     void TexturePacket::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.TexturePacket)
       // required uint64 layerref = 1;
       if (has_layerref()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->layerref(), output);
       }
    -  
    +
       // optional uint32 width = 2;
       if (has_width()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->width(), output);
       }
    -  
    +
       // optional uint32 height = 3;
       if (has_height()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->height(), output);
       }
    -  
    +
       // optional uint32 stride = 4;
       if (has_stride()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->stride(), output);
       }
    -  
    +
       // optional uint32 name = 5;
       if (has_name()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->name(), output);
       }
    -  
    +
       // optional uint32 target = 6;
       if (has_target()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->target(), output);
       }
    -  
    +
       // optional uint32 dataformat = 7;
       if (has_dataformat()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->dataformat(), output);
       }
    -  
    +
       // optional uint64 glcontext = 8;
       if (has_glcontext()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->glcontext(), output);
       }
    -  
    +
       // optional bytes data = 9;
       if (has_data()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           9, this->data(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.TexturePacket)
     }
     
     int TexturePacket::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required uint64 layerref = 1;
         if (has_layerref()) {
    @@ -807,56 +926,56 @@ int TexturePacket::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->layerref());
         }
    -    
    +
         // optional uint32 width = 2;
         if (has_width()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->width());
         }
    -    
    +
         // optional uint32 height = 3;
         if (has_height()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->height());
         }
    -    
    +
         // optional uint32 stride = 4;
         if (has_stride()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->stride());
         }
    -    
    +
         // optional uint32 name = 5;
         if (has_name()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->name());
         }
    -    
    +
         // optional uint32 target = 6;
         if (has_target()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->target());
         }
    -    
    +
         // optional uint32 dataformat = 7;
         if (has_dataformat()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->dataformat());
         }
    -    
    +
         // optional uint64 glcontext = 8;
         if (has_glcontext()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->glcontext());
         }
    -    
    +
       }
       if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
         // optional bytes data = 9;
    @@ -865,8 +984,10 @@ int TexturePacket::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->data());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -911,6 +1032,7 @@ void TexturePacket::MergeFrom(const TexturePacket& from) {
           set_data(from.data());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void TexturePacket::CopyFrom(const TexturePacket& from) {
    @@ -921,7 +1043,7 @@ void TexturePacket::CopyFrom(const TexturePacket& from) {
     
     bool TexturePacket::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    -  
    +
       return true;
     }
     
    @@ -937,6 +1059,7 @@ void TexturePacket::Swap(TexturePacket* other) {
         std::swap(glcontext_, other->glcontext_);
         std::swap(data_, other->data_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1031,6 +1154,7 @@ const int LayersPacket_Layer_Size::kHFieldNumber;
     LayersPacket_Layer_Size::LayersPacket_Layer_Size()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Size)
     }
     
     void LayersPacket_Layer_Size::InitAsDefaultInstance() {
    @@ -1040,6 +1164,7 @@ LayersPacket_Layer_Size::LayersPacket_Layer_Size(const LayersPacket_Layer_Size&
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Size)
     }
     
     void LayersPacket_Layer_Size::SharedCtor() {
    @@ -1050,11 +1175,16 @@ void LayersPacket_Layer_Size::SharedCtor() {
     }
     
     LayersPacket_Layer_Size::~LayersPacket_Layer_Size() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Size)
       SharedDtor();
     }
     
     void LayersPacket_Layer_Size::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -1064,7 +1194,12 @@ void LayersPacket_Layer_Size::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const LayersPacket_Layer_Size& LayersPacket_Layer_Size::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     LayersPacket_Layer_Size* LayersPacket_Layer_Size::default_instance_ = NULL;
    @@ -1074,82 +1209,111 @@ LayersPacket_Layer_Size* LayersPacket_Layer_Size::New() const {
     }
     
     void LayersPacket_Layer_Size::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    w_ = 0;
    -    h_ = 0;
    -  }
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(w_, h_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool LayersPacket_Layer_Size::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Size)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional int32 w = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                      input, &w_)));
               set_has_w();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_h;
             break;
           }
    -      
    +
           // optional int32 h = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_h:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                      input, &h_)));
               set_has_h();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Size)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Size)
    +  return false;
     #undef DO_
     }
     
     void LayersPacket_Layer_Size::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Size)
       // optional int32 w = 1;
       if (has_w()) {
         ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->w(), output);
       }
    -  
    +
       // optional int32 h = 2;
       if (has_h()) {
         ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->h(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Size)
     }
     
     int LayersPacket_Layer_Size::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional int32 w = 1;
         if (has_w()) {
    @@ -1157,15 +1321,17 @@ int LayersPacket_Layer_Size::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::Int32Size(
               this->w());
         }
    -    
    +
         // optional int32 h = 2;
         if (has_h()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::Int32Size(
               this->h());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1187,6 +1353,7 @@ void LayersPacket_Layer_Size::MergeFrom(const LayersPacket_Layer_Size& from) {
           set_h(from.h());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void LayersPacket_Layer_Size::CopyFrom(const LayersPacket_Layer_Size& from) {
    @@ -1196,7 +1363,7 @@ void LayersPacket_Layer_Size::CopyFrom(const LayersPacket_Layer_Size& from) {
     }
     
     bool LayersPacket_Layer_Size::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1205,6 +1372,7 @@ void LayersPacket_Layer_Size::Swap(LayersPacket_Layer_Size* other) {
         std::swap(w_, other->w_);
         std::swap(h_, other->h_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1226,6 +1394,7 @@ const int LayersPacket_Layer_Rect::kHFieldNumber;
     LayersPacket_Layer_Rect::LayersPacket_Layer_Rect()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
     }
     
     void LayersPacket_Layer_Rect::InitAsDefaultInstance() {
    @@ -1235,6 +1404,7 @@ LayersPacket_Layer_Rect::LayersPacket_Layer_Rect(const LayersPacket_Layer_Rect&
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
     }
     
     void LayersPacket_Layer_Rect::SharedCtor() {
    @@ -1247,11 +1417,16 @@ void LayersPacket_Layer_Rect::SharedCtor() {
     }
     
     LayersPacket_Layer_Rect::~LayersPacket_Layer_Rect() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
       SharedDtor();
     }
     
     void LayersPacket_Layer_Rect::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -1261,7 +1436,12 @@ void LayersPacket_Layer_Rect::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const LayersPacket_Layer_Rect& LayersPacket_Layer_Rect::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     LayersPacket_Layer_Rect* LayersPacket_Layer_Rect::default_instance_ = NULL;
    @@ -1271,126 +1451,151 @@ LayersPacket_Layer_Rect* LayersPacket_Layer_Rect::New() const {
     }
     
     void LayersPacket_Layer_Rect::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    x_ = 0;
    -    y_ = 0;
    -    w_ = 0;
    -    h_ = 0;
    -  }
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(x_, h_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool LayersPacket_Layer_Rect::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional int32 x = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                      input, &x_)));
               set_has_x();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_y;
             break;
           }
    -      
    +
           // optional int32 y = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_y:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                      input, &y_)));
               set_has_y();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(24)) goto parse_w;
             break;
           }
    -      
    +
           // optional int32 w = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 24) {
              parse_w:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                      input, &w_)));
               set_has_w();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(32)) goto parse_h;
             break;
           }
    -      
    +
           // optional int32 h = 4;
           case 4: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 32) {
              parse_h:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                      input, &h_)));
               set_has_h();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
    +  return false;
     #undef DO_
     }
     
     void LayersPacket_Layer_Rect::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
       // optional int32 x = 1;
       if (has_x()) {
         ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->x(), output);
       }
    -  
    +
       // optional int32 y = 2;
       if (has_y()) {
         ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->y(), output);
       }
    -  
    +
       // optional int32 w = 3;
       if (has_w()) {
         ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->w(), output);
       }
    -  
    +
       // optional int32 h = 4;
       if (has_h()) {
         ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->h(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
     }
     
     int LayersPacket_Layer_Rect::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional int32 x = 1;
         if (has_x()) {
    @@ -1398,29 +1603,31 @@ int LayersPacket_Layer_Rect::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::Int32Size(
               this->x());
         }
    -    
    +
         // optional int32 y = 2;
         if (has_y()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::Int32Size(
               this->y());
         }
    -    
    +
         // optional int32 w = 3;
         if (has_w()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::Int32Size(
               this->w());
         }
    -    
    +
         // optional int32 h = 4;
         if (has_h()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::Int32Size(
               this->h());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1448,6 +1655,7 @@ void LayersPacket_Layer_Rect::MergeFrom(const LayersPacket_Layer_Rect& from) {
           set_h(from.h());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void LayersPacket_Layer_Rect::CopyFrom(const LayersPacket_Layer_Rect& from) {
    @@ -1457,7 +1665,7 @@ void LayersPacket_Layer_Rect::CopyFrom(const LayersPacket_Layer_Rect& from) {
     }
     
     bool LayersPacket_Layer_Rect::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1468,6 +1676,7 @@ void LayersPacket_Layer_Rect::Swap(LayersPacket_Layer_Rect* other) {
         std::swap(w_, other->w_);
         std::swap(h_, other->h_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1486,6 +1695,7 @@ const int LayersPacket_Layer_Region::kRFieldNumber;
     LayersPacket_Layer_Region::LayersPacket_Layer_Region()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Region)
     }
     
     void LayersPacket_Layer_Region::InitAsDefaultInstance() {
    @@ -1495,6 +1705,7 @@ LayersPacket_Layer_Region::LayersPacket_Layer_Region(const LayersPacket_Layer_Re
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Region)
     }
     
     void LayersPacket_Layer_Region::SharedCtor() {
    @@ -1503,11 +1714,16 @@ void LayersPacket_Layer_Region::SharedCtor() {
     }
     
     LayersPacket_Layer_Region::~LayersPacket_Layer_Region() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Region)
       SharedDtor();
     }
     
     void LayersPacket_Layer_Region::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -1517,7 +1733,12 @@ void LayersPacket_Layer_Region::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const LayersPacket_Layer_Region& LayersPacket_Layer_Region::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     LayersPacket_Layer_Region* LayersPacket_Layer_Region::default_instance_ = NULL;
    @@ -1529,57 +1750,76 @@ LayersPacket_Layer_Region* LayersPacket_Layer_Region::New() const {
     void LayersPacket_Layer_Region::Clear() {
       r_.Clear();
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool LayersPacket_Layer_Region::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Region)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
              parse_r:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                     input, add_r()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(10)) goto parse_r;
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Region)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Region)
    +  return false;
     #undef DO_
     }
     
     void LayersPacket_Layer_Region::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Region)
       // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1;
       for (int i = 0; i < this->r_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           1, this->r(i), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Region)
     }
     
     int LayersPacket_Layer_Region::ByteSize() const {
       int total_size = 0;
    -  
    +
       // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1;
       total_size += 1 * this->r_size();
       for (int i = 0; i < this->r_size(); i++) {
    @@ -1587,7 +1827,9 @@ int LayersPacket_Layer_Region::ByteSize() const {
           ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
             this->r(i));
       }
    -  
    +
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1602,6 +1844,7 @@ void LayersPacket_Layer_Region::CheckTypeAndMergeFrom(
     void LayersPacket_Layer_Region::MergeFrom(const LayersPacket_Layer_Region& from) {
       GOOGLE_CHECK_NE(&from, this);
       r_.MergeFrom(from.r_);
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void LayersPacket_Layer_Region::CopyFrom(const LayersPacket_Layer_Region& from) {
    @@ -1611,7 +1854,7 @@ void LayersPacket_Layer_Region::CopyFrom(const LayersPacket_Layer_Region& from)
     }
     
     bool LayersPacket_Layer_Region::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1619,6 +1862,7 @@ void LayersPacket_Layer_Region::Swap(LayersPacket_Layer_Region* other) {
       if (other != this) {
         r_.Swap(&other->r_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1639,6 +1883,7 @@ const int LayersPacket_Layer_Matrix::kMFieldNumber;
     LayersPacket_Layer_Matrix::LayersPacket_Layer_Matrix()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
     }
     
     void LayersPacket_Layer_Matrix::InitAsDefaultInstance() {
    @@ -1648,6 +1893,7 @@ LayersPacket_Layer_Matrix::LayersPacket_Layer_Matrix(const LayersPacket_Layer_Ma
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
     }
     
     void LayersPacket_Layer_Matrix::SharedCtor() {
    @@ -1658,11 +1904,16 @@ void LayersPacket_Layer_Matrix::SharedCtor() {
     }
     
     LayersPacket_Layer_Matrix::~LayersPacket_Layer_Matrix() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
       SharedDtor();
     }
     
     void LayersPacket_Layer_Matrix::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -1672,7 +1923,12 @@ void LayersPacket_Layer_Matrix::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const LayersPacket_Layer_Matrix& LayersPacket_Layer_Matrix::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     LayersPacket_Layer_Matrix* LayersPacket_Layer_Matrix::default_instance_ = NULL;
    @@ -1682,122 +1938,148 @@ LayersPacket_Layer_Matrix* LayersPacket_Layer_Matrix::New() const {
     }
     
     void LayersPacket_Layer_Matrix::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    is2d_ = false;
    -    isid_ = false;
    -  }
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(is2d_, isid_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       m_.Clear();
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool LayersPacket_Layer_Matrix::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional bool is2D = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &is2d_)));
               set_has_is2d();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_isId;
             break;
           }
    -      
    +
           // optional bool isId = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_isId:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &isid_)));
               set_has_isid();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(29)) goto parse_m;
             break;
           }
    -      
    +
           // repeated float m = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
    +        if (tag == 29) {
              parse_m:
               DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
                        float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                      1, 29, input, this->mutable_m())));
    -        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
    -                   == ::google::protobuf::internal::WireFormatLite::
    -                      WIRETYPE_LENGTH_DELIMITED) {
    +        } else if (tag == 26) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
                        float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                      input, this->mutable_m())));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(29)) goto parse_m;
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
    +  return false;
     #undef DO_
     }
     
     void LayersPacket_Layer_Matrix::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
       // optional bool is2D = 1;
       if (has_is2d()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->is2d(), output);
       }
    -  
    +
       // optional bool isId = 2;
       if (has_isid()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->isid(), output);
       }
    -  
    +
       // repeated float m = 3;
       for (int i = 0; i < this->m_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteFloat(
           3, this->m(i), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
     }
     
     int LayersPacket_Layer_Matrix::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional bool is2D = 1;
         if (has_is2d()) {
           total_size += 1 + 1;
         }
    -    
    +
         // optional bool isId = 2;
         if (has_isid()) {
           total_size += 1 + 1;
         }
    -    
    +
       }
       // repeated float m = 3;
       {
    @@ -1805,7 +2087,9 @@ int LayersPacket_Layer_Matrix::ByteSize() const {
         data_size = 4 * this->m_size();
         total_size += 1 * this->m_size() + data_size;
       }
    -  
    +
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1828,6 +2112,7 @@ void LayersPacket_Layer_Matrix::MergeFrom(const LayersPacket_Layer_Matrix& from)
           set_isid(from.isid());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void LayersPacket_Layer_Matrix::CopyFrom(const LayersPacket_Layer_Matrix& from) {
    @@ -1837,7 +2122,7 @@ void LayersPacket_Layer_Matrix::CopyFrom(const LayersPacket_Layer_Matrix& from)
     }
     
     bool LayersPacket_Layer_Matrix::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1847,6 +2132,7 @@ void LayersPacket_Layer_Matrix::Swap(LayersPacket_Layer_Matrix* other) {
         std::swap(isid_, other->isid_);
         m_.Swap(&other->m_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1867,18 +2153,35 @@ const int LayersPacket_Layer_Shadow::kVRegionFieldNumber;
     LayersPacket_Layer_Shadow::LayersPacket_Layer_Shadow()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
     }
     
     void LayersPacket_Layer_Shadow::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Rect::internal_default_instance());
    +#else
       clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Rect::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::internal_default_instance());
    +#else
       transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance());
    +#else
       vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
    +#endif
     }
     
     LayersPacket_Layer_Shadow::LayersPacket_Layer_Shadow(const LayersPacket_Layer_Shadow& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
     }
     
     void LayersPacket_Layer_Shadow::SharedCtor() {
    @@ -1890,11 +2193,16 @@ void LayersPacket_Layer_Shadow::SharedCtor() {
     }
     
     LayersPacket_Layer_Shadow::~LayersPacket_Layer_Shadow() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
       SharedDtor();
     }
     
     void LayersPacket_Layer_Shadow::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
         delete clip_;
         delete transform_;
         delete vregion_;
    @@ -1907,7 +2215,12 @@ void LayersPacket_Layer_Shadow::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const LayersPacket_Layer_Shadow& LayersPacket_Layer_Shadow::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     LayersPacket_Layer_Shadow* LayersPacket_Layer_Shadow::default_instance_ = NULL;
    @@ -1917,7 +2230,7 @@ LayersPacket_Layer_Shadow* LayersPacket_Layer_Shadow::New() const {
     }
     
     void LayersPacket_Layer_Shadow::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 7) {
         if (has_clip()) {
           if (clip_ != NULL) clip_->::mozilla::layers::layerscope::LayersPacket_Layer_Rect::Clear();
         }
    @@ -1929,95 +2242,112 @@ void LayersPacket_Layer_Shadow::Clear() {
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool LayersPacket_Layer_Shadow::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_clip()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_transform;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_transform:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_transform()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(26)) goto parse_vRegion;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 26) {
              parse_vRegion:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_vregion()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
    +  return false;
     #undef DO_
     }
     
     void LayersPacket_Layer_Shadow::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1;
       if (has_clip()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           1, this->clip(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2;
       if (has_transform()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           2, this->transform(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3;
       if (has_vregion()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           3, this->vregion(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
     }
     
     int LayersPacket_Layer_Shadow::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1;
         if (has_clip()) {
    @@ -2025,22 +2355,24 @@ int LayersPacket_Layer_Shadow::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->clip());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2;
         if (has_transform()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->transform());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3;
         if (has_vregion()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->vregion());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -2065,6 +2397,7 @@ void LayersPacket_Layer_Shadow::MergeFrom(const LayersPacket_Layer_Shadow& from)
           mutable_vregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.vregion());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void LayersPacket_Layer_Shadow::CopyFrom(const LayersPacket_Layer_Shadow& from) {
    @@ -2074,7 +2407,7 @@ void LayersPacket_Layer_Shadow::CopyFrom(const LayersPacket_Layer_Shadow& from)
     }
     
     bool LayersPacket_Layer_Shadow::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -2084,6 +2417,7 @@ void LayersPacket_Layer_Shadow::Swap(LayersPacket_Layer_Shadow* other) {
         std::swap(transform_, other->transform_);
         std::swap(vregion_, other->vregion_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -2119,21 +2453,53 @@ const int LayersPacket_Layer::kSizeFieldNumber;
     LayersPacket_Layer::LayersPacket_Layer()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer)
     }
     
     void LayersPacket_Layer::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Rect::internal_default_instance());
    +#else
       clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Rect::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::internal_default_instance());
    +#else
       transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance());
    +#else
       vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  shadow_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow::internal_default_instance());
    +#else
       shadow_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Shadow::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  valid_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance());
    +#else
       valid_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  size_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Size*>(
    +      ::mozilla::layers::layerscope::LayersPacket_Layer_Size::internal_default_instance());
    +#else
       size_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Size*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Size::default_instance());
    +#endif
     }
     
     LayersPacket_Layer::LayersPacket_Layer(const LayersPacket_Layer& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer)
     }
     
     void LayersPacket_Layer::SharedCtor() {
    @@ -2160,11 +2526,16 @@ void LayersPacket_Layer::SharedCtor() {
     }
     
     LayersPacket_Layer::~LayersPacket_Layer() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer)
       SharedDtor();
     }
     
     void LayersPacket_Layer::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
         delete clip_;
         delete transform_;
         delete vregion_;
    @@ -2180,7 +2551,12 @@ void LayersPacket_Layer::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const LayersPacket_Layer& LayersPacket_Layer::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     LayersPacket_Layer* LayersPacket_Layer::default_instance_ = NULL;
    @@ -2190,10 +2566,19 @@ LayersPacket_Layer* LayersPacket_Layer::New() const {
     }
     
     void LayersPacket_Layer::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    type_ = 0;
    -    ptr_ = GOOGLE_ULONGLONG(0);
    -    parentptr_ = GOOGLE_ULONGLONG(0);
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 255) {
    +    ZR_(ptr_, parentptr_);
    +    ZR_(type_, opacity_);
         if (has_clip()) {
           if (clip_ != NULL) clip_->::mozilla::layers::layerscope::LayersPacket_Layer_Rect::Clear();
         }
    @@ -2206,193 +2591,194 @@ void LayersPacket_Layer::Clear() {
         if (has_shadow()) {
           if (shadow_ != NULL) shadow_->::mozilla::layers::layerscope::LayersPacket_Layer_Shadow::Clear();
         }
    -    opacity_ = 0;
       }
    -  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    -    copaque_ = false;
    -    calpha_ = false;
    +  if (_has_bits_[8 / 32] & 65280) {
    +    ZR_(copaque_, calpha_);
    +    ZR_(barid_, mask_);
    +    ZR_(color_, filter_);
         direct_ = 1;
    -    barid_ = GOOGLE_ULONGLONG(0);
    -    mask_ = GOOGLE_ULONGLONG(0);
         if (has_valid()) {
           if (valid_ != NULL) valid_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
         }
    -    color_ = 0u;
    -    filter_ = 0;
       }
    -  if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
    +  if (_has_bits_[16 / 32] & 196608) {
         refid_ = GOOGLE_ULONGLONG(0);
         if (has_size()) {
           if (size_ != NULL) size_->::mozilla::layers::layerscope::LayersPacket_Layer_Size::Clear();
         }
       }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool LayersPacket_Layer::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                      input, &value)));
               if (::mozilla::layers::layerscope::LayersPacket_Layer_LayerType_IsValid(value)) {
                 set_type(static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_ptr;
             break;
           }
    -      
    +
           // required uint64 ptr = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_ptr:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &ptr_)));
               set_has_ptr();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(24)) goto parse_parentPtr;
             break;
           }
    -      
    +
           // required uint64 parentPtr = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 24) {
              parse_parentPtr:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &parentptr_)));
               set_has_parentptr();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(82)) goto parse_clip;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10;
           case 10: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 82) {
              parse_clip:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_clip()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(90)) goto parse_transform;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11;
           case 11: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 90) {
              parse_transform:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_transform()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(98)) goto parse_vRegion;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12;
           case 12: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 98) {
              parse_vRegion:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_vregion()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(106)) goto parse_shadow;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13;
           case 13: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 106) {
              parse_shadow:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_shadow()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(117)) goto parse_opacity;
             break;
           }
    -      
    +
           // optional float opacity = 14;
           case 14: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
    +        if (tag == 117) {
              parse_opacity:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                      input, &opacity_)));
               set_has_opacity();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(120)) goto parse_cOpaque;
             break;
           }
    -      
    +
           // optional bool cOpaque = 15;
           case 15: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 120) {
              parse_cOpaque:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &copaque_)));
               set_has_copaque();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(128)) goto parse_cAlpha;
             break;
           }
    -      
    +
           // optional bool cAlpha = 16;
           case 16: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 128) {
              parse_cAlpha:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &calpha_)));
               set_has_calpha();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(136)) goto parse_direct;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17;
           case 17: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 136) {
              parse_direct:
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    @@ -2400,80 +2786,78 @@ bool LayersPacket_Layer::MergePartialFromCodedStream(
                      input, &value)));
               if (::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect_IsValid(value)) {
                 set_direct(static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(144)) goto parse_barID;
             break;
           }
    -      
    +
           // optional uint64 barID = 18;
           case 18: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 144) {
              parse_barID:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &barid_)));
               set_has_barid();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(152)) goto parse_mask;
             break;
           }
    -      
    +
           // optional uint64 mask = 19;
           case 19: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 152) {
              parse_mask:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &mask_)));
               set_has_mask();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(802)) goto parse_valid;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
           case 100: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 802) {
              parse_valid:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_valid()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(808)) goto parse_color;
             break;
           }
    -      
    +
           // optional uint32 color = 101;
           case 101: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 808) {
              parse_color:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                      input, &color_)));
               set_has_color();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(816)) goto parse_filter;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102;
           case 102: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 816) {
              parse_filter:
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    @@ -2481,271 +2865,283 @@ bool LayersPacket_Layer::MergePartialFromCodedStream(
                      input, &value)));
               if (::mozilla::layers::layerscope::LayersPacket_Layer_Filter_IsValid(value)) {
                 set_filter(static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Filter >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(824)) goto parse_refID;
             break;
           }
    -      
    +
           // optional uint64 refID = 103;
           case 103: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 824) {
              parse_refID:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                      input, &refid_)));
               set_has_refid();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(834)) goto parse_size;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104;
           case 104: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 834) {
              parse_size:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_size()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer)
    +  return false;
     #undef DO_
     }
     
     void LayersPacket_Layer::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer)
       // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1;
       if (has_type()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           1, this->type(), output);
       }
    -  
    +
       // required uint64 ptr = 2;
       if (has_ptr()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->ptr(), output);
       }
    -  
    +
       // required uint64 parentPtr = 3;
       if (has_parentptr()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->parentptr(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10;
       if (has_clip()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           10, this->clip(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11;
       if (has_transform()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           11, this->transform(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12;
       if (has_vregion()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           12, this->vregion(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13;
       if (has_shadow()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           13, this->shadow(), output);
       }
    -  
    +
       // optional float opacity = 14;
       if (has_opacity()) {
         ::google::protobuf::internal::WireFormatLite::WriteFloat(14, this->opacity(), output);
       }
    -  
    +
       // optional bool cOpaque = 15;
       if (has_copaque()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(15, this->copaque(), output);
       }
    -  
    +
       // optional bool cAlpha = 16;
       if (has_calpha()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->calpha(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17;
       if (has_direct()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           17, this->direct(), output);
       }
    -  
    +
       // optional uint64 barID = 18;
       if (has_barid()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(18, this->barid(), output);
       }
    -  
    +
       // optional uint64 mask = 19;
       if (has_mask()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(19, this->mask(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
       if (has_valid()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           100, this->valid(), output);
       }
    -  
    +
       // optional uint32 color = 101;
       if (has_color()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt32(101, this->color(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102;
       if (has_filter()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           102, this->filter(), output);
       }
    -  
    +
       // optional uint64 refID = 103;
       if (has_refid()) {
         ::google::protobuf::internal::WireFormatLite::WriteUInt64(103, this->refid(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104;
       if (has_size()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           104, this->size(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer)
     }
     
     int LayersPacket_Layer::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1;
         if (has_type()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
         }
    -    
    +
         // required uint64 ptr = 2;
         if (has_ptr()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->ptr());
         }
    -    
    +
         // required uint64 parentPtr = 3;
         if (has_parentptr()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->parentptr());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10;
         if (has_clip()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->clip());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11;
         if (has_transform()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->transform());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12;
         if (has_vregion()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->vregion());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13;
         if (has_shadow()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->shadow());
         }
    -    
    +
         // optional float opacity = 14;
         if (has_opacity()) {
           total_size += 1 + 4;
         }
    -    
    +
       }
       if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
         // optional bool cOpaque = 15;
         if (has_copaque()) {
           total_size += 1 + 1;
         }
    -    
    +
         // optional bool cAlpha = 16;
         if (has_calpha()) {
           total_size += 2 + 1;
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17;
         if (has_direct()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->direct());
         }
    -    
    +
         // optional uint64 barID = 18;
         if (has_barid()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->barid());
         }
    -    
    +
         // optional uint64 mask = 19;
         if (has_mask()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->mask());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
         if (has_valid()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->valid());
         }
    -    
    +
         // optional uint32 color = 101;
         if (has_color()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::UInt32Size(
               this->color());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102;
         if (has_filter()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->filter());
         }
    -    
    +
       }
       if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
         // optional uint64 refID = 103;
    @@ -2754,15 +3150,17 @@ int LayersPacket_Layer::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::UInt64Size(
               this->refid());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104;
         if (has_size()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->size());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -2836,6 +3234,7 @@ void LayersPacket_Layer::MergeFrom(const LayersPacket_Layer& from) {
           mutable_size()->::mozilla::layers::layerscope::LayersPacket_Layer_Size::MergeFrom(from.size());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void LayersPacket_Layer::CopyFrom(const LayersPacket_Layer& from) {
    @@ -2846,7 +3245,7 @@ void LayersPacket_Layer::CopyFrom(const LayersPacket_Layer& from) {
     
     bool LayersPacket_Layer::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;
    -  
    +
       return true;
     }
     
    @@ -2871,6 +3270,7 @@ void LayersPacket_Layer::Swap(LayersPacket_Layer* other) {
         std::swap(refid_, other->refid_);
         std::swap(size_, other->size_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -2889,6 +3289,7 @@ const int LayersPacket::kLayerFieldNumber;
     LayersPacket::LayersPacket()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket)
     }
     
     void LayersPacket::InitAsDefaultInstance() {
    @@ -2898,6 +3299,7 @@ LayersPacket::LayersPacket(const LayersPacket& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket)
     }
     
     void LayersPacket::SharedCtor() {
    @@ -2906,11 +3308,16 @@ void LayersPacket::SharedCtor() {
     }
     
     LayersPacket::~LayersPacket() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket)
       SharedDtor();
     }
     
     void LayersPacket::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -2920,7 +3327,12 @@ void LayersPacket::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const LayersPacket& LayersPacket::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     LayersPacket* LayersPacket::default_instance_ = NULL;
    @@ -2932,57 +3344,76 @@ LayersPacket* LayersPacket::New() const {
     void LayersPacket::Clear() {
       layer_.Clear();
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool LayersPacket::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
              parse_layer:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                     input, add_layer()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(10)) goto parse_layer;
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket)
    +  return false;
     #undef DO_
     }
     
     void LayersPacket::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket)
       // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1;
       for (int i = 0; i < this->layer_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           1, this->layer(i), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket)
     }
     
     int LayersPacket::ByteSize() const {
       int total_size = 0;
    -  
    +
       // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1;
       total_size += 1 * this->layer_size();
       for (int i = 0; i < this->layer_size(); i++) {
    @@ -2990,7 +3421,9 @@ int LayersPacket::ByteSize() const {
           ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
             this->layer(i));
       }
    -  
    +
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -3005,6 +3438,7 @@ void LayersPacket::CheckTypeAndMergeFrom(
     void LayersPacket::MergeFrom(const LayersPacket& from) {
       GOOGLE_CHECK_NE(&from, this);
       layer_.MergeFrom(from.layer_);
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void LayersPacket::CopyFrom(const LayersPacket& from) {
    @@ -3014,10 +3448,8 @@ void LayersPacket::CopyFrom(const LayersPacket& from) {
     }
     
     bool LayersPacket::IsInitialized() const {
    -  
    -  for (int i = 0; i < layer_size(); i++) {
    -    if (!this->layer(i).IsInitialized()) return false;
    -  }
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->layer())) return false;
       return true;
     }
     
    @@ -3025,6 +3457,7 @@ void LayersPacket::Swap(LayersPacket* other) {
       if (other != this) {
         layer_.Swap(&other->layer_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -3043,6 +3476,7 @@ const int MetaPacket::kComposedByHwcFieldNumber;
     MetaPacket::MetaPacket()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.MetaPacket)
     }
     
     void MetaPacket::InitAsDefaultInstance() {
    @@ -3052,6 +3486,7 @@ MetaPacket::MetaPacket(const MetaPacket& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.MetaPacket)
     }
     
     void MetaPacket::SharedCtor() {
    @@ -3061,11 +3496,16 @@ void MetaPacket::SharedCtor() {
     }
     
     MetaPacket::~MetaPacket() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.MetaPacket)
       SharedDtor();
     }
     
     void MetaPacket::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -3075,7 +3515,12 @@ void MetaPacket::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const MetaPacket& MetaPacket::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     MetaPacket* MetaPacket::default_instance_ = NULL;
    @@ -3085,67 +3530,86 @@ MetaPacket* MetaPacket::New() const {
     }
     
     void MetaPacket::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    composedbyhwc_ = false;
    -  }
    +  composedbyhwc_ = false;
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool MetaPacket::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.MetaPacket)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional bool composedByHwc = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &composedbyhwc_)));
               set_has_composedbyhwc();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.MetaPacket)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.MetaPacket)
    +  return false;
     #undef DO_
     }
     
     void MetaPacket::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.MetaPacket)
       // optional bool composedByHwc = 1;
       if (has_composedbyhwc()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->composedbyhwc(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.MetaPacket)
     }
     
     int MetaPacket::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional bool composedByHwc = 1;
         if (has_composedbyhwc()) {
           total_size += 1 + 1;
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -3164,6 +3628,7 @@ void MetaPacket::MergeFrom(const MetaPacket& from) {
           set_composedbyhwc(from.composedbyhwc());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void MetaPacket::CopyFrom(const MetaPacket& from) {
    @@ -3173,7 +3638,7 @@ void MetaPacket::CopyFrom(const MetaPacket& from) {
     }
     
     bool MetaPacket::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -3181,6 +3646,7 @@ void MetaPacket::Swap(MetaPacket* other) {
       if (other != this) {
         std::swap(composedbyhwc_, other->composedbyhwc_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -3229,20 +3695,47 @@ const int Packet::kMetaFieldNumber;
     Packet::Packet()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.Packet)
     }
     
     void Packet::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  frame_ = const_cast< ::mozilla::layers::layerscope::FramePacket*>(
    +      ::mozilla::layers::layerscope::FramePacket::internal_default_instance());
    +#else
       frame_ = const_cast< ::mozilla::layers::layerscope::FramePacket*>(&::mozilla::layers::layerscope::FramePacket::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  color_ = const_cast< ::mozilla::layers::layerscope::ColorPacket*>(
    +      ::mozilla::layers::layerscope::ColorPacket::internal_default_instance());
    +#else
       color_ = const_cast< ::mozilla::layers::layerscope::ColorPacket*>(&::mozilla::layers::layerscope::ColorPacket::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  texture_ = const_cast< ::mozilla::layers::layerscope::TexturePacket*>(
    +      ::mozilla::layers::layerscope::TexturePacket::internal_default_instance());
    +#else
       texture_ = const_cast< ::mozilla::layers::layerscope::TexturePacket*>(&::mozilla::layers::layerscope::TexturePacket::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  layers_ = const_cast< ::mozilla::layers::layerscope::LayersPacket*>(
    +      ::mozilla::layers::layerscope::LayersPacket::internal_default_instance());
    +#else
       layers_ = const_cast< ::mozilla::layers::layerscope::LayersPacket*>(&::mozilla::layers::layerscope::LayersPacket::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  meta_ = const_cast< ::mozilla::layers::layerscope::MetaPacket*>(
    +      ::mozilla::layers::layerscope::MetaPacket::internal_default_instance());
    +#else
       meta_ = const_cast< ::mozilla::layers::layerscope::MetaPacket*>(&::mozilla::layers::layerscope::MetaPacket::default_instance());
    +#endif
     }
     
     Packet::Packet(const Packet& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.Packet)
     }
     
     void Packet::SharedCtor() {
    @@ -3257,11 +3750,16 @@ void Packet::SharedCtor() {
     }
     
     Packet::~Packet() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.Packet)
       SharedDtor();
     }
     
     void Packet::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
         delete frame_;
         delete color_;
         delete texture_;
    @@ -3276,7 +3774,12 @@ void Packet::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const Packet& Packet::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     Packet* Packet::default_instance_ = NULL;
    @@ -3286,7 +3789,7 @@ Packet* Packet::New() const {
     }
     
     void Packet::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 63) {
         type_ = 1;
         if (has_frame()) {
           if (frame_ != NULL) frame_->::mozilla::layers::layerscope::FramePacket::Clear();
    @@ -3305,203 +3808,222 @@ void Packet::Clear() {
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool Packet::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.Packet)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required .mozilla.layers.layerscope.Packet.DataType type = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                      input, &value)));
               if (::mozilla::layers::layerscope::Packet_DataType_IsValid(value)) {
                 set_type(static_cast< ::mozilla::layers::layerscope::Packet_DataType >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_frame;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.FramePacket frame = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_frame:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_frame()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(26)) goto parse_color;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.ColorPacket color = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 26) {
              parse_color:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_color()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(34)) goto parse_texture;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.TexturePacket texture = 4;
           case 4: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 34) {
              parse_texture:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_texture()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(42)) goto parse_layers;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.LayersPacket layers = 5;
           case 5: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 42) {
              parse_layers:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_layers()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(50)) goto parse_meta;
             break;
           }
    -      
    +
           // optional .mozilla.layers.layerscope.MetaPacket meta = 6;
           case 6: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 50) {
              parse_meta:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_meta()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.Packet)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.Packet)
    +  return false;
     #undef DO_
     }
     
     void Packet::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.Packet)
       // required .mozilla.layers.layerscope.Packet.DataType type = 1;
       if (has_type()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           1, this->type(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.FramePacket frame = 2;
       if (has_frame()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           2, this->frame(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.ColorPacket color = 3;
       if (has_color()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           3, this->color(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.TexturePacket texture = 4;
       if (has_texture()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           4, this->texture(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket layers = 5;
       if (has_layers()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           5, this->layers(), output);
       }
    -  
    +
       // optional .mozilla.layers.layerscope.MetaPacket meta = 6;
       if (has_meta()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           6, this->meta(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.Packet)
     }
     
     int Packet::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required .mozilla.layers.layerscope.Packet.DataType type = 1;
         if (has_type()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.FramePacket frame = 2;
         if (has_frame()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->frame());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.ColorPacket color = 3;
         if (has_color()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->color());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.TexturePacket texture = 4;
         if (has_texture()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->texture());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.LayersPacket layers = 5;
         if (has_layers()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->layers());
         }
    -    
    +
         // optional .mozilla.layers.layerscope.MetaPacket meta = 6;
         if (has_meta()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->meta());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -3535,6 +4057,7 @@ void Packet::MergeFrom(const Packet& from) {
           mutable_meta()->::mozilla::layers::layerscope::MetaPacket::MergeFrom(from.meta());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void Packet::CopyFrom(const Packet& from) {
    @@ -3545,7 +4068,7 @@ void Packet::CopyFrom(const Packet& from) {
     
     bool Packet::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    -  
    +
       if (has_color()) {
         if (!this->color().IsInitialized()) return false;
       }
    @@ -3567,6 +4090,7 @@ void Packet::Swap(Packet* other) {
         std::swap(layers_, other->layers_);
         std::swap(meta_, other->meta_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -3605,6 +4129,7 @@ const int CommandPacket::kValueFieldNumber;
     CommandPacket::CommandPacket()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.CommandPacket)
     }
     
     void CommandPacket::InitAsDefaultInstance() {
    @@ -3614,6 +4139,7 @@ CommandPacket::CommandPacket(const CommandPacket& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.CommandPacket)
     }
     
     void CommandPacket::SharedCtor() {
    @@ -3624,11 +4150,16 @@ void CommandPacket::SharedCtor() {
     }
     
     CommandPacket::~CommandPacket() {
    +  // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.CommandPacket)
       SharedDtor();
     }
     
     void CommandPacket::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -3638,7 +4169,12 @@ void CommandPacket::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const CommandPacket& CommandPacket::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_LayerScopePacket_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     CommandPacket* CommandPacket::default_instance_ = NULL;
    @@ -3648,99 +4184,133 @@ CommandPacket* CommandPacket::New() const {
     }
     
     void CommandPacket::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    type_ = 0;
    -    value_ = false;
    -  }
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(type_, value_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool CommandPacket::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.CommandPacket)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                      input, &value)));
               if (::mozilla::layers::layerscope::CommandPacket_CmdType_IsValid(value)) {
                 set_type(static_cast< ::mozilla::layers::layerscope::CommandPacket_CmdType >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_value;
             break;
           }
    -      
    +
           // optional bool value = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_value:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &value_)));
               set_has_value();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.CommandPacket)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.CommandPacket)
    +  return false;
     #undef DO_
     }
     
     void CommandPacket::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.CommandPacket)
       // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1;
       if (has_type()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           1, this->type(), output);
       }
    -  
    +
       // optional bool value = 2;
       if (has_value()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->value(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.CommandPacket)
     }
     
     int CommandPacket::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1;
         if (has_type()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
         }
    -    
    +
         // optional bool value = 2;
         if (has_value()) {
           total_size += 1 + 1;
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -3762,6 +4332,7 @@ void CommandPacket::MergeFrom(const CommandPacket& from) {
           set_value(from.value());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void CommandPacket::CopyFrom(const CommandPacket& from) {
    @@ -3772,7 +4343,7 @@ void CommandPacket::CopyFrom(const CommandPacket& from) {
     
     bool CommandPacket::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    -  
    +
       return true;
     }
     
    @@ -3781,6 +4352,7 @@ void CommandPacket::Swap(CommandPacket* other) {
         std::swap(type_, other->type_);
         std::swap(value_, other->value_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.h b/gfx/layers/protobuf/LayerScopePacket.pb.h
    index 4f49ba9a7bcd..7aea54388a14 100644
    --- a/gfx/layers/protobuf/LayerScopePacket.pb.h
    +++ b/gfx/layers/protobuf/LayerScopePacket.pb.h
    @@ -8,18 +8,19 @@
     
     #include 
     
    -#if GOOGLE_PROTOBUF_VERSION < 2004000
    +#if GOOGLE_PROTOBUF_VERSION < 2006000
     #error This file was generated by a newer version of protoc which is
     #error incompatible with your Protocol Buffer headers.  Please update
     #error your headers.
     #endif
    -#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
    +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
     #error This file was generated by an older version of protoc which is
     #error incompatible with your Protocol Buffer headers.  Please
     #error regenerate this file with a newer version of protoc.
     #endif
     
     #include 
    +#include 
     #include 
     #include 
     // @@protoc_insertion_point(includes)
    @@ -115,66 +116,88 @@ class FramePacket : public ::google::protobuf::MessageLite {
      public:
       FramePacket();
       virtual ~FramePacket();
    -  
    +
       FramePacket(const FramePacket& from);
    -  
    +
       inline FramePacket& operator=(const FramePacket& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const FramePacket& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const FramePacket* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(FramePacket* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       FramePacket* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const FramePacket& from);
       void MergeFrom(const FramePacket& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional uint64 value = 1;
       inline bool has_value() const;
       inline void clear_value();
       static const int kValueFieldNumber = 1;
       inline ::google::protobuf::uint64 value() const;
       inline void set_value(::google::protobuf::uint64 value);
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.FramePacket)
      private:
       inline void set_has_value();
       inline void clear_has_value();
    -  
    -  ::google::protobuf::uint64 value_;
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
    -  
    +  ::google::protobuf::uint64 value_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static FramePacket* default_instance_;
     };
    @@ -184,73 +207,91 @@ class ColorPacket : public ::google::protobuf::MessageLite {
      public:
       ColorPacket();
       virtual ~ColorPacket();
    -  
    +
       ColorPacket(const ColorPacket& from);
    -  
    +
       inline ColorPacket& operator=(const ColorPacket& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ColorPacket& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ColorPacket* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ColorPacket* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ColorPacket* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ColorPacket& from);
       void MergeFrom(const ColorPacket& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // required uint64 layerref = 1;
       inline bool has_layerref() const;
       inline void clear_layerref();
       static const int kLayerrefFieldNumber = 1;
       inline ::google::protobuf::uint64 layerref() const;
       inline void set_layerref(::google::protobuf::uint64 value);
    -  
    +
       // optional uint32 width = 2;
       inline bool has_width() const;
       inline void clear_width();
       static const int kWidthFieldNumber = 2;
       inline ::google::protobuf::uint32 width() const;
       inline void set_width(::google::protobuf::uint32 value);
    -  
    +
       // optional uint32 height = 3;
       inline bool has_height() const;
       inline void clear_height();
       static const int kHeightFieldNumber = 3;
       inline ::google::protobuf::uint32 height() const;
       inline void set_height(::google::protobuf::uint32 value);
    -  
    +
       // optional uint32 color = 4;
       inline bool has_color() const;
       inline void clear_color();
       static const int kColorFieldNumber = 4;
       inline ::google::protobuf::uint32 color() const;
       inline void set_color(::google::protobuf::uint32 value);
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.ColorPacket)
      private:
       inline void set_has_layerref();
    @@ -261,19 +302,23 @@ class ColorPacket : public ::google::protobuf::MessageLite {
       inline void clear_has_height();
       inline void set_has_color();
       inline void clear_has_color();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::google::protobuf::uint64 layerref_;
       ::google::protobuf::uint32 width_;
       ::google::protobuf::uint32 height_;
       ::google::protobuf::uint32 color_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ColorPacket* default_instance_;
     };
    @@ -283,101 +328,119 @@ class TexturePacket : public ::google::protobuf::MessageLite {
      public:
       TexturePacket();
       virtual ~TexturePacket();
    -  
    +
       TexturePacket(const TexturePacket& from);
    -  
    +
       inline TexturePacket& operator=(const TexturePacket& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const TexturePacket& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const TexturePacket* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(TexturePacket* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       TexturePacket* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const TexturePacket& from);
       void MergeFrom(const TexturePacket& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // required uint64 layerref = 1;
       inline bool has_layerref() const;
       inline void clear_layerref();
       static const int kLayerrefFieldNumber = 1;
       inline ::google::protobuf::uint64 layerref() const;
       inline void set_layerref(::google::protobuf::uint64 value);
    -  
    +
       // optional uint32 width = 2;
       inline bool has_width() const;
       inline void clear_width();
       static const int kWidthFieldNumber = 2;
       inline ::google::protobuf::uint32 width() const;
       inline void set_width(::google::protobuf::uint32 value);
    -  
    +
       // optional uint32 height = 3;
       inline bool has_height() const;
       inline void clear_height();
       static const int kHeightFieldNumber = 3;
       inline ::google::protobuf::uint32 height() const;
       inline void set_height(::google::protobuf::uint32 value);
    -  
    +
       // optional uint32 stride = 4;
       inline bool has_stride() const;
       inline void clear_stride();
       static const int kStrideFieldNumber = 4;
       inline ::google::protobuf::uint32 stride() const;
       inline void set_stride(::google::protobuf::uint32 value);
    -  
    +
       // optional uint32 name = 5;
       inline bool has_name() const;
       inline void clear_name();
       static const int kNameFieldNumber = 5;
       inline ::google::protobuf::uint32 name() const;
       inline void set_name(::google::protobuf::uint32 value);
    -  
    +
       // optional uint32 target = 6;
       inline bool has_target() const;
       inline void clear_target();
       static const int kTargetFieldNumber = 6;
       inline ::google::protobuf::uint32 target() const;
       inline void set_target(::google::protobuf::uint32 value);
    -  
    +
       // optional uint32 dataformat = 7;
       inline bool has_dataformat() const;
       inline void clear_dataformat();
       static const int kDataformatFieldNumber = 7;
       inline ::google::protobuf::uint32 dataformat() const;
       inline void set_dataformat(::google::protobuf::uint32 value);
    -  
    +
       // optional uint64 glcontext = 8;
       inline bool has_glcontext() const;
       inline void clear_glcontext();
       static const int kGlcontextFieldNumber = 8;
       inline ::google::protobuf::uint64 glcontext() const;
       inline void set_glcontext(::google::protobuf::uint64 value);
    -  
    +
       // optional bytes data = 9;
       inline bool has_data() const;
       inline void clear_data();
    @@ -388,7 +451,8 @@ class TexturePacket : public ::google::protobuf::MessageLite {
       inline void set_data(const void* value, size_t size);
       inline ::std::string* mutable_data();
       inline ::std::string* release_data();
    -  
    +  inline void set_allocated_data(::std::string* data);
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.TexturePacket)
      private:
       inline void set_has_layerref();
    @@ -409,7 +473,11 @@ class TexturePacket : public ::google::protobuf::MessageLite {
       inline void clear_has_glcontext();
       inline void set_has_data();
       inline void clear_has_data();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::google::protobuf::uint64 layerref_;
       ::google::protobuf::uint32 width_;
       ::google::protobuf::uint32 height_;
    @@ -419,14 +487,14 @@ class TexturePacket : public ::google::protobuf::MessageLite {
       ::google::protobuf::uint32 dataformat_;
       ::google::protobuf::uint64 glcontext_;
       ::std::string* data_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static TexturePacket* default_instance_;
     };
    @@ -436,76 +504,98 @@ class LayersPacket_Layer_Size : public ::google::protobuf::MessageLite {
      public:
       LayersPacket_Layer_Size();
       virtual ~LayersPacket_Layer_Size();
    -  
    +
       LayersPacket_Layer_Size(const LayersPacket_Layer_Size& from);
    -  
    +
       inline LayersPacket_Layer_Size& operator=(const LayersPacket_Layer_Size& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const LayersPacket_Layer_Size& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const LayersPacket_Layer_Size* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(LayersPacket_Layer_Size* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       LayersPacket_Layer_Size* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const LayersPacket_Layer_Size& from);
       void MergeFrom(const LayersPacket_Layer_Size& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional int32 w = 1;
       inline bool has_w() const;
       inline void clear_w();
       static const int kWFieldNumber = 1;
       inline ::google::protobuf::int32 w() const;
       inline void set_w(::google::protobuf::int32 value);
    -  
    +
       // optional int32 h = 2;
       inline bool has_h() const;
       inline void clear_h();
       static const int kHFieldNumber = 2;
       inline ::google::protobuf::int32 h() const;
       inline void set_h(::google::protobuf::int32 value);
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Size)
      private:
       inline void set_has_w();
       inline void clear_has_w();
       inline void set_has_h();
       inline void clear_has_h();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::google::protobuf::int32 w_;
       ::google::protobuf::int32 h_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static LayersPacket_Layer_Size* default_instance_;
     };
    @@ -515,73 +605,91 @@ class LayersPacket_Layer_Rect : public ::google::protobuf::MessageLite {
      public:
       LayersPacket_Layer_Rect();
       virtual ~LayersPacket_Layer_Rect();
    -  
    +
       LayersPacket_Layer_Rect(const LayersPacket_Layer_Rect& from);
    -  
    +
       inline LayersPacket_Layer_Rect& operator=(const LayersPacket_Layer_Rect& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const LayersPacket_Layer_Rect& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const LayersPacket_Layer_Rect* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(LayersPacket_Layer_Rect* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       LayersPacket_Layer_Rect* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const LayersPacket_Layer_Rect& from);
       void MergeFrom(const LayersPacket_Layer_Rect& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional int32 x = 1;
       inline bool has_x() const;
       inline void clear_x();
       static const int kXFieldNumber = 1;
       inline ::google::protobuf::int32 x() const;
       inline void set_x(::google::protobuf::int32 value);
    -  
    +
       // optional int32 y = 2;
       inline bool has_y() const;
       inline void clear_y();
       static const int kYFieldNumber = 2;
       inline ::google::protobuf::int32 y() const;
       inline void set_y(::google::protobuf::int32 value);
    -  
    +
       // optional int32 w = 3;
       inline bool has_w() const;
       inline void clear_w();
       static const int kWFieldNumber = 3;
       inline ::google::protobuf::int32 w() const;
       inline void set_w(::google::protobuf::int32 value);
    -  
    +
       // optional int32 h = 4;
       inline bool has_h() const;
       inline void clear_h();
       static const int kHFieldNumber = 4;
       inline ::google::protobuf::int32 h() const;
       inline void set_h(::google::protobuf::int32 value);
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Rect)
      private:
       inline void set_has_x();
    @@ -592,19 +700,23 @@ class LayersPacket_Layer_Rect : public ::google::protobuf::MessageLite {
       inline void clear_has_w();
       inline void set_has_h();
       inline void clear_has_h();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::google::protobuf::int32 x_;
       ::google::protobuf::int32 y_;
       ::google::protobuf::int32 w_;
       ::google::protobuf::int32 h_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static LayersPacket_Layer_Rect* default_instance_;
     };
    @@ -614,45 +726,63 @@ class LayersPacket_Layer_Region : public ::google::protobuf::MessageLite {
      public:
       LayersPacket_Layer_Region();
       virtual ~LayersPacket_Layer_Region();
    -  
    +
       LayersPacket_Layer_Region(const LayersPacket_Layer_Region& from);
    -  
    +
       inline LayersPacket_Layer_Region& operator=(const LayersPacket_Layer_Region& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const LayersPacket_Layer_Region& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const LayersPacket_Layer_Region* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(LayersPacket_Layer_Region* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       LayersPacket_Layer_Region* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const LayersPacket_Layer_Region& from);
       void MergeFrom(const LayersPacket_Layer_Region& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1;
       inline int r_size() const;
       inline void clear_r();
    @@ -664,19 +794,23 @@ class LayersPacket_Layer_Region : public ::google::protobuf::MessageLite {
           r() const;
       inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect >*
           mutable_r();
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Region)
      private:
    -  
    -  ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect > r_;
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
    -  
    +  ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect > r_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static LayersPacket_Layer_Region* default_instance_;
     };
    @@ -686,59 +820,77 @@ class LayersPacket_Layer_Matrix : public ::google::protobuf::MessageLite {
      public:
       LayersPacket_Layer_Matrix();
       virtual ~LayersPacket_Layer_Matrix();
    -  
    +
       LayersPacket_Layer_Matrix(const LayersPacket_Layer_Matrix& from);
    -  
    +
       inline LayersPacket_Layer_Matrix& operator=(const LayersPacket_Layer_Matrix& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const LayersPacket_Layer_Matrix& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const LayersPacket_Layer_Matrix* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(LayersPacket_Layer_Matrix* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       LayersPacket_Layer_Matrix* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const LayersPacket_Layer_Matrix& from);
       void MergeFrom(const LayersPacket_Layer_Matrix& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional bool is2D = 1;
       inline bool has_is2d() const;
       inline void clear_is2d();
       static const int kIs2DFieldNumber = 1;
       inline bool is2d() const;
       inline void set_is2d(bool value);
    -  
    +
       // optional bool isId = 2;
       inline bool has_isid() const;
       inline void clear_isid();
       static const int kIsIdFieldNumber = 2;
       inline bool isid() const;
       inline void set_isid(bool value);
    -  
    +
       // repeated float m = 3;
       inline int m_size() const;
       inline void clear_m();
    @@ -750,25 +902,29 @@ class LayersPacket_Layer_Matrix : public ::google::protobuf::MessageLite {
           m() const;
       inline ::google::protobuf::RepeatedField< float >*
           mutable_m();
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Matrix)
      private:
       inline void set_has_is2d();
       inline void clear_has_is2d();
       inline void set_has_isid();
       inline void clear_has_isid();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::google::protobuf::RepeatedField< float > m_;
       bool is2d_;
       bool isid_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static LayersPacket_Layer_Matrix* default_instance_;
     };
    @@ -778,45 +934,63 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite {
      public:
       LayersPacket_Layer_Shadow();
       virtual ~LayersPacket_Layer_Shadow();
    -  
    +
       LayersPacket_Layer_Shadow(const LayersPacket_Layer_Shadow& from);
    -  
    +
       inline LayersPacket_Layer_Shadow& operator=(const LayersPacket_Layer_Shadow& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const LayersPacket_Layer_Shadow& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const LayersPacket_Layer_Shadow* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(LayersPacket_Layer_Shadow* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       LayersPacket_Layer_Shadow* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const LayersPacket_Layer_Shadow& from);
       void MergeFrom(const LayersPacket_Layer_Shadow& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1;
       inline bool has_clip() const;
       inline void clear_clip();
    @@ -824,7 +998,8 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& clip() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* mutable_clip();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* release_clip();
    -  
    +  inline void set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip);
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2;
       inline bool has_transform() const;
       inline void clear_transform();
    @@ -832,7 +1007,8 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& transform() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* mutable_transform();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* release_transform();
    -  
    +  inline void set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform);
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3;
       inline bool has_vregion() const;
       inline void clear_vregion();
    @@ -840,7 +1016,8 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& vregion() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_vregion();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_vregion();
    -  
    +  inline void set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion);
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Shadow)
      private:
       inline void set_has_clip();
    @@ -849,18 +1026,22 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite {
       inline void clear_has_transform();
       inline void set_has_vregion();
       inline void clear_has_vregion();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip_;
       ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform_;
       ::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static LayersPacket_Layer_Shadow* default_instance_;
     };
    @@ -870,49 +1051,67 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
      public:
       LayersPacket_Layer();
       virtual ~LayersPacket_Layer();
    -  
    +
       LayersPacket_Layer(const LayersPacket_Layer& from);
    -  
    +
       inline LayersPacket_Layer& operator=(const LayersPacket_Layer& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const LayersPacket_Layer& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const LayersPacket_Layer* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(LayersPacket_Layer* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       LayersPacket_Layer* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const LayersPacket_Layer& from);
       void MergeFrom(const LayersPacket_Layer& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef LayersPacket_Layer_Size Size;
       typedef LayersPacket_Layer_Rect Rect;
       typedef LayersPacket_Layer_Region Region;
       typedef LayersPacket_Layer_Matrix Matrix;
       typedef LayersPacket_Layer_Shadow Shadow;
    -  
    +
       typedef LayersPacket_Layer_LayerType LayerType;
       static const LayerType UnknownLayer = LayersPacket_Layer_LayerType_UnknownLayer;
       static const LayerType LayerManager = LayersPacket_Layer_LayerType_LayerManager;
    @@ -932,7 +1131,7 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
         LayersPacket_Layer_LayerType_LayerType_MAX;
       static const int LayerType_ARRAYSIZE =
         LayersPacket_Layer_LayerType_LayerType_ARRAYSIZE;
    -  
    +
       typedef LayersPacket_Layer_ScrollingDirect ScrollingDirect;
       static const ScrollingDirect VERTICAL = LayersPacket_Layer_ScrollingDirect_VERTICAL;
       static const ScrollingDirect HORIZONTAL = LayersPacket_Layer_ScrollingDirect_HORIZONTAL;
    @@ -945,7 +1144,7 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
         LayersPacket_Layer_ScrollingDirect_ScrollingDirect_MAX;
       static const int ScrollingDirect_ARRAYSIZE =
         LayersPacket_Layer_ScrollingDirect_ScrollingDirect_ARRAYSIZE;
    -  
    +
       typedef LayersPacket_Layer_Filter Filter;
       static const Filter FILTER_FAST = LayersPacket_Layer_Filter_FILTER_FAST;
       static const Filter FILTER_GOOD = LayersPacket_Layer_Filter_FILTER_GOOD;
    @@ -963,30 +1162,30 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
         LayersPacket_Layer_Filter_Filter_MAX;
       static const int Filter_ARRAYSIZE =
         LayersPacket_Layer_Filter_Filter_ARRAYSIZE;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1;
       inline bool has_type() const;
       inline void clear_type();
       static const int kTypeFieldNumber = 1;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType type() const;
       inline void set_type(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType value);
    -  
    +
       // required uint64 ptr = 2;
       inline bool has_ptr() const;
       inline void clear_ptr();
       static const int kPtrFieldNumber = 2;
       inline ::google::protobuf::uint64 ptr() const;
       inline void set_ptr(::google::protobuf::uint64 value);
    -  
    +
       // required uint64 parentPtr = 3;
       inline bool has_parentptr() const;
       inline void clear_parentptr();
       static const int kParentPtrFieldNumber = 3;
       inline ::google::protobuf::uint64 parentptr() const;
       inline void set_parentptr(::google::protobuf::uint64 value);
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10;
       inline bool has_clip() const;
       inline void clear_clip();
    @@ -994,7 +1193,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& clip() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* mutable_clip();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* release_clip();
    -  
    +  inline void set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip);
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11;
       inline bool has_transform() const;
       inline void clear_transform();
    @@ -1002,7 +1202,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& transform() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* mutable_transform();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* release_transform();
    -  
    +  inline void set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform);
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12;
       inline bool has_vregion() const;
       inline void clear_vregion();
    @@ -1010,7 +1211,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& vregion() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_vregion();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_vregion();
    -  
    +  inline void set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion);
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13;
       inline bool has_shadow() const;
       inline void clear_shadow();
    @@ -1018,49 +1220,50 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow& shadow() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* mutable_shadow();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* release_shadow();
    -  
    +  inline void set_allocated_shadow(::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* shadow);
    +
       // optional float opacity = 14;
       inline bool has_opacity() const;
       inline void clear_opacity();
       static const int kOpacityFieldNumber = 14;
       inline float opacity() const;
       inline void set_opacity(float value);
    -  
    +
       // optional bool cOpaque = 15;
       inline bool has_copaque() const;
       inline void clear_copaque();
       static const int kCOpaqueFieldNumber = 15;
       inline bool copaque() const;
       inline void set_copaque(bool value);
    -  
    +
       // optional bool cAlpha = 16;
       inline bool has_calpha() const;
       inline void clear_calpha();
       static const int kCAlphaFieldNumber = 16;
       inline bool calpha() const;
       inline void set_calpha(bool value);
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17;
       inline bool has_direct() const;
       inline void clear_direct();
       static const int kDirectFieldNumber = 17;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect direct() const;
       inline void set_direct(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect value);
    -  
    +
       // optional uint64 barID = 18;
       inline bool has_barid() const;
       inline void clear_barid();
       static const int kBarIDFieldNumber = 18;
       inline ::google::protobuf::uint64 barid() const;
       inline void set_barid(::google::protobuf::uint64 value);
    -  
    +
       // optional uint64 mask = 19;
       inline bool has_mask() const;
       inline void clear_mask();
       static const int kMaskFieldNumber = 19;
       inline ::google::protobuf::uint64 mask() const;
       inline void set_mask(::google::protobuf::uint64 value);
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
       inline bool has_valid() const;
       inline void clear_valid();
    @@ -1068,28 +1271,29 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& valid() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_valid();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_valid();
    -  
    +  inline void set_allocated_valid(::mozilla::layers::layerscope::LayersPacket_Layer_Region* valid);
    +
       // optional uint32 color = 101;
       inline bool has_color() const;
       inline void clear_color();
       static const int kColorFieldNumber = 101;
       inline ::google::protobuf::uint32 color() const;
       inline void set_color(::google::protobuf::uint32 value);
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102;
       inline bool has_filter() const;
       inline void clear_filter();
       static const int kFilterFieldNumber = 102;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Filter filter() const;
       inline void set_filter(::mozilla::layers::layerscope::LayersPacket_Layer_Filter value);
    -  
    +
       // optional uint64 refID = 103;
       inline bool has_refid() const;
       inline void clear_refid();
       static const int kRefIDFieldNumber = 103;
       inline ::google::protobuf::uint64 refid() const;
       inline void set_refid(::google::protobuf::uint64 value);
    -  
    +
       // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104;
       inline bool has_size() const;
       inline void clear_size();
    @@ -1097,7 +1301,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Size& size() const;
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* mutable_size();
       inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* release_size();
    -  
    +  inline void set_allocated_size(::mozilla::layers::layerscope::LayersPacket_Layer_Size* size);
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer)
      private:
       inline void set_has_type();
    @@ -1136,7 +1341,11 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       inline void clear_has_refid();
       inline void set_has_size();
       inline void clear_has_size();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::google::protobuf::uint64 ptr_;
       ::google::protobuf::uint64 parentptr_;
       ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip_;
    @@ -1155,14 +1364,14 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
       int filter_;
       ::google::protobuf::uint64 refid_;
       ::mozilla::layers::layerscope::LayersPacket_Layer_Size* size_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(18 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static LayersPacket_Layer* default_instance_;
     };
    @@ -1172,47 +1381,65 @@ class LayersPacket : public ::google::protobuf::MessageLite {
      public:
       LayersPacket();
       virtual ~LayersPacket();
    -  
    +
       LayersPacket(const LayersPacket& from);
    -  
    +
       inline LayersPacket& operator=(const LayersPacket& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const LayersPacket& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const LayersPacket* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(LayersPacket* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       LayersPacket* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const LayersPacket& from);
       void MergeFrom(const LayersPacket& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef LayersPacket_Layer Layer;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1;
       inline int layer_size() const;
       inline void clear_layer();
    @@ -1224,19 +1451,23 @@ class LayersPacket : public ::google::protobuf::MessageLite {
           layer() const;
       inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer >*
           mutable_layer();
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket)
      private:
    -  
    -  ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer > layer_;
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
    -  
    +  ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer > layer_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static LayersPacket* default_instance_;
     };
    @@ -1246,66 +1477,88 @@ class MetaPacket : public ::google::protobuf::MessageLite {
      public:
       MetaPacket();
       virtual ~MetaPacket();
    -  
    +
       MetaPacket(const MetaPacket& from);
    -  
    +
       inline MetaPacket& operator=(const MetaPacket& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const MetaPacket& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const MetaPacket* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(MetaPacket* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       MetaPacket* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const MetaPacket& from);
       void MergeFrom(const MetaPacket& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional bool composedByHwc = 1;
       inline bool has_composedbyhwc() const;
       inline void clear_composedbyhwc();
       static const int kComposedByHwcFieldNumber = 1;
       inline bool composedbyhwc() const;
       inline void set_composedbyhwc(bool value);
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.MetaPacket)
      private:
       inline void set_has_composedbyhwc();
       inline void clear_has_composedbyhwc();
    -  
    -  bool composedbyhwc_;
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
    -  
    +  bool composedbyhwc_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static MetaPacket* default_instance_;
     };
    @@ -1315,43 +1568,61 @@ class Packet : public ::google::protobuf::MessageLite {
      public:
       Packet();
       virtual ~Packet();
    -  
    +
       Packet(const Packet& from);
    -  
    +
       inline Packet& operator=(const Packet& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const Packet& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const Packet* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(Packet* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       Packet* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const Packet& from);
       void MergeFrom(const Packet& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef Packet_DataType DataType;
       static const DataType FRAMESTART = Packet_DataType_FRAMESTART;
       static const DataType FRAMEEND = Packet_DataType_FRAMEEND;
    @@ -1368,16 +1639,16 @@ class Packet : public ::google::protobuf::MessageLite {
         Packet_DataType_DataType_MAX;
       static const int DataType_ARRAYSIZE =
         Packet_DataType_DataType_ARRAYSIZE;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // required .mozilla.layers.layerscope.Packet.DataType type = 1;
       inline bool has_type() const;
       inline void clear_type();
       static const int kTypeFieldNumber = 1;
       inline ::mozilla::layers::layerscope::Packet_DataType type() const;
       inline void set_type(::mozilla::layers::layerscope::Packet_DataType value);
    -  
    +
       // optional .mozilla.layers.layerscope.FramePacket frame = 2;
       inline bool has_frame() const;
       inline void clear_frame();
    @@ -1385,7 +1656,8 @@ class Packet : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::FramePacket& frame() const;
       inline ::mozilla::layers::layerscope::FramePacket* mutable_frame();
       inline ::mozilla::layers::layerscope::FramePacket* release_frame();
    -  
    +  inline void set_allocated_frame(::mozilla::layers::layerscope::FramePacket* frame);
    +
       // optional .mozilla.layers.layerscope.ColorPacket color = 3;
       inline bool has_color() const;
       inline void clear_color();
    @@ -1393,7 +1665,8 @@ class Packet : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::ColorPacket& color() const;
       inline ::mozilla::layers::layerscope::ColorPacket* mutable_color();
       inline ::mozilla::layers::layerscope::ColorPacket* release_color();
    -  
    +  inline void set_allocated_color(::mozilla::layers::layerscope::ColorPacket* color);
    +
       // optional .mozilla.layers.layerscope.TexturePacket texture = 4;
       inline bool has_texture() const;
       inline void clear_texture();
    @@ -1401,7 +1674,8 @@ class Packet : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::TexturePacket& texture() const;
       inline ::mozilla::layers::layerscope::TexturePacket* mutable_texture();
       inline ::mozilla::layers::layerscope::TexturePacket* release_texture();
    -  
    +  inline void set_allocated_texture(::mozilla::layers::layerscope::TexturePacket* texture);
    +
       // optional .mozilla.layers.layerscope.LayersPacket layers = 5;
       inline bool has_layers() const;
       inline void clear_layers();
    @@ -1409,7 +1683,8 @@ class Packet : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::LayersPacket& layers() const;
       inline ::mozilla::layers::layerscope::LayersPacket* mutable_layers();
       inline ::mozilla::layers::layerscope::LayersPacket* release_layers();
    -  
    +  inline void set_allocated_layers(::mozilla::layers::layerscope::LayersPacket* layers);
    +
       // optional .mozilla.layers.layerscope.MetaPacket meta = 6;
       inline bool has_meta() const;
       inline void clear_meta();
    @@ -1417,7 +1692,8 @@ class Packet : public ::google::protobuf::MessageLite {
       inline const ::mozilla::layers::layerscope::MetaPacket& meta() const;
       inline ::mozilla::layers::layerscope::MetaPacket* mutable_meta();
       inline ::mozilla::layers::layerscope::MetaPacket* release_meta();
    -  
    +  inline void set_allocated_meta(::mozilla::layers::layerscope::MetaPacket* meta);
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.Packet)
      private:
       inline void set_has_type();
    @@ -1432,21 +1708,25 @@ class Packet : public ::google::protobuf::MessageLite {
       inline void clear_has_layers();
       inline void set_has_meta();
       inline void clear_has_meta();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::mozilla::layers::layerscope::FramePacket* frame_;
       ::mozilla::layers::layerscope::ColorPacket* color_;
       ::mozilla::layers::layerscope::TexturePacket* texture_;
       ::mozilla::layers::layerscope::LayersPacket* layers_;
       ::mozilla::layers::layerscope::MetaPacket* meta_;
       int type_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static Packet* default_instance_;
     };
    @@ -1456,43 +1736,61 @@ class CommandPacket : public ::google::protobuf::MessageLite {
      public:
       CommandPacket();
       virtual ~CommandPacket();
    -  
    +
       CommandPacket(const CommandPacket& from);
    -  
    +
       inline CommandPacket& operator=(const CommandPacket& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const CommandPacket& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const CommandPacket* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(CommandPacket* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       CommandPacket* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const CommandPacket& from);
       void MergeFrom(const CommandPacket& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef CommandPacket_CmdType CmdType;
       static const CmdType NO_OP = CommandPacket_CmdType_NO_OP;
       static const CmdType LAYERS_TREE = CommandPacket_CmdType_LAYERS_TREE;
    @@ -1506,40 +1804,44 @@ class CommandPacket : public ::google::protobuf::MessageLite {
         CommandPacket_CmdType_CmdType_MAX;
       static const int CmdType_ARRAYSIZE =
         CommandPacket_CmdType_CmdType_ARRAYSIZE;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1;
       inline bool has_type() const;
       inline void clear_type();
       static const int kTypeFieldNumber = 1;
       inline ::mozilla::layers::layerscope::CommandPacket_CmdType type() const;
       inline void set_type(::mozilla::layers::layerscope::CommandPacket_CmdType value);
    -  
    +
       // optional bool value = 2;
       inline bool has_value() const;
       inline void clear_value();
       static const int kValueFieldNumber = 2;
       inline bool value() const;
       inline void set_value(bool value);
    -  
    +
       // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.CommandPacket)
      private:
       inline void set_has_type();
       inline void clear_has_type();
       inline void set_has_value();
       inline void clear_has_value();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       int type_;
       bool value_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_LayerScopePacket_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_LayerScopePacket_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
       friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static CommandPacket* default_instance_;
     };
    @@ -1565,11 +1867,13 @@ inline void FramePacket::clear_value() {
       clear_has_value();
     }
     inline ::google::protobuf::uint64 FramePacket::value() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.FramePacket.value)
       return value_;
     }
     inline void FramePacket::set_value(::google::protobuf::uint64 value) {
       set_has_value();
       value_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.FramePacket.value)
     }
     
     // -------------------------------------------------------------------
    @@ -1591,11 +1895,13 @@ inline void ColorPacket::clear_layerref() {
       clear_has_layerref();
     }
     inline ::google::protobuf::uint64 ColorPacket::layerref() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.layerref)
       return layerref_;
     }
     inline void ColorPacket::set_layerref(::google::protobuf::uint64 value) {
       set_has_layerref();
       layerref_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.layerref)
     }
     
     // optional uint32 width = 2;
    @@ -1613,11 +1919,13 @@ inline void ColorPacket::clear_width() {
       clear_has_width();
     }
     inline ::google::protobuf::uint32 ColorPacket::width() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.width)
       return width_;
     }
     inline void ColorPacket::set_width(::google::protobuf::uint32 value) {
       set_has_width();
       width_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.width)
     }
     
     // optional uint32 height = 3;
    @@ -1635,11 +1943,13 @@ inline void ColorPacket::clear_height() {
       clear_has_height();
     }
     inline ::google::protobuf::uint32 ColorPacket::height() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.height)
       return height_;
     }
     inline void ColorPacket::set_height(::google::protobuf::uint32 value) {
       set_has_height();
       height_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.height)
     }
     
     // optional uint32 color = 4;
    @@ -1657,11 +1967,13 @@ inline void ColorPacket::clear_color() {
       clear_has_color();
     }
     inline ::google::protobuf::uint32 ColorPacket::color() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.color)
       return color_;
     }
     inline void ColorPacket::set_color(::google::protobuf::uint32 value) {
       set_has_color();
       color_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.color)
     }
     
     // -------------------------------------------------------------------
    @@ -1683,11 +1995,13 @@ inline void TexturePacket::clear_layerref() {
       clear_has_layerref();
     }
     inline ::google::protobuf::uint64 TexturePacket::layerref() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.layerref)
       return layerref_;
     }
     inline void TexturePacket::set_layerref(::google::protobuf::uint64 value) {
       set_has_layerref();
       layerref_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.layerref)
     }
     
     // optional uint32 width = 2;
    @@ -1705,11 +2019,13 @@ inline void TexturePacket::clear_width() {
       clear_has_width();
     }
     inline ::google::protobuf::uint32 TexturePacket::width() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.width)
       return width_;
     }
     inline void TexturePacket::set_width(::google::protobuf::uint32 value) {
       set_has_width();
       width_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.width)
     }
     
     // optional uint32 height = 3;
    @@ -1727,11 +2043,13 @@ inline void TexturePacket::clear_height() {
       clear_has_height();
     }
     inline ::google::protobuf::uint32 TexturePacket::height() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.height)
       return height_;
     }
     inline void TexturePacket::set_height(::google::protobuf::uint32 value) {
       set_has_height();
       height_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.height)
     }
     
     // optional uint32 stride = 4;
    @@ -1749,11 +2067,13 @@ inline void TexturePacket::clear_stride() {
       clear_has_stride();
     }
     inline ::google::protobuf::uint32 TexturePacket::stride() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.stride)
       return stride_;
     }
     inline void TexturePacket::set_stride(::google::protobuf::uint32 value) {
       set_has_stride();
       stride_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.stride)
     }
     
     // optional uint32 name = 5;
    @@ -1771,11 +2091,13 @@ inline void TexturePacket::clear_name() {
       clear_has_name();
     }
     inline ::google::protobuf::uint32 TexturePacket::name() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.name)
       return name_;
     }
     inline void TexturePacket::set_name(::google::protobuf::uint32 value) {
       set_has_name();
       name_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.name)
     }
     
     // optional uint32 target = 6;
    @@ -1793,11 +2115,13 @@ inline void TexturePacket::clear_target() {
       clear_has_target();
     }
     inline ::google::protobuf::uint32 TexturePacket::target() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.target)
       return target_;
     }
     inline void TexturePacket::set_target(::google::protobuf::uint32 value) {
       set_has_target();
       target_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.target)
     }
     
     // optional uint32 dataformat = 7;
    @@ -1815,11 +2139,13 @@ inline void TexturePacket::clear_dataformat() {
       clear_has_dataformat();
     }
     inline ::google::protobuf::uint32 TexturePacket::dataformat() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.dataformat)
       return dataformat_;
     }
     inline void TexturePacket::set_dataformat(::google::protobuf::uint32 value) {
       set_has_dataformat();
       dataformat_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.dataformat)
     }
     
     // optional uint64 glcontext = 8;
    @@ -1837,11 +2163,13 @@ inline void TexturePacket::clear_glcontext() {
       clear_has_glcontext();
     }
     inline ::google::protobuf::uint64 TexturePacket::glcontext() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.glcontext)
       return glcontext_;
     }
     inline void TexturePacket::set_glcontext(::google::protobuf::uint64 value) {
       set_has_glcontext();
       glcontext_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.glcontext)
     }
     
     // optional bytes data = 9;
    @@ -1855,52 +2183,70 @@ inline void TexturePacket::clear_has_data() {
       _has_bits_[0] &= ~0x00000100u;
     }
     inline void TexturePacket::clear_data() {
    -  if (data_ != &::google::protobuf::internal::kEmptyString) {
    +  if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         data_->clear();
       }
       clear_has_data();
     }
     inline const ::std::string& TexturePacket::data() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.data)
       return *data_;
     }
     inline void TexturePacket::set_data(const ::std::string& value) {
       set_has_data();
    -  if (data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         data_ = new ::std::string;
       }
       data_->assign(value);
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.data)
     }
     inline void TexturePacket::set_data(const char* value) {
       set_has_data();
    -  if (data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         data_ = new ::std::string;
       }
       data_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:mozilla.layers.layerscope.TexturePacket.data)
     }
     inline void TexturePacket::set_data(const void* value, size_t size) {
       set_has_data();
    -  if (data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         data_ = new ::std::string;
       }
       data_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:mozilla.layers.layerscope.TexturePacket.data)
     }
     inline ::std::string* TexturePacket::mutable_data() {
       set_has_data();
    -  if (data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         data_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.TexturePacket.data)
       return data_;
     }
     inline ::std::string* TexturePacket::release_data() {
       clear_has_data();
    -  if (data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = data_;
    -    data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void TexturePacket::set_allocated_data(::std::string* data) {
    +  if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete data_;
    +  }
    +  if (data) {
    +    set_has_data();
    +    data_ = data;
    +  } else {
    +    clear_has_data();
    +    data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.TexturePacket.data)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -1921,11 +2267,13 @@ inline void LayersPacket_Layer_Size::clear_w() {
       clear_has_w();
     }
     inline ::google::protobuf::int32 LayersPacket_Layer_Size::w() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Size.w)
       return w_;
     }
     inline void LayersPacket_Layer_Size::set_w(::google::protobuf::int32 value) {
       set_has_w();
       w_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Size.w)
     }
     
     // optional int32 h = 2;
    @@ -1943,11 +2291,13 @@ inline void LayersPacket_Layer_Size::clear_h() {
       clear_has_h();
     }
     inline ::google::protobuf::int32 LayersPacket_Layer_Size::h() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Size.h)
       return h_;
     }
     inline void LayersPacket_Layer_Size::set_h(::google::protobuf::int32 value) {
       set_has_h();
       h_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Size.h)
     }
     
     // -------------------------------------------------------------------
    @@ -1969,11 +2319,13 @@ inline void LayersPacket_Layer_Rect::clear_x() {
       clear_has_x();
     }
     inline ::google::protobuf::int32 LayersPacket_Layer_Rect::x() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.x)
       return x_;
     }
     inline void LayersPacket_Layer_Rect::set_x(::google::protobuf::int32 value) {
       set_has_x();
       x_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.x)
     }
     
     // optional int32 y = 2;
    @@ -1991,11 +2343,13 @@ inline void LayersPacket_Layer_Rect::clear_y() {
       clear_has_y();
     }
     inline ::google::protobuf::int32 LayersPacket_Layer_Rect::y() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.y)
       return y_;
     }
     inline void LayersPacket_Layer_Rect::set_y(::google::protobuf::int32 value) {
       set_has_y();
       y_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.y)
     }
     
     // optional int32 w = 3;
    @@ -2013,11 +2367,13 @@ inline void LayersPacket_Layer_Rect::clear_w() {
       clear_has_w();
     }
     inline ::google::protobuf::int32 LayersPacket_Layer_Rect::w() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.w)
       return w_;
     }
     inline void LayersPacket_Layer_Rect::set_w(::google::protobuf::int32 value) {
       set_has_w();
       w_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.w)
     }
     
     // optional int32 h = 4;
    @@ -2035,11 +2391,13 @@ inline void LayersPacket_Layer_Rect::clear_h() {
       clear_has_h();
     }
     inline ::google::protobuf::int32 LayersPacket_Layer_Rect::h() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.h)
       return h_;
     }
     inline void LayersPacket_Layer_Rect::set_h(::google::protobuf::int32 value) {
       set_has_h();
       h_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.h)
     }
     
     // -------------------------------------------------------------------
    @@ -2054,20 +2412,25 @@ inline void LayersPacket_Layer_Region::clear_r() {
       r_.Clear();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& LayersPacket_Layer_Region::r(int index) const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Region.r)
       return r_.Get(index);
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Region::mutable_r(int index) {
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Region.r)
       return r_.Mutable(index);
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Region::add_r() {
    +  // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.LayersPacket.Layer.Region.r)
       return r_.Add();
     }
     inline const ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect >&
     LayersPacket_Layer_Region::r() const {
    +  // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.LayersPacket.Layer.Region.r)
       return r_;
     }
     inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect >*
     LayersPacket_Layer_Region::mutable_r() {
    +  // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.LayersPacket.Layer.Region.r)
       return &r_;
     }
     
    @@ -2090,11 +2453,13 @@ inline void LayersPacket_Layer_Matrix::clear_is2d() {
       clear_has_is2d();
     }
     inline bool LayersPacket_Layer_Matrix::is2d() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.is2D)
       return is2d_;
     }
     inline void LayersPacket_Layer_Matrix::set_is2d(bool value) {
       set_has_is2d();
       is2d_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.is2D)
     }
     
     // optional bool isId = 2;
    @@ -2112,11 +2477,13 @@ inline void LayersPacket_Layer_Matrix::clear_isid() {
       clear_has_isid();
     }
     inline bool LayersPacket_Layer_Matrix::isid() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.isId)
       return isid_;
     }
     inline void LayersPacket_Layer_Matrix::set_isid(bool value) {
       set_has_isid();
       isid_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.isId)
     }
     
     // repeated float m = 3;
    @@ -2127,20 +2494,25 @@ inline void LayersPacket_Layer_Matrix::clear_m() {
       m_.Clear();
     }
     inline float LayersPacket_Layer_Matrix::m(int index) const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m)
       return m_.Get(index);
     }
     inline void LayersPacket_Layer_Matrix::set_m(int index, float value) {
       m_.Set(index, value);
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m)
     }
     inline void LayersPacket_Layer_Matrix::add_m(float value) {
       m_.Add(value);
    +  // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m)
     }
     inline const ::google::protobuf::RepeatedField< float >&
     LayersPacket_Layer_Matrix::m() const {
    +  // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m)
       return m_;
     }
     inline ::google::protobuf::RepeatedField< float >*
     LayersPacket_Layer_Matrix::mutable_m() {
    +  // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m)
       return &m_;
     }
     
    @@ -2163,11 +2535,17 @@ inline void LayersPacket_Layer_Shadow::clear_clip() {
       clear_has_clip();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& LayersPacket_Layer_Shadow::clip() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.clip)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return clip_ != NULL ? *clip_ : *default_instance().clip_;
    +#else
       return clip_ != NULL ? *clip_ : *default_instance_->clip_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Shadow::mutable_clip() {
       set_has_clip();
       if (clip_ == NULL) clip_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Rect;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.clip)
       return clip_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Shadow::release_clip() {
    @@ -2176,6 +2554,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Laye
       clip_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer_Shadow::set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip) {
    +  delete clip_;
    +  clip_ = clip;
    +  if (clip) {
    +    set_has_clip();
    +  } else {
    +    clear_has_clip();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.clip)
    +}
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2;
     inline bool LayersPacket_Layer_Shadow::has_transform() const {
    @@ -2192,11 +2580,17 @@ inline void LayersPacket_Layer_Shadow::clear_transform() {
       clear_has_transform();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& LayersPacket_Layer_Shadow::transform() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.transform)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return transform_ != NULL ? *transform_ : *default_instance().transform_;
    +#else
       return transform_ != NULL ? *transform_ : *default_instance_->transform_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer_Shadow::mutable_transform() {
       set_has_transform();
       if (transform_ == NULL) transform_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.transform)
       return transform_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer_Shadow::release_transform() {
    @@ -2205,6 +2599,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_La
       transform_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer_Shadow::set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform) {
    +  delete transform_;
    +  transform_ = transform;
    +  if (transform) {
    +    set_has_transform();
    +  } else {
    +    clear_has_transform();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.transform)
    +}
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3;
     inline bool LayersPacket_Layer_Shadow::has_vregion() const {
    @@ -2221,11 +2625,17 @@ inline void LayersPacket_Layer_Shadow::clear_vregion() {
       clear_has_vregion();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer_Shadow::vregion() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.vRegion)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return vregion_ != NULL ? *vregion_ : *default_instance().vregion_;
    +#else
       return vregion_ != NULL ? *vregion_ : *default_instance_->vregion_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer_Shadow::mutable_vregion() {
       set_has_vregion();
       if (vregion_ == NULL) vregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.vRegion)
       return vregion_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer_Shadow::release_vregion() {
    @@ -2234,6 +2644,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_La
       vregion_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer_Shadow::set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion) {
    +  delete vregion_;
    +  vregion_ = vregion;
    +  if (vregion) {
    +    set_has_vregion();
    +  } else {
    +    clear_has_vregion();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.vRegion)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -2254,12 +2674,14 @@ inline void LayersPacket_Layer::clear_type() {
       clear_has_type();
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType LayersPacket_Layer::type() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.type)
       return static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType >(type_);
     }
     inline void LayersPacket_Layer::set_type(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType value) {
    -  GOOGLE_DCHECK(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType_IsValid(value));
    +  assert(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType_IsValid(value));
       set_has_type();
       type_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.type)
     }
     
     // required uint64 ptr = 2;
    @@ -2277,11 +2699,13 @@ inline void LayersPacket_Layer::clear_ptr() {
       clear_has_ptr();
     }
     inline ::google::protobuf::uint64 LayersPacket_Layer::ptr() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.ptr)
       return ptr_;
     }
     inline void LayersPacket_Layer::set_ptr(::google::protobuf::uint64 value) {
       set_has_ptr();
       ptr_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.ptr)
     }
     
     // required uint64 parentPtr = 3;
    @@ -2299,11 +2723,13 @@ inline void LayersPacket_Layer::clear_parentptr() {
       clear_has_parentptr();
     }
     inline ::google::protobuf::uint64 LayersPacket_Layer::parentptr() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.parentPtr)
       return parentptr_;
     }
     inline void LayersPacket_Layer::set_parentptr(::google::protobuf::uint64 value) {
       set_has_parentptr();
       parentptr_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.parentPtr)
     }
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10;
    @@ -2321,11 +2747,17 @@ inline void LayersPacket_Layer::clear_clip() {
       clear_has_clip();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& LayersPacket_Layer::clip() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.clip)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return clip_ != NULL ? *clip_ : *default_instance().clip_;
    +#else
       return clip_ != NULL ? *clip_ : *default_instance_->clip_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer::mutable_clip() {
       set_has_clip();
       if (clip_ == NULL) clip_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Rect;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.clip)
       return clip_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer::release_clip() {
    @@ -2334,6 +2766,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Laye
       clip_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer::set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip) {
    +  delete clip_;
    +  clip_ = clip;
    +  if (clip) {
    +    set_has_clip();
    +  } else {
    +    clear_has_clip();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.clip)
    +}
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11;
     inline bool LayersPacket_Layer::has_transform() const {
    @@ -2350,11 +2792,17 @@ inline void LayersPacket_Layer::clear_transform() {
       clear_has_transform();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& LayersPacket_Layer::transform() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.transform)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return transform_ != NULL ? *transform_ : *default_instance().transform_;
    +#else
       return transform_ != NULL ? *transform_ : *default_instance_->transform_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer::mutable_transform() {
       set_has_transform();
       if (transform_ == NULL) transform_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.transform)
       return transform_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer::release_transform() {
    @@ -2363,6 +2811,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_La
       transform_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer::set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform) {
    +  delete transform_;
    +  transform_ = transform;
    +  if (transform) {
    +    set_has_transform();
    +  } else {
    +    clear_has_transform();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.transform)
    +}
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12;
     inline bool LayersPacket_Layer::has_vregion() const {
    @@ -2379,11 +2837,17 @@ inline void LayersPacket_Layer::clear_vregion() {
       clear_has_vregion();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::vregion() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.vRegion)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return vregion_ != NULL ? *vregion_ : *default_instance().vregion_;
    +#else
       return vregion_ != NULL ? *vregion_ : *default_instance_->vregion_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_vregion() {
       set_has_vregion();
       if (vregion_ == NULL) vregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.vRegion)
       return vregion_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_vregion() {
    @@ -2392,6 +2856,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_La
       vregion_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer::set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion) {
    +  delete vregion_;
    +  vregion_ = vregion;
    +  if (vregion) {
    +    set_has_vregion();
    +  } else {
    +    clear_has_vregion();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.vRegion)
    +}
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13;
     inline bool LayersPacket_Layer::has_shadow() const {
    @@ -2408,11 +2882,17 @@ inline void LayersPacket_Layer::clear_shadow() {
       clear_has_shadow();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow& LayersPacket_Layer::shadow() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.shadow)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return shadow_ != NULL ? *shadow_ : *default_instance().shadow_;
    +#else
       return shadow_ != NULL ? *shadow_ : *default_instance_->shadow_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* LayersPacket_Layer::mutable_shadow() {
       set_has_shadow();
       if (shadow_ == NULL) shadow_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.shadow)
       return shadow_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* LayersPacket_Layer::release_shadow() {
    @@ -2421,6 +2901,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* LayersPacket_La
       shadow_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer::set_allocated_shadow(::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* shadow) {
    +  delete shadow_;
    +  shadow_ = shadow;
    +  if (shadow) {
    +    set_has_shadow();
    +  } else {
    +    clear_has_shadow();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.shadow)
    +}
     
     // optional float opacity = 14;
     inline bool LayersPacket_Layer::has_opacity() const {
    @@ -2437,11 +2927,13 @@ inline void LayersPacket_Layer::clear_opacity() {
       clear_has_opacity();
     }
     inline float LayersPacket_Layer::opacity() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.opacity)
       return opacity_;
     }
     inline void LayersPacket_Layer::set_opacity(float value) {
       set_has_opacity();
       opacity_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.opacity)
     }
     
     // optional bool cOpaque = 15;
    @@ -2459,11 +2951,13 @@ inline void LayersPacket_Layer::clear_copaque() {
       clear_has_copaque();
     }
     inline bool LayersPacket_Layer::copaque() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.cOpaque)
       return copaque_;
     }
     inline void LayersPacket_Layer::set_copaque(bool value) {
       set_has_copaque();
       copaque_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.cOpaque)
     }
     
     // optional bool cAlpha = 16;
    @@ -2481,11 +2975,13 @@ inline void LayersPacket_Layer::clear_calpha() {
       clear_has_calpha();
     }
     inline bool LayersPacket_Layer::calpha() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.cAlpha)
       return calpha_;
     }
     inline void LayersPacket_Layer::set_calpha(bool value) {
       set_has_calpha();
       calpha_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.cAlpha)
     }
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17;
    @@ -2503,12 +2999,14 @@ inline void LayersPacket_Layer::clear_direct() {
       clear_has_direct();
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect LayersPacket_Layer::direct() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.direct)
       return static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect >(direct_);
     }
     inline void LayersPacket_Layer::set_direct(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect value) {
    -  GOOGLE_DCHECK(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect_IsValid(value));
    +  assert(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect_IsValid(value));
       set_has_direct();
       direct_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.direct)
     }
     
     // optional uint64 barID = 18;
    @@ -2526,11 +3024,13 @@ inline void LayersPacket_Layer::clear_barid() {
       clear_has_barid();
     }
     inline ::google::protobuf::uint64 LayersPacket_Layer::barid() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.barID)
       return barid_;
     }
     inline void LayersPacket_Layer::set_barid(::google::protobuf::uint64 value) {
       set_has_barid();
       barid_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.barID)
     }
     
     // optional uint64 mask = 19;
    @@ -2548,11 +3048,13 @@ inline void LayersPacket_Layer::clear_mask() {
       clear_has_mask();
     }
     inline ::google::protobuf::uint64 LayersPacket_Layer::mask() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.mask)
       return mask_;
     }
     inline void LayersPacket_Layer::set_mask(::google::protobuf::uint64 value) {
       set_has_mask();
       mask_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.mask)
     }
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
    @@ -2570,11 +3072,17 @@ inline void LayersPacket_Layer::clear_valid() {
       clear_has_valid();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::valid() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.valid)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return valid_ != NULL ? *valid_ : *default_instance().valid_;
    +#else
       return valid_ != NULL ? *valid_ : *default_instance_->valid_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_valid() {
       set_has_valid();
       if (valid_ == NULL) valid_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.valid)
       return valid_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_valid() {
    @@ -2583,6 +3091,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_La
       valid_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer::set_allocated_valid(::mozilla::layers::layerscope::LayersPacket_Layer_Region* valid) {
    +  delete valid_;
    +  valid_ = valid;
    +  if (valid) {
    +    set_has_valid();
    +  } else {
    +    clear_has_valid();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.valid)
    +}
     
     // optional uint32 color = 101;
     inline bool LayersPacket_Layer::has_color() const {
    @@ -2599,11 +3117,13 @@ inline void LayersPacket_Layer::clear_color() {
       clear_has_color();
     }
     inline ::google::protobuf::uint32 LayersPacket_Layer::color() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.color)
       return color_;
     }
     inline void LayersPacket_Layer::set_color(::google::protobuf::uint32 value) {
       set_has_color();
       color_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.color)
     }
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102;
    @@ -2621,12 +3141,14 @@ inline void LayersPacket_Layer::clear_filter() {
       clear_has_filter();
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Filter LayersPacket_Layer::filter() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.filter)
       return static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Filter >(filter_);
     }
     inline void LayersPacket_Layer::set_filter(::mozilla::layers::layerscope::LayersPacket_Layer_Filter value) {
    -  GOOGLE_DCHECK(::mozilla::layers::layerscope::LayersPacket_Layer_Filter_IsValid(value));
    +  assert(::mozilla::layers::layerscope::LayersPacket_Layer_Filter_IsValid(value));
       set_has_filter();
       filter_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.filter)
     }
     
     // optional uint64 refID = 103;
    @@ -2644,11 +3166,13 @@ inline void LayersPacket_Layer::clear_refid() {
       clear_has_refid();
     }
     inline ::google::protobuf::uint64 LayersPacket_Layer::refid() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.refID)
       return refid_;
     }
     inline void LayersPacket_Layer::set_refid(::google::protobuf::uint64 value) {
       set_has_refid();
       refid_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.refID)
     }
     
     // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104;
    @@ -2666,11 +3190,17 @@ inline void LayersPacket_Layer::clear_size() {
       clear_has_size();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Size& LayersPacket_Layer::size() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.size)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return size_ != NULL ? *size_ : *default_instance().size_;
    +#else
       return size_ != NULL ? *size_ : *default_instance_->size_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* LayersPacket_Layer::mutable_size() {
       set_has_size();
       if (size_ == NULL) size_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Size;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.size)
       return size_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* LayersPacket_Layer::release_size() {
    @@ -2679,6 +3209,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* LayersPacket_Laye
       size_ = NULL;
       return temp;
     }
    +inline void LayersPacket_Layer::set_allocated_size(::mozilla::layers::layerscope::LayersPacket_Layer_Size* size) {
    +  delete size_;
    +  size_ = size;
    +  if (size) {
    +    set_has_size();
    +  } else {
    +    clear_has_size();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.size)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -2692,20 +3232,25 @@ inline void LayersPacket::clear_layer() {
       layer_.Clear();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket_Layer& LayersPacket::layer(int index) const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.layer)
       return layer_.Get(index);
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer* LayersPacket::mutable_layer(int index) {
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.layer)
       return layer_.Mutable(index);
     }
     inline ::mozilla::layers::layerscope::LayersPacket_Layer* LayersPacket::add_layer() {
    +  // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.LayersPacket.layer)
       return layer_.Add();
     }
     inline const ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer >&
     LayersPacket::layer() const {
    +  // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.LayersPacket.layer)
       return layer_;
     }
     inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer >*
     LayersPacket::mutable_layer() {
    +  // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.LayersPacket.layer)
       return &layer_;
     }
     
    @@ -2728,11 +3273,13 @@ inline void MetaPacket::clear_composedbyhwc() {
       clear_has_composedbyhwc();
     }
     inline bool MetaPacket::composedbyhwc() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.MetaPacket.composedByHwc)
       return composedbyhwc_;
     }
     inline void MetaPacket::set_composedbyhwc(bool value) {
       set_has_composedbyhwc();
       composedbyhwc_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.MetaPacket.composedByHwc)
     }
     
     // -------------------------------------------------------------------
    @@ -2754,12 +3301,14 @@ inline void Packet::clear_type() {
       clear_has_type();
     }
     inline ::mozilla::layers::layerscope::Packet_DataType Packet::type() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.type)
       return static_cast< ::mozilla::layers::layerscope::Packet_DataType >(type_);
     }
     inline void Packet::set_type(::mozilla::layers::layerscope::Packet_DataType value) {
    -  GOOGLE_DCHECK(::mozilla::layers::layerscope::Packet_DataType_IsValid(value));
    +  assert(::mozilla::layers::layerscope::Packet_DataType_IsValid(value));
       set_has_type();
       type_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.Packet.type)
     }
     
     // optional .mozilla.layers.layerscope.FramePacket frame = 2;
    @@ -2777,11 +3326,17 @@ inline void Packet::clear_frame() {
       clear_has_frame();
     }
     inline const ::mozilla::layers::layerscope::FramePacket& Packet::frame() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.frame)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return frame_ != NULL ? *frame_ : *default_instance().frame_;
    +#else
       return frame_ != NULL ? *frame_ : *default_instance_->frame_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::FramePacket* Packet::mutable_frame() {
       set_has_frame();
       if (frame_ == NULL) frame_ = new ::mozilla::layers::layerscope::FramePacket;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.frame)
       return frame_;
     }
     inline ::mozilla::layers::layerscope::FramePacket* Packet::release_frame() {
    @@ -2790,6 +3345,16 @@ inline ::mozilla::layers::layerscope::FramePacket* Packet::release_frame() {
       frame_ = NULL;
       return temp;
     }
    +inline void Packet::set_allocated_frame(::mozilla::layers::layerscope::FramePacket* frame) {
    +  delete frame_;
    +  frame_ = frame;
    +  if (frame) {
    +    set_has_frame();
    +  } else {
    +    clear_has_frame();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.frame)
    +}
     
     // optional .mozilla.layers.layerscope.ColorPacket color = 3;
     inline bool Packet::has_color() const {
    @@ -2806,11 +3371,17 @@ inline void Packet::clear_color() {
       clear_has_color();
     }
     inline const ::mozilla::layers::layerscope::ColorPacket& Packet::color() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.color)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return color_ != NULL ? *color_ : *default_instance().color_;
    +#else
       return color_ != NULL ? *color_ : *default_instance_->color_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::ColorPacket* Packet::mutable_color() {
       set_has_color();
       if (color_ == NULL) color_ = new ::mozilla::layers::layerscope::ColorPacket;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.color)
       return color_;
     }
     inline ::mozilla::layers::layerscope::ColorPacket* Packet::release_color() {
    @@ -2819,6 +3390,16 @@ inline ::mozilla::layers::layerscope::ColorPacket* Packet::release_color() {
       color_ = NULL;
       return temp;
     }
    +inline void Packet::set_allocated_color(::mozilla::layers::layerscope::ColorPacket* color) {
    +  delete color_;
    +  color_ = color;
    +  if (color) {
    +    set_has_color();
    +  } else {
    +    clear_has_color();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.color)
    +}
     
     // optional .mozilla.layers.layerscope.TexturePacket texture = 4;
     inline bool Packet::has_texture() const {
    @@ -2835,11 +3416,17 @@ inline void Packet::clear_texture() {
       clear_has_texture();
     }
     inline const ::mozilla::layers::layerscope::TexturePacket& Packet::texture() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.texture)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return texture_ != NULL ? *texture_ : *default_instance().texture_;
    +#else
       return texture_ != NULL ? *texture_ : *default_instance_->texture_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::TexturePacket* Packet::mutable_texture() {
       set_has_texture();
       if (texture_ == NULL) texture_ = new ::mozilla::layers::layerscope::TexturePacket;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.texture)
       return texture_;
     }
     inline ::mozilla::layers::layerscope::TexturePacket* Packet::release_texture() {
    @@ -2848,6 +3435,16 @@ inline ::mozilla::layers::layerscope::TexturePacket* Packet::release_texture() {
       texture_ = NULL;
       return temp;
     }
    +inline void Packet::set_allocated_texture(::mozilla::layers::layerscope::TexturePacket* texture) {
    +  delete texture_;
    +  texture_ = texture;
    +  if (texture) {
    +    set_has_texture();
    +  } else {
    +    clear_has_texture();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.texture)
    +}
     
     // optional .mozilla.layers.layerscope.LayersPacket layers = 5;
     inline bool Packet::has_layers() const {
    @@ -2864,11 +3461,17 @@ inline void Packet::clear_layers() {
       clear_has_layers();
     }
     inline const ::mozilla::layers::layerscope::LayersPacket& Packet::layers() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.layers)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return layers_ != NULL ? *layers_ : *default_instance().layers_;
    +#else
       return layers_ != NULL ? *layers_ : *default_instance_->layers_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::LayersPacket* Packet::mutable_layers() {
       set_has_layers();
       if (layers_ == NULL) layers_ = new ::mozilla::layers::layerscope::LayersPacket;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.layers)
       return layers_;
     }
     inline ::mozilla::layers::layerscope::LayersPacket* Packet::release_layers() {
    @@ -2877,6 +3480,16 @@ inline ::mozilla::layers::layerscope::LayersPacket* Packet::release_layers() {
       layers_ = NULL;
       return temp;
     }
    +inline void Packet::set_allocated_layers(::mozilla::layers::layerscope::LayersPacket* layers) {
    +  delete layers_;
    +  layers_ = layers;
    +  if (layers) {
    +    set_has_layers();
    +  } else {
    +    clear_has_layers();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.layers)
    +}
     
     // optional .mozilla.layers.layerscope.MetaPacket meta = 6;
     inline bool Packet::has_meta() const {
    @@ -2893,11 +3506,17 @@ inline void Packet::clear_meta() {
       clear_has_meta();
     }
     inline const ::mozilla::layers::layerscope::MetaPacket& Packet::meta() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.meta)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return meta_ != NULL ? *meta_ : *default_instance().meta_;
    +#else
       return meta_ != NULL ? *meta_ : *default_instance_->meta_;
    +#endif
     }
     inline ::mozilla::layers::layerscope::MetaPacket* Packet::mutable_meta() {
       set_has_meta();
       if (meta_ == NULL) meta_ = new ::mozilla::layers::layerscope::MetaPacket;
    +  // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.meta)
       return meta_;
     }
     inline ::mozilla::layers::layerscope::MetaPacket* Packet::release_meta() {
    @@ -2906,6 +3525,16 @@ inline ::mozilla::layers::layerscope::MetaPacket* Packet::release_meta() {
       meta_ = NULL;
       return temp;
     }
    +inline void Packet::set_allocated_meta(::mozilla::layers::layerscope::MetaPacket* meta) {
    +  delete meta_;
    +  meta_ = meta;
    +  if (meta) {
    +    set_has_meta();
    +  } else {
    +    clear_has_meta();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.meta)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -2926,12 +3555,14 @@ inline void CommandPacket::clear_type() {
       clear_has_type();
     }
     inline ::mozilla::layers::layerscope::CommandPacket_CmdType CommandPacket::type() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.CommandPacket.type)
       return static_cast< ::mozilla::layers::layerscope::CommandPacket_CmdType >(type_);
     }
     inline void CommandPacket::set_type(::mozilla::layers::layerscope::CommandPacket_CmdType value) {
    -  GOOGLE_DCHECK(::mozilla::layers::layerscope::CommandPacket_CmdType_IsValid(value));
    +  assert(::mozilla::layers::layerscope::CommandPacket_CmdType_IsValid(value));
       set_has_type();
       type_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.CommandPacket.type)
     }
     
     // optional bool value = 2;
    @@ -2949,11 +3580,13 @@ inline void CommandPacket::clear_value() {
       clear_has_value();
     }
     inline bool CommandPacket::value() const {
    +  // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.CommandPacket.value)
       return value_;
     }
     inline void CommandPacket::set_value(bool value) {
       set_has_value();
       value_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.CommandPacket.value)
     }
     
     
    diff --git a/toolkit/components/downloads/csd.pb.cc b/toolkit/components/downloads/csd.pb.cc
    index 99108deecfa0..5896e47688ee 100644
    --- a/toolkit/components/downloads/csd.pb.cc
    +++ b/toolkit/components/downloads/csd.pb.cc
    @@ -1,18 +1,27 @@
     // Generated by the protocol buffer compiler.  DO NOT EDIT!
    +// source: csd.proto
     
     #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
     #include "csd.pb.h"
     
     #include 
     
    +#include 
     #include 
     #include 
     #include 
    +#include 
     // @@protoc_insertion_point(includes)
     
     namespace safe_browsing {
     
     void protobuf_ShutdownFile_csd_2eproto() {
    +  delete ClientPhishingRequest::default_instance_;
    +  delete ClientPhishingRequest_Feature::default_instance_;
    +  delete ClientPhishingResponse::default_instance_;
    +  delete ClientMalwareRequest::default_instance_;
    +  delete ClientMalwareRequest_UrlInfo::default_instance_;
    +  delete ClientMalwareResponse::default_instance_;
       delete ClientDownloadRequest::default_instance_;
       delete ClientDownloadRequest_Digests::default_instance_;
       delete ClientDownloadRequest_Resource::default_instance_;
    @@ -22,16 +31,51 @@ void protobuf_ShutdownFile_csd_2eproto() {
       delete ClientDownloadRequest_PEImageHeaders::default_instance_;
       delete ClientDownloadRequest_PEImageHeaders_DebugData::default_instance_;
       delete ClientDownloadRequest_ImageHeaders::default_instance_;
    +  delete ClientDownloadRequest_ArchivedBinary::default_instance_;
       delete ClientDownloadResponse::default_instance_;
       delete ClientDownloadResponse_MoreInfo::default_instance_;
    +  delete ClientDownloadReport::default_instance_;
    +  delete ClientDownloadReport_UserInformation::default_instance_;
    +  delete ClientUploadResponse::default_instance_;
    +  delete ClientIncidentReport::default_instance_;
    +  delete ClientIncidentReport_IncidentData::default_instance_;
    +  delete ClientIncidentReport_IncidentData_TrackedPreferenceIncident::default_instance_;
    +  delete ClientIncidentReport_IncidentData_BinaryIntegrityIncident::default_instance_;
    +  delete ClientIncidentReport_IncidentData_BlacklistLoadIncident::default_instance_;
    +  delete ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::default_instance_;
    +  delete ClientIncidentReport_IncidentData_ScriptRequestIncident::default_instance_;
    +  delete ClientIncidentReport_DownloadDetails::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData_OS::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData_Machine::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData_Process::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData_Process_Patch::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData_Process_NetworkProvider::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData_Process_Dll::default_instance_;
    +  delete ClientIncidentReport_EnvironmentData_Process_ModuleState::default_instance_;
    +  delete ClientIncidentResponse::default_instance_;
    +  delete ClientIncidentResponse_EnvironmentRequest::default_instance_;
    +  delete DownloadMetadata::default_instance_;
     }
     
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +void protobuf_AddDesc_csd_2eproto_impl() {
    +  GOOGLE_PROTOBUF_VERIFY_VERSION;
    +
    +#else
     void protobuf_AddDesc_csd_2eproto() {
       static bool already_here = false;
       if (already_here) return;
       already_here = true;
       GOOGLE_PROTOBUF_VERIFY_VERSION;
     
    +#endif
    +  ClientPhishingRequest::default_instance_ = new ClientPhishingRequest();
    +  ClientPhishingRequest_Feature::default_instance_ = new ClientPhishingRequest_Feature();
    +  ClientPhishingResponse::default_instance_ = new ClientPhishingResponse();
    +  ClientMalwareRequest::default_instance_ = new ClientMalwareRequest();
    +  ClientMalwareRequest_UrlInfo::default_instance_ = new ClientMalwareRequest_UrlInfo();
    +  ClientMalwareResponse::default_instance_ = new ClientMalwareResponse();
       ClientDownloadRequest::default_instance_ = new ClientDownloadRequest();
       ClientDownloadRequest_Digests::default_instance_ = new ClientDownloadRequest_Digests();
       ClientDownloadRequest_Resource::default_instance_ = new ClientDownloadRequest_Resource();
    @@ -41,8 +85,37 @@ void protobuf_AddDesc_csd_2eproto() {
       ClientDownloadRequest_PEImageHeaders::default_instance_ = new ClientDownloadRequest_PEImageHeaders();
       ClientDownloadRequest_PEImageHeaders_DebugData::default_instance_ = new ClientDownloadRequest_PEImageHeaders_DebugData();
       ClientDownloadRequest_ImageHeaders::default_instance_ = new ClientDownloadRequest_ImageHeaders();
    +  ClientDownloadRequest_ArchivedBinary::default_instance_ = new ClientDownloadRequest_ArchivedBinary();
       ClientDownloadResponse::default_instance_ = new ClientDownloadResponse();
       ClientDownloadResponse_MoreInfo::default_instance_ = new ClientDownloadResponse_MoreInfo();
    +  ClientDownloadReport::default_instance_ = new ClientDownloadReport();
    +  ClientDownloadReport_UserInformation::default_instance_ = new ClientDownloadReport_UserInformation();
    +  ClientUploadResponse::default_instance_ = new ClientUploadResponse();
    +  ClientIncidentReport::default_instance_ = new ClientIncidentReport();
    +  ClientIncidentReport_IncidentData::default_instance_ = new ClientIncidentReport_IncidentData();
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident::default_instance_ = new ClientIncidentReport_IncidentData_TrackedPreferenceIncident();
    +  ClientIncidentReport_IncidentData_BinaryIntegrityIncident::default_instance_ = new ClientIncidentReport_IncidentData_BinaryIntegrityIncident();
    +  ClientIncidentReport_IncidentData_BlacklistLoadIncident::default_instance_ = new ClientIncidentReport_IncidentData_BlacklistLoadIncident();
    +  ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::default_instance_ = new ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident();
    +  ClientIncidentReport_IncidentData_ScriptRequestIncident::default_instance_ = new ClientIncidentReport_IncidentData_ScriptRequestIncident();
    +  ClientIncidentReport_DownloadDetails::default_instance_ = new ClientIncidentReport_DownloadDetails();
    +  ClientIncidentReport_EnvironmentData::default_instance_ = new ClientIncidentReport_EnvironmentData();
    +  ClientIncidentReport_EnvironmentData_OS::default_instance_ = new ClientIncidentReport_EnvironmentData_OS();
    +  ClientIncidentReport_EnvironmentData_Machine::default_instance_ = new ClientIncidentReport_EnvironmentData_Machine();
    +  ClientIncidentReport_EnvironmentData_Process::default_instance_ = new ClientIncidentReport_EnvironmentData_Process();
    +  ClientIncidentReport_EnvironmentData_Process_Patch::default_instance_ = new ClientIncidentReport_EnvironmentData_Process_Patch();
    +  ClientIncidentReport_EnvironmentData_Process_NetworkProvider::default_instance_ = new ClientIncidentReport_EnvironmentData_Process_NetworkProvider();
    +  ClientIncidentReport_EnvironmentData_Process_Dll::default_instance_ = new ClientIncidentReport_EnvironmentData_Process_Dll();
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState::default_instance_ = new ClientIncidentReport_EnvironmentData_Process_ModuleState();
    +  ClientIncidentResponse::default_instance_ = new ClientIncidentResponse();
    +  ClientIncidentResponse_EnvironmentRequest::default_instance_ = new ClientIncidentResponse_EnvironmentRequest();
    +  DownloadMetadata::default_instance_ = new DownloadMetadata();
    +  ClientPhishingRequest::default_instance_->InitAsDefaultInstance();
    +  ClientPhishingRequest_Feature::default_instance_->InitAsDefaultInstance();
    +  ClientPhishingResponse::default_instance_->InitAsDefaultInstance();
    +  ClientMalwareRequest::default_instance_->InitAsDefaultInstance();
    +  ClientMalwareRequest_UrlInfo::default_instance_->InitAsDefaultInstance();
    +  ClientMalwareResponse::default_instance_->InitAsDefaultInstance();
       ClientDownloadRequest::default_instance_->InitAsDefaultInstance();
       ClientDownloadRequest_Digests::default_instance_->InitAsDefaultInstance();
       ClientDownloadRequest_Resource::default_instance_->InitAsDefaultInstance();
    @@ -52,17 +125,1911 @@ void protobuf_AddDesc_csd_2eproto() {
       ClientDownloadRequest_PEImageHeaders::default_instance_->InitAsDefaultInstance();
       ClientDownloadRequest_PEImageHeaders_DebugData::default_instance_->InitAsDefaultInstance();
       ClientDownloadRequest_ImageHeaders::default_instance_->InitAsDefaultInstance();
    +  ClientDownloadRequest_ArchivedBinary::default_instance_->InitAsDefaultInstance();
       ClientDownloadResponse::default_instance_->InitAsDefaultInstance();
       ClientDownloadResponse_MoreInfo::default_instance_->InitAsDefaultInstance();
    +  ClientDownloadReport::default_instance_->InitAsDefaultInstance();
    +  ClientDownloadReport_UserInformation::default_instance_->InitAsDefaultInstance();
    +  ClientUploadResponse::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_IncidentData::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_IncidentData_BinaryIntegrityIncident::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_IncidentData_BlacklistLoadIncident::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_IncidentData_ScriptRequestIncident::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_DownloadDetails::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData_OS::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData_Machine::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData_Process::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData_Process_Patch::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData_Process_NetworkProvider::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData_Process_Dll::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentResponse::default_instance_->InitAsDefaultInstance();
    +  ClientIncidentResponse_EnvironmentRequest::default_instance_->InitAsDefaultInstance();
    +  DownloadMetadata::default_instance_->InitAsDefaultInstance();
       ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_csd_2eproto);
     }
     
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AddDesc_csd_2eproto_once_);
    +void protobuf_AddDesc_csd_2eproto() {
    +  ::google::protobuf::GoogleOnceInit(&protobuf_AddDesc_csd_2eproto_once_,
    +                 &protobuf_AddDesc_csd_2eproto_impl);
    +}
    +#else
     // Force AddDescriptors() to be called at static initialization time.
     struct StaticDescriptorInitializer_csd_2eproto {
       StaticDescriptorInitializer_csd_2eproto() {
         protobuf_AddDesc_csd_2eproto();
       }
     } static_descriptor_initializer_csd_2eproto_;
    +#endif
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int ClientPhishingRequest_Feature::kNameFieldNumber;
    +const int ClientPhishingRequest_Feature::kValueFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientPhishingRequest_Feature::ClientPhishingRequest_Feature()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientPhishingRequest.Feature)
    +}
    +
    +void ClientPhishingRequest_Feature::InitAsDefaultInstance() {
    +}
    +
    +ClientPhishingRequest_Feature::ClientPhishingRequest_Feature(const ClientPhishingRequest_Feature& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientPhishingRequest.Feature)
    +}
    +
    +void ClientPhishingRequest_Feature::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  value_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientPhishingRequest_Feature::~ClientPhishingRequest_Feature() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientPhishingRequest.Feature)
    +  SharedDtor();
    +}
    +
    +void ClientPhishingRequest_Feature::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientPhishingRequest_Feature::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientPhishingRequest_Feature& ClientPhishingRequest_Feature::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientPhishingRequest_Feature* ClientPhishingRequest_Feature::default_instance_ = NULL;
    +
    +ClientPhishingRequest_Feature* ClientPhishingRequest_Feature::New() const {
    +  return new ClientPhishingRequest_Feature;
    +}
    +
    +void ClientPhishingRequest_Feature::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    value_ = 0;
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientPhishingRequest_Feature::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientPhishingRequest.Feature)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // required string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(17)) goto parse_value;
    +        break;
    +      }
    +
    +      // required double value = 2;
    +      case 2: {
    +        if (tag == 17) {
    +         parse_value:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
    +                 input, &value_)));
    +          set_has_value();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientPhishingRequest.Feature)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientPhishingRequest.Feature)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientPhishingRequest_Feature::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientPhishingRequest.Feature)
    +  // required string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // required double value = 2;
    +  if (has_value()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->value(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientPhishingRequest.Feature)
    +}
    +
    +int ClientPhishingRequest_Feature::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // required string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // required double value = 2;
    +    if (has_value()) {
    +      total_size += 1 + 8;
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientPhishingRequest_Feature::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientPhishingRequest_Feature::MergeFrom(const ClientPhishingRequest_Feature& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_value()) {
    +      set_value(from.value());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientPhishingRequest_Feature::CopyFrom(const ClientPhishingRequest_Feature& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientPhishingRequest_Feature::IsInitialized() const {
    +  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
    +
    +  return true;
    +}
    +
    +void ClientPhishingRequest_Feature::Swap(ClientPhishingRequest_Feature* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    std::swap(value_, other->value_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientPhishingRequest_Feature::GetTypeName() const {
    +  return "safe_browsing.ClientPhishingRequest.Feature";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientPhishingRequest::kUrlFieldNumber;
    +const int ClientPhishingRequest::kOBSOLETEHashPrefixFieldNumber;
    +const int ClientPhishingRequest::kClientScoreFieldNumber;
    +const int ClientPhishingRequest::kIsPhishingFieldNumber;
    +const int ClientPhishingRequest::kFeatureMapFieldNumber;
    +const int ClientPhishingRequest::kModelVersionFieldNumber;
    +const int ClientPhishingRequest::kNonModelFeatureMapFieldNumber;
    +const int ClientPhishingRequest::kOBSOLETEReferrerUrlFieldNumber;
    +const int ClientPhishingRequest::kShingleHashesFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientPhishingRequest::ClientPhishingRequest()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientPhishingRequest)
    +}
    +
    +void ClientPhishingRequest::InitAsDefaultInstance() {
    +}
    +
    +ClientPhishingRequest::ClientPhishingRequest(const ClientPhishingRequest& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientPhishingRequest)
    +}
    +
    +void ClientPhishingRequest::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  obsolete_hash_prefix_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  client_score_ = 0;
    +  is_phishing_ = false;
    +  model_version_ = 0;
    +  obsolete_referrer_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientPhishingRequest::~ClientPhishingRequest() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientPhishingRequest)
    +  SharedDtor();
    +}
    +
    +void ClientPhishingRequest::SharedDtor() {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (obsolete_hash_prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete obsolete_hash_prefix_;
    +  }
    +  if (obsolete_referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete obsolete_referrer_url_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientPhishingRequest::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientPhishingRequest& ClientPhishingRequest::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientPhishingRequest* ClientPhishingRequest::default_instance_ = NULL;
    +
    +ClientPhishingRequest* ClientPhishingRequest::New() const {
    +  return new ClientPhishingRequest;
    +}
    +
    +void ClientPhishingRequest::Clear() {
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 175) {
    +    ZR_(client_score_, is_phishing_);
    +    if (has_url()) {
    +      if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        url_->clear();
    +      }
    +    }
    +    if (has_obsolete_hash_prefix()) {
    +      if (obsolete_hash_prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        obsolete_hash_prefix_->clear();
    +      }
    +    }
    +    model_version_ = 0;
    +    if (has_obsolete_referrer_url()) {
    +      if (obsolete_referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        obsolete_referrer_url_->clear();
    +      }
    +    }
    +  }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  feature_map_.Clear();
    +  non_model_feature_map_.Clear();
    +  shingle_hashes_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientPhishingRequest::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientPhishingRequest)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string url = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_url()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(21)) goto parse_client_score;
    +        break;
    +      }
    +
    +      // required float client_score = 2;
    +      case 2: {
    +        if (tag == 21) {
    +         parse_client_score:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
    +                 input, &client_score_)));
    +          set_has_client_score();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_is_phishing;
    +        break;
    +      }
    +
    +      // optional bool is_phishing = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_is_phishing:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &is_phishing_)));
    +          set_has_is_phishing();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(42)) goto parse_feature_map;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientPhishingRequest.Feature feature_map = 5;
    +      case 5: {
    +        if (tag == 42) {
    +         parse_feature_map:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_feature_map()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(42)) goto parse_feature_map;
    +        if (input->ExpectTag(48)) goto parse_model_version;
    +        break;
    +      }
    +
    +      // optional int32 model_version = 6;
    +      case 6: {
    +        if (tag == 48) {
    +         parse_model_version:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &model_version_)));
    +          set_has_model_version();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(66)) goto parse_non_model_feature_map;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientPhishingRequest.Feature non_model_feature_map = 8;
    +      case 8: {
    +        if (tag == 66) {
    +         parse_non_model_feature_map:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_non_model_feature_map()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(66)) goto parse_non_model_feature_map;
    +        if (input->ExpectTag(74)) goto parse_OBSOLETE_referrer_url;
    +        break;
    +      }
    +
    +      // optional string OBSOLETE_referrer_url = 9;
    +      case 9: {
    +        if (tag == 74) {
    +         parse_OBSOLETE_referrer_url:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_obsolete_referrer_url()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(82)) goto parse_OBSOLETE_hash_prefix;
    +        break;
    +      }
    +
    +      // optional bytes OBSOLETE_hash_prefix = 10;
    +      case 10: {
    +        if (tag == 82) {
    +         parse_OBSOLETE_hash_prefix:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
    +                input, this->mutable_obsolete_hash_prefix()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(98)) goto parse_shingle_hashes;
    +        break;
    +      }
    +
    +      // repeated uint32 shingle_hashes = 12 [packed = true];
    +      case 12: {
    +        if (tag == 98) {
    +         parse_shingle_hashes:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
    +                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
    +                 input, this->mutable_shingle_hashes())));
    +        } else if (tag == 96) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
    +                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
    +                 1, 98, input, this->mutable_shingle_hashes())));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientPhishingRequest)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientPhishingRequest)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientPhishingRequest::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientPhishingRequest)
    +  // optional string url = 1;
    +  if (has_url()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->url(), output);
    +  }
    +
    +  // required float client_score = 2;
    +  if (has_client_score()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->client_score(), output);
    +  }
    +
    +  // optional bool is_phishing = 4;
    +  if (has_is_phishing()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->is_phishing(), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientPhishingRequest.Feature feature_map = 5;
    +  for (int i = 0; i < this->feature_map_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      5, this->feature_map(i), output);
    +  }
    +
    +  // optional int32 model_version = 6;
    +  if (has_model_version()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(6, this->model_version(), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientPhishingRequest.Feature non_model_feature_map = 8;
    +  for (int i = 0; i < this->non_model_feature_map_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      8, this->non_model_feature_map(i), output);
    +  }
    +
    +  // optional string OBSOLETE_referrer_url = 9;
    +  if (has_obsolete_referrer_url()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      9, this->obsolete_referrer_url(), output);
    +  }
    +
    +  // optional bytes OBSOLETE_hash_prefix = 10;
    +  if (has_obsolete_hash_prefix()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
    +      10, this->obsolete_hash_prefix(), output);
    +  }
    +
    +  // repeated uint32 shingle_hashes = 12 [packed = true];
    +  if (this->shingle_hashes_size() > 0) {
    +    ::google::protobuf::internal::WireFormatLite::WriteTag(12, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    +    output->WriteVarint32(_shingle_hashes_cached_byte_size_);
    +  }
    +  for (int i = 0; i < this->shingle_hashes_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
    +      this->shingle_hashes(i), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientPhishingRequest)
    +}
    +
    +int ClientPhishingRequest::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string url = 1;
    +    if (has_url()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->url());
    +    }
    +
    +    // optional bytes OBSOLETE_hash_prefix = 10;
    +    if (has_obsolete_hash_prefix()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::BytesSize(
    +          this->obsolete_hash_prefix());
    +    }
    +
    +    // required float client_score = 2;
    +    if (has_client_score()) {
    +      total_size += 1 + 4;
    +    }
    +
    +    // optional bool is_phishing = 4;
    +    if (has_is_phishing()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional int32 model_version = 6;
    +    if (has_model_version()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->model_version());
    +    }
    +
    +    // optional string OBSOLETE_referrer_url = 9;
    +    if (has_obsolete_referrer_url()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->obsolete_referrer_url());
    +    }
    +
    +  }
    +  // repeated .safe_browsing.ClientPhishingRequest.Feature feature_map = 5;
    +  total_size += 1 * this->feature_map_size();
    +  for (int i = 0; i < this->feature_map_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->feature_map(i));
    +  }
    +
    +  // repeated .safe_browsing.ClientPhishingRequest.Feature non_model_feature_map = 8;
    +  total_size += 1 * this->non_model_feature_map_size();
    +  for (int i = 0; i < this->non_model_feature_map_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->non_model_feature_map(i));
    +  }
    +
    +  // repeated uint32 shingle_hashes = 12 [packed = true];
    +  {
    +    int data_size = 0;
    +    for (int i = 0; i < this->shingle_hashes_size(); i++) {
    +      data_size += ::google::protobuf::internal::WireFormatLite::
    +        UInt32Size(this->shingle_hashes(i));
    +    }
    +    if (data_size > 0) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    +    }
    +    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +    _shingle_hashes_cached_byte_size_ = data_size;
    +    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +    total_size += data_size;
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientPhishingRequest::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientPhishingRequest::MergeFrom(const ClientPhishingRequest& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  feature_map_.MergeFrom(from.feature_map_);
    +  non_model_feature_map_.MergeFrom(from.non_model_feature_map_);
    +  shingle_hashes_.MergeFrom(from.shingle_hashes_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_url()) {
    +      set_url(from.url());
    +    }
    +    if (from.has_obsolete_hash_prefix()) {
    +      set_obsolete_hash_prefix(from.obsolete_hash_prefix());
    +    }
    +    if (from.has_client_score()) {
    +      set_client_score(from.client_score());
    +    }
    +    if (from.has_is_phishing()) {
    +      set_is_phishing(from.is_phishing());
    +    }
    +    if (from.has_model_version()) {
    +      set_model_version(from.model_version());
    +    }
    +    if (from.has_obsolete_referrer_url()) {
    +      set_obsolete_referrer_url(from.obsolete_referrer_url());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientPhishingRequest::CopyFrom(const ClientPhishingRequest& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientPhishingRequest::IsInitialized() const {
    +  if ((_has_bits_[0] & 0x00000004) != 0x00000004) return false;
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->feature_map())) return false;
    +  if (!::google::protobuf::internal::AllAreInitialized(this->non_model_feature_map())) return false;
    +  return true;
    +}
    +
    +void ClientPhishingRequest::Swap(ClientPhishingRequest* other) {
    +  if (other != this) {
    +    std::swap(url_, other->url_);
    +    std::swap(obsolete_hash_prefix_, other->obsolete_hash_prefix_);
    +    std::swap(client_score_, other->client_score_);
    +    std::swap(is_phishing_, other->is_phishing_);
    +    feature_map_.Swap(&other->feature_map_);
    +    std::swap(model_version_, other->model_version_);
    +    non_model_feature_map_.Swap(&other->non_model_feature_map_);
    +    std::swap(obsolete_referrer_url_, other->obsolete_referrer_url_);
    +    shingle_hashes_.Swap(&other->shingle_hashes_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientPhishingRequest::GetTypeName() const {
    +  return "safe_browsing.ClientPhishingRequest";
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int ClientPhishingResponse::kPhishyFieldNumber;
    +const int ClientPhishingResponse::kOBSOLETEWhitelistExpressionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientPhishingResponse::ClientPhishingResponse()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientPhishingResponse)
    +}
    +
    +void ClientPhishingResponse::InitAsDefaultInstance() {
    +}
    +
    +ClientPhishingResponse::ClientPhishingResponse(const ClientPhishingResponse& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientPhishingResponse)
    +}
    +
    +void ClientPhishingResponse::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  phishy_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientPhishingResponse::~ClientPhishingResponse() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientPhishingResponse)
    +  SharedDtor();
    +}
    +
    +void ClientPhishingResponse::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientPhishingResponse::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientPhishingResponse& ClientPhishingResponse::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientPhishingResponse* ClientPhishingResponse::default_instance_ = NULL;
    +
    +ClientPhishingResponse* ClientPhishingResponse::New() const {
    +  return new ClientPhishingResponse;
    +}
    +
    +void ClientPhishingResponse::Clear() {
    +  phishy_ = false;
    +  obsolete_whitelist_expression_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientPhishingResponse::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientPhishingResponse)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // required bool phishy = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &phishy_)));
    +          set_has_phishy();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_OBSOLETE_whitelist_expression;
    +        break;
    +      }
    +
    +      // repeated string OBSOLETE_whitelist_expression = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_OBSOLETE_whitelist_expression:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->add_obsolete_whitelist_expression()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_OBSOLETE_whitelist_expression;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientPhishingResponse)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientPhishingResponse)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientPhishingResponse::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientPhishingResponse)
    +  // required bool phishy = 1;
    +  if (has_phishy()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->phishy(), output);
    +  }
    +
    +  // repeated string OBSOLETE_whitelist_expression = 2;
    +  for (int i = 0; i < this->obsolete_whitelist_expression_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteString(
    +      2, this->obsolete_whitelist_expression(i), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientPhishingResponse)
    +}
    +
    +int ClientPhishingResponse::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // required bool phishy = 1;
    +    if (has_phishy()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  // repeated string OBSOLETE_whitelist_expression = 2;
    +  total_size += 1 * this->obsolete_whitelist_expression_size();
    +  for (int i = 0; i < this->obsolete_whitelist_expression_size(); i++) {
    +    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
    +      this->obsolete_whitelist_expression(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientPhishingResponse::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientPhishingResponse::MergeFrom(const ClientPhishingResponse& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  obsolete_whitelist_expression_.MergeFrom(from.obsolete_whitelist_expression_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_phishy()) {
    +      set_phishy(from.phishy());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientPhishingResponse::CopyFrom(const ClientPhishingResponse& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientPhishingResponse::IsInitialized() const {
    +  if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    +
    +  return true;
    +}
    +
    +void ClientPhishingResponse::Swap(ClientPhishingResponse* other) {
    +  if (other != this) {
    +    std::swap(phishy_, other->phishy_);
    +    obsolete_whitelist_expression_.Swap(&other->obsolete_whitelist_expression_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientPhishingResponse::GetTypeName() const {
    +  return "safe_browsing.ClientPhishingResponse";
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int ClientMalwareRequest_UrlInfo::kIpFieldNumber;
    +const int ClientMalwareRequest_UrlInfo::kUrlFieldNumber;
    +const int ClientMalwareRequest_UrlInfo::kMethodFieldNumber;
    +const int ClientMalwareRequest_UrlInfo::kReferrerFieldNumber;
    +const int ClientMalwareRequest_UrlInfo::kResourceTypeFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientMalwareRequest_UrlInfo::ClientMalwareRequest_UrlInfo()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientMalwareRequest.UrlInfo)
    +}
    +
    +void ClientMalwareRequest_UrlInfo::InitAsDefaultInstance() {
    +}
    +
    +ClientMalwareRequest_UrlInfo::ClientMalwareRequest_UrlInfo(const ClientMalwareRequest_UrlInfo& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientMalwareRequest.UrlInfo)
    +}
    +
    +void ClientMalwareRequest_UrlInfo::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  method_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  resource_type_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientMalwareRequest_UrlInfo::~ClientMalwareRequest_UrlInfo() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientMalwareRequest.UrlInfo)
    +  SharedDtor();
    +}
    +
    +void ClientMalwareRequest_UrlInfo::SharedDtor() {
    +  if (ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete ip_;
    +  }
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (method_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete method_;
    +  }
    +  if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete referrer_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientMalwareRequest_UrlInfo::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientMalwareRequest_UrlInfo& ClientMalwareRequest_UrlInfo::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientMalwareRequest_UrlInfo* ClientMalwareRequest_UrlInfo::default_instance_ = NULL;
    +
    +ClientMalwareRequest_UrlInfo* ClientMalwareRequest_UrlInfo::New() const {
    +  return new ClientMalwareRequest_UrlInfo;
    +}
    +
    +void ClientMalwareRequest_UrlInfo::Clear() {
    +  if (_has_bits_[0 / 32] & 31) {
    +    if (has_ip()) {
    +      if (ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        ip_->clear();
    +      }
    +    }
    +    if (has_url()) {
    +      if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        url_->clear();
    +      }
    +    }
    +    if (has_method()) {
    +      if (method_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        method_->clear();
    +      }
    +    }
    +    if (has_referrer()) {
    +      if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        referrer_->clear();
    +      }
    +    }
    +    resource_type_ = 0;
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientMalwareRequest_UrlInfo::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientMalwareRequest.UrlInfo)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // required string ip = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_ip()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_url;
    +        break;
    +      }
    +
    +      // required string url = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_url:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_url()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_method;
    +        break;
    +      }
    +
    +      // optional string method = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_method:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_method()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_referrer;
    +        break;
    +      }
    +
    +      // optional string referrer = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_referrer:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_referrer()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(40)) goto parse_resource_type;
    +        break;
    +      }
    +
    +      // optional int32 resource_type = 5;
    +      case 5: {
    +        if (tag == 40) {
    +         parse_resource_type:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &resource_type_)));
    +          set_has_resource_type();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientMalwareRequest.UrlInfo)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientMalwareRequest.UrlInfo)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientMalwareRequest_UrlInfo::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientMalwareRequest.UrlInfo)
    +  // required string ip = 1;
    +  if (has_ip()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->ip(), output);
    +  }
    +
    +  // required string url = 2;
    +  if (has_url()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->url(), output);
    +  }
    +
    +  // optional string method = 3;
    +  if (has_method()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      3, this->method(), output);
    +  }
    +
    +  // optional string referrer = 4;
    +  if (has_referrer()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      4, this->referrer(), output);
    +  }
    +
    +  // optional int32 resource_type = 5;
    +  if (has_resource_type()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->resource_type(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientMalwareRequest.UrlInfo)
    +}
    +
    +int ClientMalwareRequest_UrlInfo::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // required string ip = 1;
    +    if (has_ip()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->ip());
    +    }
    +
    +    // required string url = 2;
    +    if (has_url()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->url());
    +    }
    +
    +    // optional string method = 3;
    +    if (has_method()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->method());
    +    }
    +
    +    // optional string referrer = 4;
    +    if (has_referrer()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->referrer());
    +    }
    +
    +    // optional int32 resource_type = 5;
    +    if (has_resource_type()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->resource_type());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientMalwareRequest_UrlInfo::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientMalwareRequest_UrlInfo::MergeFrom(const ClientMalwareRequest_UrlInfo& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_ip()) {
    +      set_ip(from.ip());
    +    }
    +    if (from.has_url()) {
    +      set_url(from.url());
    +    }
    +    if (from.has_method()) {
    +      set_method(from.method());
    +    }
    +    if (from.has_referrer()) {
    +      set_referrer(from.referrer());
    +    }
    +    if (from.has_resource_type()) {
    +      set_resource_type(from.resource_type());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientMalwareRequest_UrlInfo::CopyFrom(const ClientMalwareRequest_UrlInfo& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientMalwareRequest_UrlInfo::IsInitialized() const {
    +  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
    +
    +  return true;
    +}
    +
    +void ClientMalwareRequest_UrlInfo::Swap(ClientMalwareRequest_UrlInfo* other) {
    +  if (other != this) {
    +    std::swap(ip_, other->ip_);
    +    std::swap(url_, other->url_);
    +    std::swap(method_, other->method_);
    +    std::swap(referrer_, other->referrer_);
    +    std::swap(resource_type_, other->resource_type_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientMalwareRequest_UrlInfo::GetTypeName() const {
    +  return "safe_browsing.ClientMalwareRequest.UrlInfo";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientMalwareRequest::kUrlFieldNumber;
    +const int ClientMalwareRequest::kReferrerUrlFieldNumber;
    +const int ClientMalwareRequest::kBadIpUrlInfoFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientMalwareRequest::ClientMalwareRequest()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientMalwareRequest)
    +}
    +
    +void ClientMalwareRequest::InitAsDefaultInstance() {
    +}
    +
    +ClientMalwareRequest::ClientMalwareRequest(const ClientMalwareRequest& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientMalwareRequest)
    +}
    +
    +void ClientMalwareRequest::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  referrer_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientMalwareRequest::~ClientMalwareRequest() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientMalwareRequest)
    +  SharedDtor();
    +}
    +
    +void ClientMalwareRequest::SharedDtor() {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete referrer_url_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientMalwareRequest::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientMalwareRequest& ClientMalwareRequest::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientMalwareRequest* ClientMalwareRequest::default_instance_ = NULL;
    +
    +ClientMalwareRequest* ClientMalwareRequest::New() const {
    +  return new ClientMalwareRequest;
    +}
    +
    +void ClientMalwareRequest::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_url()) {
    +      if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        url_->clear();
    +      }
    +    }
    +    if (has_referrer_url()) {
    +      if (referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        referrer_url_->clear();
    +      }
    +    }
    +  }
    +  bad_ip_url_info_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientMalwareRequest::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientMalwareRequest)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // required string url = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_url()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_referrer_url;
    +        break;
    +      }
    +
    +      // optional string referrer_url = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_referrer_url:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_referrer_url()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(58)) goto parse_bad_ip_url_info;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientMalwareRequest.UrlInfo bad_ip_url_info = 7;
    +      case 7: {
    +        if (tag == 58) {
    +         parse_bad_ip_url_info:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_bad_ip_url_info()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(58)) goto parse_bad_ip_url_info;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientMalwareRequest)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientMalwareRequest)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientMalwareRequest::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientMalwareRequest)
    +  // required string url = 1;
    +  if (has_url()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->url(), output);
    +  }
    +
    +  // optional string referrer_url = 4;
    +  if (has_referrer_url()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      4, this->referrer_url(), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientMalwareRequest.UrlInfo bad_ip_url_info = 7;
    +  for (int i = 0; i < this->bad_ip_url_info_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      7, this->bad_ip_url_info(i), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientMalwareRequest)
    +}
    +
    +int ClientMalwareRequest::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // required string url = 1;
    +    if (has_url()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->url());
    +    }
    +
    +    // optional string referrer_url = 4;
    +    if (has_referrer_url()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->referrer_url());
    +    }
    +
    +  }
    +  // repeated .safe_browsing.ClientMalwareRequest.UrlInfo bad_ip_url_info = 7;
    +  total_size += 1 * this->bad_ip_url_info_size();
    +  for (int i = 0; i < this->bad_ip_url_info_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->bad_ip_url_info(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientMalwareRequest::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientMalwareRequest::MergeFrom(const ClientMalwareRequest& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  bad_ip_url_info_.MergeFrom(from.bad_ip_url_info_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_url()) {
    +      set_url(from.url());
    +    }
    +    if (from.has_referrer_url()) {
    +      set_referrer_url(from.referrer_url());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientMalwareRequest::CopyFrom(const ClientMalwareRequest& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientMalwareRequest::IsInitialized() const {
    +  if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->bad_ip_url_info())) return false;
    +  return true;
    +}
    +
    +void ClientMalwareRequest::Swap(ClientMalwareRequest* other) {
    +  if (other != this) {
    +    std::swap(url_, other->url_);
    +    std::swap(referrer_url_, other->referrer_url_);
    +    bad_ip_url_info_.Swap(&other->bad_ip_url_info_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientMalwareRequest::GetTypeName() const {
    +  return "safe_browsing.ClientMalwareRequest";
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int ClientMalwareResponse::kBlacklistFieldNumber;
    +const int ClientMalwareResponse::kBadIpFieldNumber;
    +const int ClientMalwareResponse::kBadUrlFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientMalwareResponse::ClientMalwareResponse()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientMalwareResponse)
    +}
    +
    +void ClientMalwareResponse::InitAsDefaultInstance() {
    +}
    +
    +ClientMalwareResponse::ClientMalwareResponse(const ClientMalwareResponse& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientMalwareResponse)
    +}
    +
    +void ClientMalwareResponse::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  blacklist_ = false;
    +  bad_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  bad_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientMalwareResponse::~ClientMalwareResponse() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientMalwareResponse)
    +  SharedDtor();
    +}
    +
    +void ClientMalwareResponse::SharedDtor() {
    +  if (bad_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete bad_ip_;
    +  }
    +  if (bad_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete bad_url_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientMalwareResponse::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientMalwareResponse& ClientMalwareResponse::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientMalwareResponse* ClientMalwareResponse::default_instance_ = NULL;
    +
    +ClientMalwareResponse* ClientMalwareResponse::New() const {
    +  return new ClientMalwareResponse;
    +}
    +
    +void ClientMalwareResponse::Clear() {
    +  if (_has_bits_[0 / 32] & 7) {
    +    blacklist_ = false;
    +    if (has_bad_ip()) {
    +      if (bad_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        bad_ip_->clear();
    +      }
    +    }
    +    if (has_bad_url()) {
    +      if (bad_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        bad_url_->clear();
    +      }
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientMalwareResponse::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientMalwareResponse)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // required bool blacklist = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &blacklist_)));
    +          set_has_blacklist();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_bad_ip;
    +        break;
    +      }
    +
    +      // optional string bad_ip = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_bad_ip:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_bad_ip()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_bad_url;
    +        break;
    +      }
    +
    +      // optional string bad_url = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_bad_url:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_bad_url()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientMalwareResponse)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientMalwareResponse)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientMalwareResponse::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientMalwareResponse)
    +  // required bool blacklist = 1;
    +  if (has_blacklist()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->blacklist(), output);
    +  }
    +
    +  // optional string bad_ip = 2;
    +  if (has_bad_ip()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->bad_ip(), output);
    +  }
    +
    +  // optional string bad_url = 3;
    +  if (has_bad_url()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      3, this->bad_url(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientMalwareResponse)
    +}
    +
    +int ClientMalwareResponse::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // required bool blacklist = 1;
    +    if (has_blacklist()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional string bad_ip = 2;
    +    if (has_bad_ip()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->bad_ip());
    +    }
    +
    +    // optional string bad_url = 3;
    +    if (has_bad_url()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->bad_url());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientMalwareResponse::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientMalwareResponse::MergeFrom(const ClientMalwareResponse& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_blacklist()) {
    +      set_blacklist(from.blacklist());
    +    }
    +    if (from.has_bad_ip()) {
    +      set_bad_ip(from.bad_ip());
    +    }
    +    if (from.has_bad_url()) {
    +      set_bad_url(from.bad_url());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientMalwareResponse::CopyFrom(const ClientMalwareResponse& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientMalwareResponse::IsInitialized() const {
    +  if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    +
    +  return true;
    +}
    +
    +void ClientMalwareResponse::Swap(ClientMalwareResponse* other) {
    +  if (other != this) {
    +    std::swap(blacklist_, other->blacklist_);
    +    std::swap(bad_ip_, other->bad_ip_);
    +    std::swap(bad_url_, other->bad_url_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientMalwareResponse::GetTypeName() const {
    +  return "safe_browsing.ClientMalwareResponse";
    +}
     
     
     // ===================================================================
    @@ -94,6 +2061,7 @@ bool ClientDownloadRequest_DownloadType_IsValid(int value) {
         case 1:
         case 2:
         case 3:
    +    case 4:
           return true;
         default:
           return false;
    @@ -105,6 +2073,7 @@ const ClientDownloadRequest_DownloadType ClientDownloadRequest::WIN_EXECUTABLE;
     const ClientDownloadRequest_DownloadType ClientDownloadRequest::CHROME_EXTENSION;
     const ClientDownloadRequest_DownloadType ClientDownloadRequest::ANDROID_APK;
     const ClientDownloadRequest_DownloadType ClientDownloadRequest::ZIPPED_EXECUTABLE;
    +const ClientDownloadRequest_DownloadType ClientDownloadRequest::MAC_EXECUTABLE;
     const ClientDownloadRequest_DownloadType ClientDownloadRequest::DownloadType_MIN;
     const ClientDownloadRequest_DownloadType ClientDownloadRequest::DownloadType_MAX;
     const int ClientDownloadRequest::DownloadType_ARRAYSIZE;
    @@ -118,6 +2087,7 @@ const int ClientDownloadRequest_Digests::kMd5FieldNumber;
     ClientDownloadRequest_Digests::ClientDownloadRequest_Digests()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.Digests)
     }
     
     void ClientDownloadRequest_Digests::InitAsDefaultInstance() {
    @@ -127,31 +2097,38 @@ ClientDownloadRequest_Digests::ClientDownloadRequest_Digests(const ClientDownloa
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.Digests)
     }
     
     void ClientDownloadRequest_Digests::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
    -  sha256_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  sha1_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  md5_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  sha256_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  sha1_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  md5_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadRequest_Digests::~ClientDownloadRequest_Digests() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.Digests)
       SharedDtor();
     }
     
     void ClientDownloadRequest_Digests::SharedDtor() {
    -  if (sha256_ != &::google::protobuf::internal::kEmptyString) {
    +  if (sha256_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete sha256_;
       }
    -  if (sha1_ != &::google::protobuf::internal::kEmptyString) {
    +  if (sha1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete sha1_;
       }
    -  if (md5_ != &::google::protobuf::internal::kEmptyString) {
    +  if (md5_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete md5_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -161,7 +2138,12 @@ void ClientDownloadRequest_Digests::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_Digests& ClientDownloadRequest_Digests::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_Digests* ClientDownloadRequest_Digests::default_instance_ = NULL;
    @@ -171,113 +2153,130 @@ ClientDownloadRequest_Digests* ClientDownloadRequest_Digests::New() const {
     }
     
     void ClientDownloadRequest_Digests::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 7) {
         if (has_sha256()) {
    -      if (sha256_ != &::google::protobuf::internal::kEmptyString) {
    +      if (sha256_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             sha256_->clear();
           }
         }
         if (has_sha1()) {
    -      if (sha1_ != &::google::protobuf::internal::kEmptyString) {
    +      if (sha1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             sha1_->clear();
           }
         }
         if (has_md5()) {
    -      if (md5_ != &::google::protobuf::internal::kEmptyString) {
    +      if (md5_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             md5_->clear();
           }
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_Digests::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.Digests)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional bytes sha256 = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_sha256()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_sha1;
             break;
           }
    -      
    +
           // optional bytes sha1 = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_sha1:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_sha1()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(26)) goto parse_md5;
             break;
           }
    -      
    +
           // optional bytes md5 = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 26) {
              parse_md5:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_md5()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.Digests)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.Digests)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_Digests::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.Digests)
       // optional bytes sha256 = 1;
       if (has_sha256()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           1, this->sha256(), output);
       }
    -  
    +
       // optional bytes sha1 = 2;
       if (has_sha1()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           2, this->sha1(), output);
       }
    -  
    +
       // optional bytes md5 = 3;
       if (has_md5()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           3, this->md5(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.Digests)
     }
     
     int ClientDownloadRequest_Digests::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional bytes sha256 = 1;
         if (has_sha256()) {
    @@ -285,22 +2284,24 @@ int ClientDownloadRequest_Digests::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->sha256());
         }
    -    
    +
         // optional bytes sha1 = 2;
         if (has_sha1()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->sha1());
         }
    -    
    +
         // optional bytes md5 = 3;
         if (has_md5()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->md5());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -325,6 +2326,7 @@ void ClientDownloadRequest_Digests::MergeFrom(const ClientDownloadRequest_Digest
           set_md5(from.md5());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_Digests::CopyFrom(const ClientDownloadRequest_Digests& from) {
    @@ -334,7 +2336,7 @@ void ClientDownloadRequest_Digests::CopyFrom(const ClientDownloadRequest_Digests
     }
     
     bool ClientDownloadRequest_Digests::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -344,6 +2346,7 @@ void ClientDownloadRequest_Digests::Swap(ClientDownloadRequest_Digests* other) {
         std::swap(sha1_, other->sha1_);
         std::swap(md5_, other->md5_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -365,6 +2368,7 @@ const int ClientDownloadRequest_Resource::kReferrerFieldNumber;
     ClientDownloadRequest_Resource::ClientDownloadRequest_Resource()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.Resource)
     }
     
     void ClientDownloadRequest_Resource::InitAsDefaultInstance() {
    @@ -374,32 +2378,39 @@ ClientDownloadRequest_Resource::ClientDownloadRequest_Resource(const ClientDownl
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.Resource)
     }
     
     void ClientDownloadRequest_Resource::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
    -  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       type_ = 0;
    -  remote_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  remote_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadRequest_Resource::~ClientDownloadRequest_Resource() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.Resource)
       SharedDtor();
     }
     
     void ClientDownloadRequest_Resource::SharedDtor() {
    -  if (url_ != &::google::protobuf::internal::kEmptyString) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete url_;
       }
    -  if (remote_ip_ != &::google::protobuf::internal::kEmptyString) {
    +  if (remote_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete remote_ip_;
       }
    -  if (referrer_ != &::google::protobuf::internal::kEmptyString) {
    +  if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete referrer_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -409,7 +2420,12 @@ void ClientDownloadRequest_Resource::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_Resource& ClientDownloadRequest_Resource::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_Resource* ClientDownloadRequest_Resource::default_instance_ = NULL;
    @@ -419,50 +2435,57 @@ ClientDownloadRequest_Resource* ClientDownloadRequest_Resource::New() const {
     }
     
     void ClientDownloadRequest_Resource::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 15) {
         if (has_url()) {
    -      if (url_ != &::google::protobuf::internal::kEmptyString) {
    +      if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             url_->clear();
           }
         }
         type_ = 0;
         if (has_remote_ip()) {
    -      if (remote_ip_ != &::google::protobuf::internal::kEmptyString) {
    +      if (remote_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             remote_ip_->clear();
           }
         }
         if (has_referrer()) {
    -      if (referrer_ != &::google::protobuf::internal::kEmptyString) {
    +      if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             referrer_->clear();
           }
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_Resource::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.Resource)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required string url = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                     input, this->mutable_url()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(16)) goto parse_type;
             break;
           }
    -      
    +
           // required .safe_browsing.ClientDownloadRequest.ResourceType type = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_type:
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    @@ -470,88 +2493,100 @@ bool ClientDownloadRequest_Resource::MergePartialFromCodedStream(
                      input, &value)));
               if (::safe_browsing::ClientDownloadRequest_ResourceType_IsValid(value)) {
                 set_type(static_cast< ::safe_browsing::ClientDownloadRequest_ResourceType >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(26)) goto parse_remote_ip;
             break;
           }
    -      
    +
           // optional bytes remote_ip = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 26) {
              parse_remote_ip:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_remote_ip()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(34)) goto parse_referrer;
             break;
           }
    -      
    +
           // optional string referrer = 4;
           case 4: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 34) {
              parse_referrer:
               DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                     input, this->mutable_referrer()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.Resource)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.Resource)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_Resource::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.Resource)
       // required string url = 1;
       if (has_url()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteString(
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
           1, this->url(), output);
       }
    -  
    +
       // required .safe_browsing.ClientDownloadRequest.ResourceType type = 2;
       if (has_type()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           2, this->type(), output);
       }
    -  
    +
       // optional bytes remote_ip = 3;
       if (has_remote_ip()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           3, this->remote_ip(), output);
       }
    -  
    +
       // optional string referrer = 4;
       if (has_referrer()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteString(
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
           4, this->referrer(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.Resource)
     }
     
     int ClientDownloadRequest_Resource::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required string url = 1;
         if (has_url()) {
    @@ -559,28 +2594,30 @@ int ClientDownloadRequest_Resource::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::StringSize(
               this->url());
         }
    -    
    +
         // required .safe_browsing.ClientDownloadRequest.ResourceType type = 2;
         if (has_type()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
         }
    -    
    +
         // optional bytes remote_ip = 3;
         if (has_remote_ip()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->remote_ip());
         }
    -    
    +
         // optional string referrer = 4;
         if (has_referrer()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::StringSize(
               this->referrer());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -608,6 +2645,7 @@ void ClientDownloadRequest_Resource::MergeFrom(const ClientDownloadRequest_Resou
           set_referrer(from.referrer());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_Resource::CopyFrom(const ClientDownloadRequest_Resource& from) {
    @@ -618,7 +2656,7 @@ void ClientDownloadRequest_Resource::CopyFrom(const ClientDownloadRequest_Resour
     
     bool ClientDownloadRequest_Resource::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
    -  
    +
       return true;
     }
     
    @@ -629,6 +2667,7 @@ void ClientDownloadRequest_Resource::Swap(ClientDownloadRequest_Resource* other)
         std::swap(remote_ip_, other->remote_ip_);
         std::swap(referrer_, other->referrer_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -647,6 +2686,7 @@ const int ClientDownloadRequest_CertificateChain_Element::kCertificateFieldNumbe
     ClientDownloadRequest_CertificateChain_Element::ClientDownloadRequest_CertificateChain_Element()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
     }
     
     void ClientDownloadRequest_CertificateChain_Element::InitAsDefaultInstance() {
    @@ -656,23 +2696,30 @@ ClientDownloadRequest_CertificateChain_Element::ClientDownloadRequest_Certificat
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
     }
     
     void ClientDownloadRequest_CertificateChain_Element::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
    -  certificate_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  certificate_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadRequest_CertificateChain_Element::~ClientDownloadRequest_CertificateChain_Element() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
       SharedDtor();
     }
     
     void ClientDownloadRequest_CertificateChain_Element::SharedDtor() {
    -  if (certificate_ != &::google::protobuf::internal::kEmptyString) {
    +  if (certificate_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete certificate_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -682,7 +2729,12 @@ void ClientDownloadRequest_CertificateChain_Element::SetCachedSize(int size) con
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_CertificateChain_Element& ClientDownloadRequest_CertificateChain_Element::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_CertificateChain_Element* ClientDownloadRequest_CertificateChain_Element::default_instance_ = NULL;
    @@ -692,63 +2744,80 @@ ClientDownloadRequest_CertificateChain_Element* ClientDownloadRequest_Certificat
     }
     
     void ClientDownloadRequest_CertificateChain_Element::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    if (has_certificate()) {
    -      if (certificate_ != &::google::protobuf::internal::kEmptyString) {
    -        certificate_->clear();
    -      }
    +  if (has_certificate()) {
    +    if (certificate_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +      certificate_->clear();
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_CertificateChain_Element::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional bytes certificate = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_certificate()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_CertificateChain_Element::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
       // optional bytes certificate = 1;
       if (has_certificate()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           1, this->certificate(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
     }
     
     int ClientDownloadRequest_CertificateChain_Element::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional bytes certificate = 1;
         if (has_certificate()) {
    @@ -756,8 +2825,10 @@ int ClientDownloadRequest_CertificateChain_Element::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->certificate());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -776,6 +2847,7 @@ void ClientDownloadRequest_CertificateChain_Element::MergeFrom(const ClientDownl
           set_certificate(from.certificate());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_CertificateChain_Element::CopyFrom(const ClientDownloadRequest_CertificateChain_Element& from) {
    @@ -785,7 +2857,7 @@ void ClientDownloadRequest_CertificateChain_Element::CopyFrom(const ClientDownlo
     }
     
     bool ClientDownloadRequest_CertificateChain_Element::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -793,6 +2865,7 @@ void ClientDownloadRequest_CertificateChain_Element::Swap(ClientDownloadRequest_
       if (other != this) {
         std::swap(certificate_, other->certificate_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -811,6 +2884,7 @@ const int ClientDownloadRequest_CertificateChain::kElementFieldNumber;
     ClientDownloadRequest_CertificateChain::ClientDownloadRequest_CertificateChain()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.CertificateChain)
     }
     
     void ClientDownloadRequest_CertificateChain::InitAsDefaultInstance() {
    @@ -820,6 +2894,7 @@ ClientDownloadRequest_CertificateChain::ClientDownloadRequest_CertificateChain(c
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.CertificateChain)
     }
     
     void ClientDownloadRequest_CertificateChain::SharedCtor() {
    @@ -828,11 +2903,16 @@ void ClientDownloadRequest_CertificateChain::SharedCtor() {
     }
     
     ClientDownloadRequest_CertificateChain::~ClientDownloadRequest_CertificateChain() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.CertificateChain)
       SharedDtor();
     }
     
     void ClientDownloadRequest_CertificateChain::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -842,7 +2922,12 @@ void ClientDownloadRequest_CertificateChain::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_CertificateChain& ClientDownloadRequest_CertificateChain::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_CertificateChain* ClientDownloadRequest_CertificateChain::default_instance_ = NULL;
    @@ -854,57 +2939,76 @@ ClientDownloadRequest_CertificateChain* ClientDownloadRequest_CertificateChain::
     void ClientDownloadRequest_CertificateChain::Clear() {
       element_.Clear();
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_CertificateChain::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.CertificateChain)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // repeated .safe_browsing.ClientDownloadRequest.CertificateChain.Element element = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
              parse_element:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                     input, add_element()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(10)) goto parse_element;
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.CertificateChain)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.CertificateChain)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_CertificateChain::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.CertificateChain)
       // repeated .safe_browsing.ClientDownloadRequest.CertificateChain.Element element = 1;
       for (int i = 0; i < this->element_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           1, this->element(i), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.CertificateChain)
     }
     
     int ClientDownloadRequest_CertificateChain::ByteSize() const {
       int total_size = 0;
    -  
    +
       // repeated .safe_browsing.ClientDownloadRequest.CertificateChain.Element element = 1;
       total_size += 1 * this->element_size();
       for (int i = 0; i < this->element_size(); i++) {
    @@ -912,7 +3016,9 @@ int ClientDownloadRequest_CertificateChain::ByteSize() const {
           ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
             this->element(i));
       }
    -  
    +
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -927,6 +3033,7 @@ void ClientDownloadRequest_CertificateChain::CheckTypeAndMergeFrom(
     void ClientDownloadRequest_CertificateChain::MergeFrom(const ClientDownloadRequest_CertificateChain& from) {
       GOOGLE_CHECK_NE(&from, this);
       element_.MergeFrom(from.element_);
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_CertificateChain::CopyFrom(const ClientDownloadRequest_CertificateChain& from) {
    @@ -936,7 +3043,7 @@ void ClientDownloadRequest_CertificateChain::CopyFrom(const ClientDownloadReques
     }
     
     bool ClientDownloadRequest_CertificateChain::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -944,6 +3051,7 @@ void ClientDownloadRequest_CertificateChain::Swap(ClientDownloadRequest_Certific
       if (other != this) {
         element_.Swap(&other->element_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -963,6 +3071,7 @@ const int ClientDownloadRequest_SignatureInfo::kTrustedFieldNumber;
     ClientDownloadRequest_SignatureInfo::ClientDownloadRequest_SignatureInfo()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.SignatureInfo)
     }
     
     void ClientDownloadRequest_SignatureInfo::InitAsDefaultInstance() {
    @@ -972,6 +3081,7 @@ ClientDownloadRequest_SignatureInfo::ClientDownloadRequest_SignatureInfo(const C
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.SignatureInfo)
     }
     
     void ClientDownloadRequest_SignatureInfo::SharedCtor() {
    @@ -981,11 +3091,16 @@ void ClientDownloadRequest_SignatureInfo::SharedCtor() {
     }
     
     ClientDownloadRequest_SignatureInfo::~ClientDownloadRequest_SignatureInfo() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.SignatureInfo)
       SharedDtor();
     }
     
     void ClientDownloadRequest_SignatureInfo::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -995,7 +3110,12 @@ void ClientDownloadRequest_SignatureInfo::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_SignatureInfo& ClientDownloadRequest_SignatureInfo::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_SignatureInfo* ClientDownloadRequest_SignatureInfo::default_instance_ = NULL;
    @@ -1005,89 +3125,105 @@ ClientDownloadRequest_SignatureInfo* ClientDownloadRequest_SignatureInfo::New()
     }
     
     void ClientDownloadRequest_SignatureInfo::Clear() {
    -  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    -    trusted_ = false;
    -  }
    +  trusted_ = false;
       certificate_chain_.Clear();
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_SignatureInfo::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.SignatureInfo)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // repeated .safe_browsing.ClientDownloadRequest.CertificateChain certificate_chain = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
              parse_certificate_chain:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                     input, add_certificate_chain()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(10)) goto parse_certificate_chain;
             if (input->ExpectTag(16)) goto parse_trusted;
             break;
           }
    -      
    +
           // optional bool trusted = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 16) {
              parse_trusted:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &trusted_)));
               set_has_trusted();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.SignatureInfo)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.SignatureInfo)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_SignatureInfo::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.SignatureInfo)
       // repeated .safe_browsing.ClientDownloadRequest.CertificateChain certificate_chain = 1;
       for (int i = 0; i < this->certificate_chain_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           1, this->certificate_chain(i), output);
       }
    -  
    +
       // optional bool trusted = 2;
       if (has_trusted()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->trusted(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.SignatureInfo)
     }
     
     int ClientDownloadRequest_SignatureInfo::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
         // optional bool trusted = 2;
         if (has_trusted()) {
           total_size += 1 + 1;
         }
    -    
    +
       }
       // repeated .safe_browsing.ClientDownloadRequest.CertificateChain certificate_chain = 1;
       total_size += 1 * this->certificate_chain_size();
    @@ -1096,7 +3232,9 @@ int ClientDownloadRequest_SignatureInfo::ByteSize() const {
           ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
             this->certificate_chain(i));
       }
    -  
    +
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1116,6 +3254,7 @@ void ClientDownloadRequest_SignatureInfo::MergeFrom(const ClientDownloadRequest_
           set_trusted(from.trusted());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_SignatureInfo::CopyFrom(const ClientDownloadRequest_SignatureInfo& from) {
    @@ -1125,7 +3264,7 @@ void ClientDownloadRequest_SignatureInfo::CopyFrom(const ClientDownloadRequest_S
     }
     
     bool ClientDownloadRequest_SignatureInfo::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1134,6 +3273,7 @@ void ClientDownloadRequest_SignatureInfo::Swap(ClientDownloadRequest_SignatureIn
         certificate_chain_.Swap(&other->certificate_chain_);
         std::swap(trusted_, other->trusted_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1153,6 +3293,7 @@ const int ClientDownloadRequest_PEImageHeaders_DebugData::kRawDataFieldNumber;
     ClientDownloadRequest_PEImageHeaders_DebugData::ClientDownloadRequest_PEImageHeaders_DebugData()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
     }
     
     void ClientDownloadRequest_PEImageHeaders_DebugData::InitAsDefaultInstance() {
    @@ -1162,27 +3303,34 @@ ClientDownloadRequest_PEImageHeaders_DebugData::ClientDownloadRequest_PEImageHea
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
     }
     
     void ClientDownloadRequest_PEImageHeaders_DebugData::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
    -  directory_entry_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  raw_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  directory_entry_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  raw_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadRequest_PEImageHeaders_DebugData::~ClientDownloadRequest_PEImageHeaders_DebugData() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
       SharedDtor();
     }
     
     void ClientDownloadRequest_PEImageHeaders_DebugData::SharedDtor() {
    -  if (directory_entry_ != &::google::protobuf::internal::kEmptyString) {
    +  if (directory_entry_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete directory_entry_;
       }
    -  if (raw_data_ != &::google::protobuf::internal::kEmptyString) {
    +  if (raw_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete raw_data_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -1192,7 +3340,12 @@ void ClientDownloadRequest_PEImageHeaders_DebugData::SetCachedSize(int size) con
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_PEImageHeaders_DebugData& ClientDownloadRequest_PEImageHeaders_DebugData::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_PEImageHeaders_DebugData* ClientDownloadRequest_PEImageHeaders_DebugData::default_instance_ = NULL;
    @@ -1202,88 +3355,106 @@ ClientDownloadRequest_PEImageHeaders_DebugData* ClientDownloadRequest_PEImageHea
     }
     
     void ClientDownloadRequest_PEImageHeaders_DebugData::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 3) {
         if (has_directory_entry()) {
    -      if (directory_entry_ != &::google::protobuf::internal::kEmptyString) {
    +      if (directory_entry_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             directory_entry_->clear();
           }
         }
         if (has_raw_data()) {
    -      if (raw_data_ != &::google::protobuf::internal::kEmptyString) {
    +      if (raw_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             raw_data_->clear();
           }
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_PEImageHeaders_DebugData::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional bytes directory_entry = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_directory_entry()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_raw_data;
             break;
           }
    -      
    +
           // optional bytes raw_data = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_raw_data:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_raw_data()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_PEImageHeaders_DebugData::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
       // optional bytes directory_entry = 1;
       if (has_directory_entry()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           1, this->directory_entry(), output);
       }
    -  
    +
       // optional bytes raw_data = 2;
       if (has_raw_data()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           2, this->raw_data(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
     }
     
     int ClientDownloadRequest_PEImageHeaders_DebugData::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional bytes directory_entry = 1;
         if (has_directory_entry()) {
    @@ -1291,15 +3462,17 @@ int ClientDownloadRequest_PEImageHeaders_DebugData::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->directory_entry());
         }
    -    
    +
         // optional bytes raw_data = 2;
         if (has_raw_data()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->raw_data());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1321,6 +3494,7 @@ void ClientDownloadRequest_PEImageHeaders_DebugData::MergeFrom(const ClientDownl
           set_raw_data(from.raw_data());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_PEImageHeaders_DebugData::CopyFrom(const ClientDownloadRequest_PEImageHeaders_DebugData& from) {
    @@ -1330,7 +3504,7 @@ void ClientDownloadRequest_PEImageHeaders_DebugData::CopyFrom(const ClientDownlo
     }
     
     bool ClientDownloadRequest_PEImageHeaders_DebugData::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1339,6 +3513,7 @@ void ClientDownloadRequest_PEImageHeaders_DebugData::Swap(ClientDownloadRequest_
         std::swap(directory_entry_, other->directory_entry_);
         std::swap(raw_data_, other->raw_data_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1363,6 +3538,7 @@ const int ClientDownloadRequest_PEImageHeaders::kDebugDataFieldNumber;
     ClientDownloadRequest_PEImageHeaders::ClientDownloadRequest_PEImageHeaders()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.PEImageHeaders)
     }
     
     void ClientDownloadRequest_PEImageHeaders::InitAsDefaultInstance() {
    @@ -1372,39 +3548,46 @@ ClientDownloadRequest_PEImageHeaders::ClientDownloadRequest_PEImageHeaders(const
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.PEImageHeaders)
     }
     
     void ClientDownloadRequest_PEImageHeaders::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
    -  dos_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  file_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  optional_headers32_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  optional_headers64_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  export_section_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  dos_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  file_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  optional_headers32_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  optional_headers64_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  export_section_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadRequest_PEImageHeaders::~ClientDownloadRequest_PEImageHeaders() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.PEImageHeaders)
       SharedDtor();
     }
     
     void ClientDownloadRequest_PEImageHeaders::SharedDtor() {
    -  if (dos_header_ != &::google::protobuf::internal::kEmptyString) {
    +  if (dos_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete dos_header_;
       }
    -  if (file_header_ != &::google::protobuf::internal::kEmptyString) {
    +  if (file_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete file_header_;
       }
    -  if (optional_headers32_ != &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers32_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete optional_headers32_;
       }
    -  if (optional_headers64_ != &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers64_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete optional_headers64_;
       }
    -  if (export_section_data_ != &::google::protobuf::internal::kEmptyString) {
    +  if (export_section_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete export_section_data_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -1414,7 +3597,12 @@ void ClientDownloadRequest_PEImageHeaders::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_PEImageHeaders& ClientDownloadRequest_PEImageHeaders::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_PEImageHeaders* ClientDownloadRequest_PEImageHeaders::default_instance_ = NULL;
    @@ -1424,29 +3612,29 @@ ClientDownloadRequest_PEImageHeaders* ClientDownloadRequest_PEImageHeaders::New(
     }
     
     void ClientDownloadRequest_PEImageHeaders::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 47) {
         if (has_dos_header()) {
    -      if (dos_header_ != &::google::protobuf::internal::kEmptyString) {
    +      if (dos_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             dos_header_->clear();
           }
         }
         if (has_file_header()) {
    -      if (file_header_ != &::google::protobuf::internal::kEmptyString) {
    +      if (file_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             file_header_->clear();
           }
         }
         if (has_optional_headers32()) {
    -      if (optional_headers32_ != &::google::protobuf::internal::kEmptyString) {
    +      if (optional_headers32_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             optional_headers32_->clear();
           }
         }
         if (has_optional_headers64()) {
    -      if (optional_headers64_ != &::google::protobuf::internal::kEmptyString) {
    +      if (optional_headers64_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             optional_headers64_->clear();
           }
         }
         if (has_export_section_data()) {
    -      if (export_section_data_ != &::google::protobuf::internal::kEmptyString) {
    +      if (export_section_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             export_section_data_->clear();
           }
         }
    @@ -1454,177 +3642,190 @@ void ClientDownloadRequest_PEImageHeaders::Clear() {
       section_header_.Clear();
       debug_data_.Clear();
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_PEImageHeaders::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.PEImageHeaders)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional bytes dos_header = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_dos_header()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_file_header;
             break;
           }
    -      
    +
           // optional bytes file_header = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_file_header:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_file_header()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(26)) goto parse_optional_headers32;
             break;
           }
    -      
    +
           // optional bytes optional_headers32 = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 26) {
              parse_optional_headers32:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_optional_headers32()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(34)) goto parse_optional_headers64;
             break;
           }
    -      
    +
           // optional bytes optional_headers64 = 4;
           case 4: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 34) {
              parse_optional_headers64:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_optional_headers64()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(42)) goto parse_section_header;
             break;
           }
    -      
    +
           // repeated bytes section_header = 5;
           case 5: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 42) {
              parse_section_header:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->add_section_header()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(42)) goto parse_section_header;
             if (input->ExpectTag(50)) goto parse_export_section_data;
             break;
           }
    -      
    +
           // optional bytes export_section_data = 6;
           case 6: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 50) {
              parse_export_section_data:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_export_section_data()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(58)) goto parse_debug_data;
             break;
           }
    -      
    +
           // repeated .safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData debug_data = 7;
           case 7: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 58) {
              parse_debug_data:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                     input, add_debug_data()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(58)) goto parse_debug_data;
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.PEImageHeaders)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.PEImageHeaders)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_PEImageHeaders::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.PEImageHeaders)
       // optional bytes dos_header = 1;
       if (has_dos_header()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           1, this->dos_header(), output);
       }
    -  
    +
       // optional bytes file_header = 2;
       if (has_file_header()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           2, this->file_header(), output);
       }
    -  
    +
       // optional bytes optional_headers32 = 3;
       if (has_optional_headers32()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           3, this->optional_headers32(), output);
       }
    -  
    +
       // optional bytes optional_headers64 = 4;
       if (has_optional_headers64()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           4, this->optional_headers64(), output);
       }
    -  
    +
       // repeated bytes section_header = 5;
       for (int i = 0; i < this->section_header_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteBytes(
           5, this->section_header(i), output);
       }
    -  
    +
       // optional bytes export_section_data = 6;
       if (has_export_section_data()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           6, this->export_section_data(), output);
       }
    -  
    +
       // repeated .safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData debug_data = 7;
       for (int i = 0; i < this->debug_data_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           7, this->debug_data(i), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.PEImageHeaders)
     }
     
     int ClientDownloadRequest_PEImageHeaders::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional bytes dos_header = 1;
         if (has_dos_header()) {
    @@ -1632,35 +3833,35 @@ int ClientDownloadRequest_PEImageHeaders::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->dos_header());
         }
    -    
    +
         // optional bytes file_header = 2;
         if (has_file_header()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->file_header());
         }
    -    
    +
         // optional bytes optional_headers32 = 3;
         if (has_optional_headers32()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->optional_headers32());
         }
    -    
    +
         // optional bytes optional_headers64 = 4;
         if (has_optional_headers64()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->optional_headers64());
         }
    -    
    +
         // optional bytes export_section_data = 6;
         if (has_export_section_data()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->export_section_data());
         }
    -    
    +
       }
       // repeated bytes section_header = 5;
       total_size += 1 * this->section_header_size();
    @@ -1668,7 +3869,7 @@ int ClientDownloadRequest_PEImageHeaders::ByteSize() const {
         total_size += ::google::protobuf::internal::WireFormatLite::BytesSize(
           this->section_header(i));
       }
    -  
    +
       // repeated .safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData debug_data = 7;
       total_size += 1 * this->debug_data_size();
       for (int i = 0; i < this->debug_data_size(); i++) {
    @@ -1676,7 +3877,9 @@ int ClientDownloadRequest_PEImageHeaders::ByteSize() const {
           ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
             this->debug_data(i));
       }
    -  
    +
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1709,6 +3912,7 @@ void ClientDownloadRequest_PEImageHeaders::MergeFrom(const ClientDownloadRequest
           set_export_section_data(from.export_section_data());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_PEImageHeaders::CopyFrom(const ClientDownloadRequest_PEImageHeaders& from) {
    @@ -1718,7 +3922,7 @@ void ClientDownloadRequest_PEImageHeaders::CopyFrom(const ClientDownloadRequest_
     }
     
     bool ClientDownloadRequest_PEImageHeaders::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1732,6 +3936,7 @@ void ClientDownloadRequest_PEImageHeaders::Swap(ClientDownloadRequest_PEImageHea
         std::swap(export_section_data_, other->export_section_data_);
         debug_data_.Swap(&other->debug_data_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1750,16 +3955,23 @@ const int ClientDownloadRequest_ImageHeaders::kPeHeadersFieldNumber;
     ClientDownloadRequest_ImageHeaders::ClientDownloadRequest_ImageHeaders()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.ImageHeaders)
     }
     
     void ClientDownloadRequest_ImageHeaders::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  pe_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_PEImageHeaders*>(
    +      ::safe_browsing::ClientDownloadRequest_PEImageHeaders::internal_default_instance());
    +#else
       pe_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_PEImageHeaders*>(&::safe_browsing::ClientDownloadRequest_PEImageHeaders::default_instance());
    +#endif
     }
     
     ClientDownloadRequest_ImageHeaders::ClientDownloadRequest_ImageHeaders(const ClientDownloadRequest_ImageHeaders& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.ImageHeaders)
     }
     
     void ClientDownloadRequest_ImageHeaders::SharedCtor() {
    @@ -1769,11 +3981,16 @@ void ClientDownloadRequest_ImageHeaders::SharedCtor() {
     }
     
     ClientDownloadRequest_ImageHeaders::~ClientDownloadRequest_ImageHeaders() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.ImageHeaders)
       SharedDtor();
     }
     
     void ClientDownloadRequest_ImageHeaders::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
         delete pe_headers_;
       }
     }
    @@ -1784,7 +4001,12 @@ void ClientDownloadRequest_ImageHeaders::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest_ImageHeaders& ClientDownloadRequest_ImageHeaders::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest_ImageHeaders* ClientDownloadRequest_ImageHeaders::default_instance_ = NULL;
    @@ -1794,61 +4016,78 @@ ClientDownloadRequest_ImageHeaders* ClientDownloadRequest_ImageHeaders::New() co
     }
     
     void ClientDownloadRequest_ImageHeaders::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    -    if (has_pe_headers()) {
    -      if (pe_headers_ != NULL) pe_headers_->::safe_browsing::ClientDownloadRequest_PEImageHeaders::Clear();
    -    }
    +  if (has_pe_headers()) {
    +    if (pe_headers_ != NULL) pe_headers_->::safe_browsing::ClientDownloadRequest_PEImageHeaders::Clear();
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest_ImageHeaders::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.ImageHeaders)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional .safe_browsing.ClientDownloadRequest.PEImageHeaders pe_headers = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_pe_headers()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.ImageHeaders)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.ImageHeaders)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest_ImageHeaders::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.ImageHeaders)
       // optional .safe_browsing.ClientDownloadRequest.PEImageHeaders pe_headers = 1;
       if (has_pe_headers()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           1, this->pe_headers(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.ImageHeaders)
     }
     
     int ClientDownloadRequest_ImageHeaders::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional .safe_browsing.ClientDownloadRequest.PEImageHeaders pe_headers = 1;
         if (has_pe_headers()) {
    @@ -1856,8 +4095,10 @@ int ClientDownloadRequest_ImageHeaders::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->pe_headers());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -1876,6 +4117,7 @@ void ClientDownloadRequest_ImageHeaders::MergeFrom(const ClientDownloadRequest_I
           mutable_pe_headers()->::safe_browsing::ClientDownloadRequest_PEImageHeaders::MergeFrom(from.pe_headers());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest_ImageHeaders::CopyFrom(const ClientDownloadRequest_ImageHeaders& from) {
    @@ -1885,7 +4127,7 @@ void ClientDownloadRequest_ImageHeaders::CopyFrom(const ClientDownloadRequest_Im
     }
     
     bool ClientDownloadRequest_ImageHeaders::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -1893,6 +4135,7 @@ void ClientDownloadRequest_ImageHeaders::Swap(ClientDownloadRequest_ImageHeaders
       if (other != this) {
         std::swap(pe_headers_, other->pe_headers_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -1902,6 +4145,406 @@ void ClientDownloadRequest_ImageHeaders::Swap(ClientDownloadRequest_ImageHeaders
     }
     
     
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientDownloadRequest_ArchivedBinary::kFileBasenameFieldNumber;
    +const int ClientDownloadRequest_ArchivedBinary::kDownloadTypeFieldNumber;
    +const int ClientDownloadRequest_ArchivedBinary::kDigestsFieldNumber;
    +const int ClientDownloadRequest_ArchivedBinary::kLengthFieldNumber;
    +const int ClientDownloadRequest_ArchivedBinary::kSignatureFieldNumber;
    +const int ClientDownloadRequest_ArchivedBinary::kImageHeadersFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientDownloadRequest_ArchivedBinary::ClientDownloadRequest_ArchivedBinary()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  digests_ = const_cast< ::safe_browsing::ClientDownloadRequest_Digests*>(
    +      ::safe_browsing::ClientDownloadRequest_Digests::internal_default_instance());
    +#else
    +  digests_ = const_cast< ::safe_browsing::ClientDownloadRequest_Digests*>(&::safe_browsing::ClientDownloadRequest_Digests::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(
    +      ::safe_browsing::ClientDownloadRequest_SignatureInfo::internal_default_instance());
    +#else
    +  signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(&::safe_browsing::ClientDownloadRequest_SignatureInfo::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(
    +      ::safe_browsing::ClientDownloadRequest_ImageHeaders::internal_default_instance());
    +#else
    +  image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(&::safe_browsing::ClientDownloadRequest_ImageHeaders::default_instance());
    +#endif
    +}
    +
    +ClientDownloadRequest_ArchivedBinary::ClientDownloadRequest_ArchivedBinary(const ClientDownloadRequest_ArchivedBinary& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  download_type_ = 0;
    +  digests_ = NULL;
    +  length_ = GOOGLE_LONGLONG(0);
    +  signature_ = NULL;
    +  image_headers_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientDownloadRequest_ArchivedBinary::~ClientDownloadRequest_ArchivedBinary() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +  SharedDtor();
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::SharedDtor() {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete file_basename_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete digests_;
    +    delete signature_;
    +    delete image_headers_;
    +  }
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientDownloadRequest_ArchivedBinary& ClientDownloadRequest_ArchivedBinary::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientDownloadRequest_ArchivedBinary* ClientDownloadRequest_ArchivedBinary::default_instance_ = NULL;
    +
    +ClientDownloadRequest_ArchivedBinary* ClientDownloadRequest_ArchivedBinary::New() const {
    +  return new ClientDownloadRequest_ArchivedBinary;
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::Clear() {
    +  if (_has_bits_[0 / 32] & 63) {
    +    if (has_file_basename()) {
    +      if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        file_basename_->clear();
    +      }
    +    }
    +    download_type_ = 0;
    +    if (has_digests()) {
    +      if (digests_ != NULL) digests_->::safe_browsing::ClientDownloadRequest_Digests::Clear();
    +    }
    +    length_ = GOOGLE_LONGLONG(0);
    +    if (has_signature()) {
    +      if (signature_ != NULL) signature_->::safe_browsing::ClientDownloadRequest_SignatureInfo::Clear();
    +    }
    +    if (has_image_headers()) {
    +      if (image_headers_ != NULL) image_headers_->::safe_browsing::ClientDownloadRequest_ImageHeaders::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientDownloadRequest_ArchivedBinary::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string file_basename = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_file_basename()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_download_type;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_download_type:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::safe_browsing::ClientDownloadRequest_DownloadType_IsValid(value)) {
    +            set_download_type(static_cast< ::safe_browsing::ClientDownloadRequest_DownloadType >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_digests;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.Digests digests = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_digests:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_digests()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_length;
    +        break;
    +      }
    +
    +      // optional int64 length = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_length:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
    +                 input, &length_)));
    +          set_has_length();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(42)) goto parse_signature;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +      case 5: {
    +        if (tag == 42) {
    +         parse_signature:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_signature()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(50)) goto parse_image_headers;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +      case 6: {
    +        if (tag == 50) {
    +         parse_image_headers:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_image_headers()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +  // optional string file_basename = 1;
    +  if (has_file_basename()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->file_basename(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 2;
    +  if (has_download_type()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      2, this->download_type(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.Digests digests = 3;
    +  if (has_digests()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      3, this->digests(), output);
    +  }
    +
    +  // optional int64 length = 4;
    +  if (has_length()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->length(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +  if (has_signature()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      5, this->signature(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +  if (has_image_headers()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      6, this->image_headers(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    +}
    +
    +int ClientDownloadRequest_ArchivedBinary::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string file_basename = 1;
    +    if (has_file_basename()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->file_basename());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 2;
    +    if (has_download_type()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->download_type());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.Digests digests = 3;
    +    if (has_digests()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->digests());
    +    }
    +
    +    // optional int64 length = 4;
    +    if (has_length()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int64Size(
    +          this->length());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +    if (has_signature()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->signature());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +    if (has_image_headers()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->image_headers());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::MergeFrom(const ClientDownloadRequest_ArchivedBinary& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_file_basename()) {
    +      set_file_basename(from.file_basename());
    +    }
    +    if (from.has_download_type()) {
    +      set_download_type(from.download_type());
    +    }
    +    if (from.has_digests()) {
    +      mutable_digests()->::safe_browsing::ClientDownloadRequest_Digests::MergeFrom(from.digests());
    +    }
    +    if (from.has_length()) {
    +      set_length(from.length());
    +    }
    +    if (from.has_signature()) {
    +      mutable_signature()->::safe_browsing::ClientDownloadRequest_SignatureInfo::MergeFrom(from.signature());
    +    }
    +    if (from.has_image_headers()) {
    +      mutable_image_headers()->::safe_browsing::ClientDownloadRequest_ImageHeaders::MergeFrom(from.image_headers());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::CopyFrom(const ClientDownloadRequest_ArchivedBinary& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientDownloadRequest_ArchivedBinary::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientDownloadRequest_ArchivedBinary::Swap(ClientDownloadRequest_ArchivedBinary* other) {
    +  if (other != this) {
    +    std::swap(file_basename_, other->file_basename_);
    +    std::swap(download_type_, other->download_type_);
    +    std::swap(digests_, other->digests_);
    +    std::swap(length_, other->length_);
    +    std::swap(signature_, other->signature_);
    +    std::swap(image_headers_, other->image_headers_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientDownloadRequest_ArchivedBinary::GetTypeName() const {
    +  return "safe_browsing.ClientDownloadRequest.ArchivedBinary";
    +}
    +
    +
     // -------------------------------------------------------------------
     
     #ifndef _MSC_VER
    @@ -1915,54 +4558,78 @@ const int ClientDownloadRequest::kFileBasenameFieldNumber;
     const int ClientDownloadRequest::kDownloadTypeFieldNumber;
     const int ClientDownloadRequest::kLocaleFieldNumber;
     const int ClientDownloadRequest::kImageHeadersFieldNumber;
    +const int ClientDownloadRequest::kArchivedBinaryFieldNumber;
     #endif  // !_MSC_VER
     
     ClientDownloadRequest::ClientDownloadRequest()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadRequest)
     }
     
     void ClientDownloadRequest::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  digests_ = const_cast< ::safe_browsing::ClientDownloadRequest_Digests*>(
    +      ::safe_browsing::ClientDownloadRequest_Digests::internal_default_instance());
    +#else
       digests_ = const_cast< ::safe_browsing::ClientDownloadRequest_Digests*>(&::safe_browsing::ClientDownloadRequest_Digests::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(
    +      ::safe_browsing::ClientDownloadRequest_SignatureInfo::internal_default_instance());
    +#else
       signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(&::safe_browsing::ClientDownloadRequest_SignatureInfo::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(
    +      ::safe_browsing::ClientDownloadRequest_ImageHeaders::internal_default_instance());
    +#else
       image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(&::safe_browsing::ClientDownloadRequest_ImageHeaders::default_instance());
    +#endif
     }
     
     ClientDownloadRequest::ClientDownloadRequest(const ClientDownloadRequest& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadRequest)
     }
     
     void ClientDownloadRequest::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
    -  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       digests_ = NULL;
       length_ = GOOGLE_LONGLONG(0);
       signature_ = NULL;
       user_initiated_ = false;
    -  file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       download_type_ = 0;
    -  locale_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  locale_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       image_headers_ = NULL;
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadRequest::~ClientDownloadRequest() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadRequest)
       SharedDtor();
     }
     
     void ClientDownloadRequest::SharedDtor() {
    -  if (url_ != &::google::protobuf::internal::kEmptyString) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete url_;
       }
    -  if (file_basename_ != &::google::protobuf::internal::kEmptyString) {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete file_basename_;
       }
    -  if (locale_ != &::google::protobuf::internal::kEmptyString) {
    +  if (locale_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete locale_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
         delete digests_;
         delete signature_;
         delete image_headers_;
    @@ -1975,7 +4642,12 @@ void ClientDownloadRequest::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadRequest& ClientDownloadRequest::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadRequest* ClientDownloadRequest::default_instance_ = NULL;
    @@ -1985,9 +4657,20 @@ ClientDownloadRequest* ClientDownloadRequest::New() const {
     }
     
     void ClientDownloadRequest::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 247) {
    +    ZR_(user_initiated_, download_type_);
         if (has_url()) {
    -      if (url_ != &::google::protobuf::internal::kEmptyString) {
    +      if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             url_->clear();
           }
         }
    @@ -1998,17 +4681,15 @@ void ClientDownloadRequest::Clear() {
         if (has_signature()) {
           if (signature_ != NULL) signature_->::safe_browsing::ClientDownloadRequest_SignatureInfo::Clear();
         }
    -    user_initiated_ = false;
         if (has_file_basename()) {
    -      if (file_basename_ != &::google::protobuf::internal::kEmptyString) {
    +      if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             file_basename_->clear();
           }
         }
    -    download_type_ = 0;
       }
    -  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    +  if (_has_bits_[8 / 32] & 768) {
         if (has_locale()) {
    -      if (locale_ != &::google::protobuf::internal::kEmptyString) {
    +      if (locale_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             locale_->clear();
           }
         }
    @@ -2016,122 +4697,128 @@ void ClientDownloadRequest::Clear() {
           if (image_headers_ != NULL) image_headers_->::safe_browsing::ClientDownloadRequest_ImageHeaders::Clear();
         }
       }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
       resources_.Clear();
    +  archived_binary_.Clear();
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadRequest::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadRequest)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required string url = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                     input, this->mutable_url()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_digests;
             break;
           }
    -      
    +
           // required .safe_browsing.ClientDownloadRequest.Digests digests = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_digests:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_digests()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(24)) goto parse_length;
             break;
           }
    -      
    +
           // required int64 length = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 24) {
              parse_length:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                      input, &length_)));
               set_has_length();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(34)) goto parse_resources;
             break;
           }
    -      
    +
           // repeated .safe_browsing.ClientDownloadRequest.Resource resources = 4;
           case 4: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 34) {
              parse_resources:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                     input, add_resources()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(34)) goto parse_resources;
             if (input->ExpectTag(42)) goto parse_signature;
             break;
           }
    -      
    +
           // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
           case 5: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 42) {
              parse_signature:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_signature()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(48)) goto parse_user_initiated;
             break;
           }
    -      
    +
           // optional bool user_initiated = 6;
           case 6: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 48) {
              parse_user_initiated:
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                      input, &user_initiated_)));
               set_has_user_initiated();
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(74)) goto parse_file_basename;
             break;
           }
    -      
    +
           // optional string file_basename = 9;
           case 9: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 74) {
              parse_file_basename:
               DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                     input, this->mutable_file_basename()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(80)) goto parse_download_type;
             break;
           }
    -      
    +
           // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 10 [default = WIN_EXECUTABLE];
           case 10: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 80) {
              parse_download_type:
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    @@ -2139,122 +4826,154 @@ bool ClientDownloadRequest::MergePartialFromCodedStream(
                      input, &value)));
               if (::safe_browsing::ClientDownloadRequest_DownloadType_IsValid(value)) {
                 set_download_type(static_cast< ::safe_browsing::ClientDownloadRequest_DownloadType >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(90)) goto parse_locale;
             break;
           }
    -      
    +
           // optional string locale = 11;
           case 11: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 90) {
              parse_locale:
               DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                     input, this->mutable_locale()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(146)) goto parse_image_headers;
             break;
           }
    -      
    +
           // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 18;
           case 18: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 146) {
              parse_image_headers:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_image_headers()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectTag(178)) goto parse_archived_binary;
             break;
           }
    -      
    -      default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +
    +      // repeated .safe_browsing.ClientDownloadRequest.ArchivedBinary archived_binary = 22;
    +      case 22: {
    +        if (tag == 178) {
    +         parse_archived_binary:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_archived_binary()));
    +        } else {
    +          goto handle_unusual;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        if (input->ExpectTag(178)) goto parse_archived_binary;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadRequest)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadRequest)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadRequest::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadRequest)
       // required string url = 1;
       if (has_url()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteString(
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
           1, this->url(), output);
       }
    -  
    +
       // required .safe_browsing.ClientDownloadRequest.Digests digests = 2;
       if (has_digests()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           2, this->digests(), output);
       }
    -  
    +
       // required int64 length = 3;
       if (has_length()) {
         ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->length(), output);
       }
    -  
    +
       // repeated .safe_browsing.ClientDownloadRequest.Resource resources = 4;
       for (int i = 0; i < this->resources_size(); i++) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           4, this->resources(i), output);
       }
    -  
    +
       // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
       if (has_signature()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           5, this->signature(), output);
       }
    -  
    +
       // optional bool user_initiated = 6;
       if (has_user_initiated()) {
         ::google::protobuf::internal::WireFormatLite::WriteBool(6, this->user_initiated(), output);
       }
    -  
    +
       // optional string file_basename = 9;
       if (has_file_basename()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteString(
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
           9, this->file_basename(), output);
       }
    -  
    +
       // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 10 [default = WIN_EXECUTABLE];
       if (has_download_type()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           10, this->download_type(), output);
       }
    -  
    +
       // optional string locale = 11;
       if (has_locale()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteString(
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
           11, this->locale(), output);
       }
    -  
    +
       // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 18;
       if (has_image_headers()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           18, this->image_headers(), output);
       }
    -  
    +
    +  // repeated .safe_browsing.ClientDownloadRequest.ArchivedBinary archived_binary = 22;
    +  for (int i = 0; i < this->archived_binary_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      22, this->archived_binary(i), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadRequest)
     }
     
     int ClientDownloadRequest::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required string url = 1;
         if (has_url()) {
    @@ -2262,46 +4981,46 @@ int ClientDownloadRequest::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::StringSize(
               this->url());
         }
    -    
    +
         // required .safe_browsing.ClientDownloadRequest.Digests digests = 2;
         if (has_digests()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->digests());
         }
    -    
    +
         // required int64 length = 3;
         if (has_length()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::Int64Size(
               this->length());
         }
    -    
    +
         // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
         if (has_signature()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->signature());
         }
    -    
    +
         // optional bool user_initiated = 6;
         if (has_user_initiated()) {
           total_size += 1 + 1;
         }
    -    
    +
         // optional string file_basename = 9;
         if (has_file_basename()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::StringSize(
               this->file_basename());
         }
    -    
    +
         // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 10 [default = WIN_EXECUTABLE];
         if (has_download_type()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->download_type());
         }
    -    
    +
       }
       if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
         // optional string locale = 11;
    @@ -2310,14 +5029,14 @@ int ClientDownloadRequest::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::StringSize(
               this->locale());
         }
    -    
    +
         // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 18;
         if (has_image_headers()) {
           total_size += 2 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->image_headers());
         }
    -    
    +
       }
       // repeated .safe_browsing.ClientDownloadRequest.Resource resources = 4;
       total_size += 1 * this->resources_size();
    @@ -2326,7 +5045,17 @@ int ClientDownloadRequest::ByteSize() const {
           ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
             this->resources(i));
       }
    -  
    +
    +  // repeated .safe_browsing.ClientDownloadRequest.ArchivedBinary archived_binary = 22;
    +  total_size += 2 * this->archived_binary_size();
    +  for (int i = 0; i < this->archived_binary_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->archived_binary(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -2341,6 +5070,7 @@ void ClientDownloadRequest::CheckTypeAndMergeFrom(
     void ClientDownloadRequest::MergeFrom(const ClientDownloadRequest& from) {
       GOOGLE_CHECK_NE(&from, this);
       resources_.MergeFrom(from.resources_);
    +  archived_binary_.MergeFrom(from.archived_binary_);
       if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         if (from.has_url()) {
           set_url(from.url());
    @@ -2372,6 +5102,7 @@ void ClientDownloadRequest::MergeFrom(const ClientDownloadRequest& from) {
           mutable_image_headers()->::safe_browsing::ClientDownloadRequest_ImageHeaders::MergeFrom(from.image_headers());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadRequest::CopyFrom(const ClientDownloadRequest& from) {
    @@ -2382,10 +5113,8 @@ void ClientDownloadRequest::CopyFrom(const ClientDownloadRequest& from) {
     
     bool ClientDownloadRequest::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;
    -  
    -  for (int i = 0; i < resources_size(); i++) {
    -    if (!this->resources(i).IsInitialized()) return false;
    -  }
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->resources())) return false;
       return true;
     }
     
    @@ -2401,7 +5130,9 @@ void ClientDownloadRequest::Swap(ClientDownloadRequest* other) {
         std::swap(download_type_, other->download_type_);
         std::swap(locale_, other->locale_);
         std::swap(image_headers_, other->image_headers_);
    +    archived_binary_.Swap(&other->archived_binary_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -2444,6 +5175,7 @@ const int ClientDownloadResponse_MoreInfo::kUrlFieldNumber;
     ClientDownloadResponse_MoreInfo::ClientDownloadResponse_MoreInfo()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadResponse.MoreInfo)
     }
     
     void ClientDownloadResponse_MoreInfo::InitAsDefaultInstance() {
    @@ -2453,27 +5185,34 @@ ClientDownloadResponse_MoreInfo::ClientDownloadResponse_MoreInfo(const ClientDow
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadResponse.MoreInfo)
     }
     
     void ClientDownloadResponse_MoreInfo::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
    -  description_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    -  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  description_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadResponse_MoreInfo::~ClientDownloadResponse_MoreInfo() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadResponse.MoreInfo)
       SharedDtor();
     }
     
     void ClientDownloadResponse_MoreInfo::SharedDtor() {
    -  if (description_ != &::google::protobuf::internal::kEmptyString) {
    +  if (description_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete description_;
       }
    -  if (url_ != &::google::protobuf::internal::kEmptyString) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete url_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
       }
     }
     
    @@ -2483,7 +5222,12 @@ void ClientDownloadResponse_MoreInfo::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadResponse_MoreInfo& ClientDownloadResponse_MoreInfo::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadResponse_MoreInfo* ClientDownloadResponse_MoreInfo::default_instance_ = NULL;
    @@ -2493,88 +5237,106 @@ ClientDownloadResponse_MoreInfo* ClientDownloadResponse_MoreInfo::New() const {
     }
     
     void ClientDownloadResponse_MoreInfo::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 3) {
         if (has_description()) {
    -      if (description_ != &::google::protobuf::internal::kEmptyString) {
    +      if (description_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             description_->clear();
           }
         }
         if (has_url()) {
    -      if (url_ != &::google::protobuf::internal::kEmptyString) {
    +      if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             url_->clear();
           }
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadResponse_MoreInfo::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadResponse.MoreInfo)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // optional string description = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 10) {
               DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                     input, this->mutable_description()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_url;
             break;
           }
    -      
    +
           // optional string url = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_url:
               DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                     input, this->mutable_url()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadResponse.MoreInfo)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadResponse.MoreInfo)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadResponse_MoreInfo::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadResponse.MoreInfo)
       // optional string description = 1;
       if (has_description()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteString(
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
           1, this->description(), output);
       }
    -  
    +
       // optional string url = 2;
       if (has_url()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteString(
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
           2, this->url(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadResponse.MoreInfo)
     }
     
     int ClientDownloadResponse_MoreInfo::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // optional string description = 1;
         if (has_description()) {
    @@ -2582,15 +5344,17 @@ int ClientDownloadResponse_MoreInfo::ByteSize() const {
             ::google::protobuf::internal::WireFormatLite::StringSize(
               this->description());
         }
    -    
    +
         // optional string url = 2;
         if (has_url()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::StringSize(
               this->url());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -2612,6 +5376,7 @@ void ClientDownloadResponse_MoreInfo::MergeFrom(const ClientDownloadResponse_Mor
           set_url(from.url());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadResponse_MoreInfo::CopyFrom(const ClientDownloadResponse_MoreInfo& from) {
    @@ -2621,7 +5386,7 @@ void ClientDownloadResponse_MoreInfo::CopyFrom(const ClientDownloadResponse_More
     }
     
     bool ClientDownloadResponse_MoreInfo::IsInitialized() const {
    -  
    +
       return true;
     }
     
    @@ -2630,6 +5395,7 @@ void ClientDownloadResponse_MoreInfo::Swap(ClientDownloadResponse_MoreInfo* othe
         std::swap(description_, other->description_);
         std::swap(url_, other->url_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -2650,35 +5416,48 @@ const int ClientDownloadResponse::kTokenFieldNumber;
     ClientDownloadResponse::ClientDownloadResponse()
       : ::google::protobuf::MessageLite() {
       SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadResponse)
     }
     
     void ClientDownloadResponse::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  more_info_ = const_cast< ::safe_browsing::ClientDownloadResponse_MoreInfo*>(
    +      ::safe_browsing::ClientDownloadResponse_MoreInfo::internal_default_instance());
    +#else
       more_info_ = const_cast< ::safe_browsing::ClientDownloadResponse_MoreInfo*>(&::safe_browsing::ClientDownloadResponse_MoreInfo::default_instance());
    +#endif
     }
     
     ClientDownloadResponse::ClientDownloadResponse(const ClientDownloadResponse& from)
       : ::google::protobuf::MessageLite() {
       SharedCtor();
       MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadResponse)
     }
     
     void ClientDownloadResponse::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
       _cached_size_ = 0;
       verdict_ = 0;
       more_info_ = NULL;
    -  token_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +  token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
     }
     
     ClientDownloadResponse::~ClientDownloadResponse() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadResponse)
       SharedDtor();
     }
     
     void ClientDownloadResponse::SharedDtor() {
    -  if (token_ != &::google::protobuf::internal::kEmptyString) {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         delete token_;
       }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
       if (this != default_instance_) {
    +  #endif
         delete more_info_;
       }
     }
    @@ -2689,7 +5468,12 @@ void ClientDownloadResponse::SetCachedSize(int size) const {
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
     }
     const ClientDownloadResponse& ClientDownloadResponse::default_instance() {
    -  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();  return *default_instance_;
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
     }
     
     ClientDownloadResponse* ClientDownloadResponse::default_instance_ = NULL;
    @@ -2699,134 +5483,156 @@ ClientDownloadResponse* ClientDownloadResponse::New() const {
     }
     
     void ClientDownloadResponse::Clear() {
    -  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +  if (_has_bits_[0 / 32] & 7) {
         verdict_ = 0;
         if (has_more_info()) {
           if (more_info_ != NULL) more_info_->::safe_browsing::ClientDownloadResponse_MoreInfo::Clear();
         }
         if (has_token()) {
    -      if (token_ != &::google::protobuf::internal::kEmptyString) {
    +      if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
             token_->clear();
           }
         }
       }
       ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
     }
     
     bool ClientDownloadResponse::MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) {
    -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
       ::google::protobuf::uint32 tag;
    -  while ((tag = input->ReadTag()) != 0) {
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadResponse)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
         switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
           // required .safe_browsing.ClientDownloadResponse.Verdict verdict = 1;
           case 1: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
    +        if (tag == 8) {
               int value;
               DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                      input, &value)));
               if (::safe_browsing::ClientDownloadResponse_Verdict_IsValid(value)) {
                 set_verdict(static_cast< ::safe_browsing::ClientDownloadResponse_Verdict >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
               }
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(18)) goto parse_more_info;
             break;
           }
    -      
    +
           // optional .safe_browsing.ClientDownloadResponse.MoreInfo more_info = 2;
           case 2: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 18) {
              parse_more_info:
               DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                    input, mutable_more_info()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
             if (input->ExpectTag(26)) goto parse_token;
             break;
           }
    -      
    +
           // optional bytes token = 3;
           case 3: {
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    -            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +        if (tag == 26) {
              parse_token:
               DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                     input, this->mutable_token()));
             } else {
    -          goto handle_uninterpreted;
    +          goto handle_unusual;
             }
    -        if (input->ExpectAtEnd()) return true;
    +        if (input->ExpectAtEnd()) goto success;
             break;
           }
    -      
    +
           default: {
    -      handle_uninterpreted:
    -        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
                 ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    -          return true;
    +          goto success;
             }
    -        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
             break;
           }
         }
       }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadResponse)
       return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadResponse)
    +  return false;
     #undef DO_
     }
     
     void ClientDownloadResponse::SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadResponse)
       // required .safe_browsing.ClientDownloadResponse.Verdict verdict = 1;
       if (has_verdict()) {
         ::google::protobuf::internal::WireFormatLite::WriteEnum(
           1, this->verdict(), output);
       }
    -  
    +
       // optional .safe_browsing.ClientDownloadResponse.MoreInfo more_info = 2;
       if (has_more_info()) {
         ::google::protobuf::internal::WireFormatLite::WriteMessage(
           2, this->more_info(), output);
       }
    -  
    +
       // optional bytes token = 3;
       if (has_token()) {
    -    ::google::protobuf::internal::WireFormatLite::WriteBytes(
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
           3, this->token(), output);
       }
    -  
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadResponse)
     }
     
     int ClientDownloadResponse::ByteSize() const {
       int total_size = 0;
    -  
    +
       if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
         // required .safe_browsing.ClientDownloadResponse.Verdict verdict = 1;
         if (has_verdict()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::EnumSize(this->verdict());
         }
    -    
    +
         // optional .safe_browsing.ClientDownloadResponse.MoreInfo more_info = 2;
         if (has_more_info()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
               this->more_info());
         }
    -    
    +
         // optional bytes token = 3;
         if (has_token()) {
           total_size += 1 +
             ::google::protobuf::internal::WireFormatLite::BytesSize(
               this->token());
         }
    -    
    +
       }
    +  total_size += unknown_fields().size();
    +
       GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
       _cached_size_ = total_size;
       GOOGLE_SAFE_CONCURRENT_WRITES_END();
    @@ -2851,6 +5657,7 @@ void ClientDownloadResponse::MergeFrom(const ClientDownloadResponse& from) {
           set_token(from.token());
         }
       }
    +  mutable_unknown_fields()->append(from.unknown_fields());
     }
     
     void ClientDownloadResponse::CopyFrom(const ClientDownloadResponse& from) {
    @@ -2861,7 +5668,7 @@ void ClientDownloadResponse::CopyFrom(const ClientDownloadResponse& from) {
     
     bool ClientDownloadResponse::IsInitialized() const {
       if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false;
    -  
    +
       return true;
     }
     
    @@ -2871,6 +5678,7 @@ void ClientDownloadResponse::Swap(ClientDownloadResponse* other) {
         std::swap(more_info_, other->more_info_);
         std::swap(token_, other->token_);
         std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
         std::swap(_cached_size_, other->_cached_size_);
       }
     }
    @@ -2880,6 +5688,6380 @@ void ClientDownloadResponse::Swap(ClientDownloadResponse* other) {
     }
     
     
    +// ===================================================================
    +
    +bool ClientDownloadReport_Reason_IsValid(int value) {
    +  switch(value) {
    +    case 0:
    +    case 1:
    +    case 2:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const ClientDownloadReport_Reason ClientDownloadReport::SHARE;
    +const ClientDownloadReport_Reason ClientDownloadReport::FALSE_POSITIVE;
    +const ClientDownloadReport_Reason ClientDownloadReport::APPEAL;
    +const ClientDownloadReport_Reason ClientDownloadReport::Reason_MIN;
    +const ClientDownloadReport_Reason ClientDownloadReport::Reason_MAX;
    +const int ClientDownloadReport::Reason_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int ClientDownloadReport_UserInformation::kEmailFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientDownloadReport_UserInformation::ClientDownloadReport_UserInformation()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadReport.UserInformation)
    +}
    +
    +void ClientDownloadReport_UserInformation::InitAsDefaultInstance() {
    +}
    +
    +ClientDownloadReport_UserInformation::ClientDownloadReport_UserInformation(const ClientDownloadReport_UserInformation& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadReport.UserInformation)
    +}
    +
    +void ClientDownloadReport_UserInformation::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  email_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientDownloadReport_UserInformation::~ClientDownloadReport_UserInformation() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadReport.UserInformation)
    +  SharedDtor();
    +}
    +
    +void ClientDownloadReport_UserInformation::SharedDtor() {
    +  if (email_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete email_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientDownloadReport_UserInformation::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientDownloadReport_UserInformation& ClientDownloadReport_UserInformation::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientDownloadReport_UserInformation* ClientDownloadReport_UserInformation::default_instance_ = NULL;
    +
    +ClientDownloadReport_UserInformation* ClientDownloadReport_UserInformation::New() const {
    +  return new ClientDownloadReport_UserInformation;
    +}
    +
    +void ClientDownloadReport_UserInformation::Clear() {
    +  if (has_email()) {
    +    if (email_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +      email_->clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientDownloadReport_UserInformation::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadReport.UserInformation)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string email = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_email()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadReport.UserInformation)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadReport.UserInformation)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientDownloadReport_UserInformation::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadReport.UserInformation)
    +  // optional string email = 1;
    +  if (has_email()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->email(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadReport.UserInformation)
    +}
    +
    +int ClientDownloadReport_UserInformation::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string email = 1;
    +    if (has_email()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->email());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientDownloadReport_UserInformation::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientDownloadReport_UserInformation::MergeFrom(const ClientDownloadReport_UserInformation& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_email()) {
    +      set_email(from.email());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientDownloadReport_UserInformation::CopyFrom(const ClientDownloadReport_UserInformation& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientDownloadReport_UserInformation::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientDownloadReport_UserInformation::Swap(ClientDownloadReport_UserInformation* other) {
    +  if (other != this) {
    +    std::swap(email_, other->email_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientDownloadReport_UserInformation::GetTypeName() const {
    +  return "safe_browsing.ClientDownloadReport.UserInformation";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientDownloadReport::kReasonFieldNumber;
    +const int ClientDownloadReport::kDownloadRequestFieldNumber;
    +const int ClientDownloadReport::kUserInformationFieldNumber;
    +const int ClientDownloadReport::kCommentFieldNumber;
    +const int ClientDownloadReport::kDownloadResponseFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientDownloadReport::ClientDownloadReport()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientDownloadReport)
    +}
    +
    +void ClientDownloadReport::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  download_request_ = const_cast< ::safe_browsing::ClientDownloadRequest*>(
    +      ::safe_browsing::ClientDownloadRequest::internal_default_instance());
    +#else
    +  download_request_ = const_cast< ::safe_browsing::ClientDownloadRequest*>(&::safe_browsing::ClientDownloadRequest::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  user_information_ = const_cast< ::safe_browsing::ClientDownloadReport_UserInformation*>(
    +      ::safe_browsing::ClientDownloadReport_UserInformation::internal_default_instance());
    +#else
    +  user_information_ = const_cast< ::safe_browsing::ClientDownloadReport_UserInformation*>(&::safe_browsing::ClientDownloadReport_UserInformation::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  download_response_ = const_cast< ::safe_browsing::ClientDownloadResponse*>(
    +      ::safe_browsing::ClientDownloadResponse::internal_default_instance());
    +#else
    +  download_response_ = const_cast< ::safe_browsing::ClientDownloadResponse*>(&::safe_browsing::ClientDownloadResponse::default_instance());
    +#endif
    +}
    +
    +ClientDownloadReport::ClientDownloadReport(const ClientDownloadReport& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientDownloadReport)
    +}
    +
    +void ClientDownloadReport::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  reason_ = 0;
    +  download_request_ = NULL;
    +  user_information_ = NULL;
    +  comment_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  download_response_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientDownloadReport::~ClientDownloadReport() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientDownloadReport)
    +  SharedDtor();
    +}
    +
    +void ClientDownloadReport::SharedDtor() {
    +  if (comment_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete comment_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete download_request_;
    +    delete user_information_;
    +    delete download_response_;
    +  }
    +}
    +
    +void ClientDownloadReport::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientDownloadReport& ClientDownloadReport::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientDownloadReport* ClientDownloadReport::default_instance_ = NULL;
    +
    +ClientDownloadReport* ClientDownloadReport::New() const {
    +  return new ClientDownloadReport;
    +}
    +
    +void ClientDownloadReport::Clear() {
    +  if (_has_bits_[0 / 32] & 31) {
    +    reason_ = 0;
    +    if (has_download_request()) {
    +      if (download_request_ != NULL) download_request_->::safe_browsing::ClientDownloadRequest::Clear();
    +    }
    +    if (has_user_information()) {
    +      if (user_information_ != NULL) user_information_->::safe_browsing::ClientDownloadReport_UserInformation::Clear();
    +    }
    +    if (has_comment()) {
    +      if (comment_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        comment_->clear();
    +      }
    +    }
    +    if (has_download_response()) {
    +      if (download_response_ != NULL) download_response_->::safe_browsing::ClientDownloadResponse::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientDownloadReport::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientDownloadReport)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional .safe_browsing.ClientDownloadReport.Reason reason = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::safe_browsing::ClientDownloadReport_Reason_IsValid(value)) {
    +            set_reason(static_cast< ::safe_browsing::ClientDownloadReport_Reason >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_download_request;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest download_request = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_download_request:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_download_request()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_user_information;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadReport.UserInformation user_information = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_user_information:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_user_information()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_comment;
    +        break;
    +      }
    +
    +      // optional bytes comment = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_comment:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
    +                input, this->mutable_comment()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(42)) goto parse_download_response;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadResponse download_response = 5;
    +      case 5: {
    +        if (tag == 42) {
    +         parse_download_response:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_download_response()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientDownloadReport)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientDownloadReport)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientDownloadReport::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientDownloadReport)
    +  // optional .safe_browsing.ClientDownloadReport.Reason reason = 1;
    +  if (has_reason()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      1, this->reason(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest download_request = 2;
    +  if (has_download_request()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->download_request(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadReport.UserInformation user_information = 3;
    +  if (has_user_information()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      3, this->user_information(), output);
    +  }
    +
    +  // optional bytes comment = 4;
    +  if (has_comment()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
    +      4, this->comment(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadResponse download_response = 5;
    +  if (has_download_response()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      5, this->download_response(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientDownloadReport)
    +}
    +
    +int ClientDownloadReport::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional .safe_browsing.ClientDownloadReport.Reason reason = 1;
    +    if (has_reason()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest download_request = 2;
    +    if (has_download_request()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->download_request());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadReport.UserInformation user_information = 3;
    +    if (has_user_information()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->user_information());
    +    }
    +
    +    // optional bytes comment = 4;
    +    if (has_comment()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::BytesSize(
    +          this->comment());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadResponse download_response = 5;
    +    if (has_download_response()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->download_response());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientDownloadReport::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientDownloadReport::MergeFrom(const ClientDownloadReport& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_reason()) {
    +      set_reason(from.reason());
    +    }
    +    if (from.has_download_request()) {
    +      mutable_download_request()->::safe_browsing::ClientDownloadRequest::MergeFrom(from.download_request());
    +    }
    +    if (from.has_user_information()) {
    +      mutable_user_information()->::safe_browsing::ClientDownloadReport_UserInformation::MergeFrom(from.user_information());
    +    }
    +    if (from.has_comment()) {
    +      set_comment(from.comment());
    +    }
    +    if (from.has_download_response()) {
    +      mutable_download_response()->::safe_browsing::ClientDownloadResponse::MergeFrom(from.download_response());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientDownloadReport::CopyFrom(const ClientDownloadReport& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientDownloadReport::IsInitialized() const {
    +
    +  if (has_download_request()) {
    +    if (!this->download_request().IsInitialized()) return false;
    +  }
    +  if (has_download_response()) {
    +    if (!this->download_response().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void ClientDownloadReport::Swap(ClientDownloadReport* other) {
    +  if (other != this) {
    +    std::swap(reason_, other->reason_);
    +    std::swap(download_request_, other->download_request_);
    +    std::swap(user_information_, other->user_information_);
    +    std::swap(comment_, other->comment_);
    +    std::swap(download_response_, other->download_response_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientDownloadReport::GetTypeName() const {
    +  return "safe_browsing.ClientDownloadReport";
    +}
    +
    +
    +// ===================================================================
    +
    +bool ClientUploadResponse_UploadStatus_IsValid(int value) {
    +  switch(value) {
    +    case 0:
    +    case 1:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const ClientUploadResponse_UploadStatus ClientUploadResponse::SUCCESS;
    +const ClientUploadResponse_UploadStatus ClientUploadResponse::UPLOAD_FAILURE;
    +const ClientUploadResponse_UploadStatus ClientUploadResponse::UploadStatus_MIN;
    +const ClientUploadResponse_UploadStatus ClientUploadResponse::UploadStatus_MAX;
    +const int ClientUploadResponse::UploadStatus_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int ClientUploadResponse::kStatusFieldNumber;
    +const int ClientUploadResponse::kPermalinkFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientUploadResponse::ClientUploadResponse()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientUploadResponse)
    +}
    +
    +void ClientUploadResponse::InitAsDefaultInstance() {
    +}
    +
    +ClientUploadResponse::ClientUploadResponse(const ClientUploadResponse& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientUploadResponse)
    +}
    +
    +void ClientUploadResponse::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  status_ = 0;
    +  permalink_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientUploadResponse::~ClientUploadResponse() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientUploadResponse)
    +  SharedDtor();
    +}
    +
    +void ClientUploadResponse::SharedDtor() {
    +  if (permalink_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete permalink_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientUploadResponse::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientUploadResponse& ClientUploadResponse::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientUploadResponse* ClientUploadResponse::default_instance_ = NULL;
    +
    +ClientUploadResponse* ClientUploadResponse::New() const {
    +  return new ClientUploadResponse;
    +}
    +
    +void ClientUploadResponse::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    status_ = 0;
    +    if (has_permalink()) {
    +      if (permalink_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        permalink_->clear();
    +      }
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientUploadResponse::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientUploadResponse)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional .safe_browsing.ClientUploadResponse.UploadStatus status = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::safe_browsing::ClientUploadResponse_UploadStatus_IsValid(value)) {
    +            set_status(static_cast< ::safe_browsing::ClientUploadResponse_UploadStatus >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_permalink;
    +        break;
    +      }
    +
    +      // optional string permalink = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_permalink:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_permalink()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientUploadResponse)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientUploadResponse)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientUploadResponse::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientUploadResponse)
    +  // optional .safe_browsing.ClientUploadResponse.UploadStatus status = 1;
    +  if (has_status()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      1, this->status(), output);
    +  }
    +
    +  // optional string permalink = 2;
    +  if (has_permalink()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->permalink(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientUploadResponse)
    +}
    +
    +int ClientUploadResponse::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional .safe_browsing.ClientUploadResponse.UploadStatus status = 1;
    +    if (has_status()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
    +    }
    +
    +    // optional string permalink = 2;
    +    if (has_permalink()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->permalink());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientUploadResponse::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientUploadResponse::MergeFrom(const ClientUploadResponse& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_status()) {
    +      set_status(from.status());
    +    }
    +    if (from.has_permalink()) {
    +      set_permalink(from.permalink());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientUploadResponse::CopyFrom(const ClientUploadResponse& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientUploadResponse::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientUploadResponse::Swap(ClientUploadResponse* other) {
    +  if (other != this) {
    +    std::swap(status_, other->status_);
    +    std::swap(permalink_, other->permalink_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientUploadResponse::GetTypeName() const {
    +  return "safe_browsing.ClientUploadResponse";
    +}
    +
    +
    +// ===================================================================
    +
    +bool ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_IsValid(int value) {
    +  switch(value) {
    +    case 0:
    +    case 1:
    +    case 2:
    +    case 3:
    +    case 4:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::UNKNOWN;
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::CLEARED;
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::WEAK_LEGACY_OBSOLETE;
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::CHANGED;
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::UNTRUSTED_UNKNOWN_VALUE;
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::ValueState_MIN;
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::ValueState_MAX;
    +const int ClientIncidentReport_IncidentData_TrackedPreferenceIncident::ValueState_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_IncidentData_TrackedPreferenceIncident::kPathFieldNumber;
    +const int ClientIncidentReport_IncidentData_TrackedPreferenceIncident::kAtomicValueFieldNumber;
    +const int ClientIncidentReport_IncidentData_TrackedPreferenceIncident::kSplitKeyFieldNumber;
    +const int ClientIncidentReport_IncidentData_TrackedPreferenceIncident::kValueStateFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_IncidentData_TrackedPreferenceIncident::ClientIncidentReport_IncidentData_TrackedPreferenceIncident()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_IncidentData_TrackedPreferenceIncident::ClientIncidentReport_IncidentData_TrackedPreferenceIncident(const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  atomic_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  value_state_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_IncidentData_TrackedPreferenceIncident::~ClientIncidentReport_IncidentData_TrackedPreferenceIncident() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::SharedDtor() {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete path_;
    +  }
    +  if (atomic_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete atomic_value_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& ClientIncidentReport_IncidentData_TrackedPreferenceIncident::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_IncidentData_TrackedPreferenceIncident* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::default_instance_ = NULL;
    +
    +ClientIncidentReport_IncidentData_TrackedPreferenceIncident* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::New() const {
    +  return new ClientIncidentReport_IncidentData_TrackedPreferenceIncident;
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::Clear() {
    +  if (_has_bits_[0 / 32] & 11) {
    +    if (has_path()) {
    +      if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        path_->clear();
    +      }
    +    }
    +    if (has_atomic_value()) {
    +      if (atomic_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        atomic_value_->clear();
    +      }
    +    }
    +    value_state_ = 0;
    +  }
    +  split_key_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_IncidentData_TrackedPreferenceIncident::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string path = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_path()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_atomic_value;
    +        break;
    +      }
    +
    +      // optional string atomic_value = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_atomic_value:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_atomic_value()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_split_key;
    +        break;
    +      }
    +
    +      // repeated string split_key = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_split_key:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->add_split_key()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_split_key;
    +        if (input->ExpectTag(32)) goto parse_value_state;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.ValueState value_state = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_value_state:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_IsValid(value)) {
    +            set_value_state(static_cast< ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +  // optional string path = 1;
    +  if (has_path()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->path(), output);
    +  }
    +
    +  // optional string atomic_value = 2;
    +  if (has_atomic_value()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->atomic_value(), output);
    +  }
    +
    +  // repeated string split_key = 3;
    +  for (int i = 0; i < this->split_key_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteString(
    +      3, this->split_key(i), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.ValueState value_state = 4;
    +  if (has_value_state()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      4, this->value_state(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    +}
    +
    +int ClientIncidentReport_IncidentData_TrackedPreferenceIncident::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string path = 1;
    +    if (has_path()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->path());
    +    }
    +
    +    // optional string atomic_value = 2;
    +    if (has_atomic_value()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->atomic_value());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.ValueState value_state = 4;
    +    if (has_value_state()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->value_state());
    +    }
    +
    +  }
    +  // repeated string split_key = 3;
    +  total_size += 1 * this->split_key_size();
    +  for (int i = 0; i < this->split_key_size(); i++) {
    +    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
    +      this->split_key(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::MergeFrom(const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  split_key_.MergeFrom(from.split_key_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_path()) {
    +      set_path(from.path());
    +    }
    +    if (from.has_atomic_value()) {
    +      set_atomic_value(from.atomic_value());
    +    }
    +    if (from.has_value_state()) {
    +      set_value_state(from.value_state());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::CopyFrom(const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_IncidentData_TrackedPreferenceIncident::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::Swap(ClientIncidentReport_IncidentData_TrackedPreferenceIncident* other) {
    +  if (other != this) {
    +    std::swap(path_, other->path_);
    +    std::swap(atomic_value_, other->atomic_value_);
    +    split_key_.Swap(&other->split_key_);
    +    std::swap(value_state_, other->value_state_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_IncidentData_TrackedPreferenceIncident::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_IncidentData_BinaryIntegrityIncident::kFileBasenameFieldNumber;
    +const int ClientIncidentReport_IncidentData_BinaryIntegrityIncident::kSignatureFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_IncidentData_BinaryIntegrityIncident::ClientIncidentReport_IncidentData_BinaryIntegrityIncident()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(
    +      ::safe_browsing::ClientDownloadRequest_SignatureInfo::internal_default_instance());
    +#else
    +  signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(&::safe_browsing::ClientDownloadRequest_SignatureInfo::default_instance());
    +#endif
    +}
    +
    +ClientIncidentReport_IncidentData_BinaryIntegrityIncident::ClientIncidentReport_IncidentData_BinaryIntegrityIncident(const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  signature_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_IncidentData_BinaryIntegrityIncident::~ClientIncidentReport_IncidentData_BinaryIntegrityIncident() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::SharedDtor() {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete file_basename_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete signature_;
    +  }
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& ClientIncidentReport_IncidentData_BinaryIntegrityIncident::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_IncidentData_BinaryIntegrityIncident* ClientIncidentReport_IncidentData_BinaryIntegrityIncident::default_instance_ = NULL;
    +
    +ClientIncidentReport_IncidentData_BinaryIntegrityIncident* ClientIncidentReport_IncidentData_BinaryIntegrityIncident::New() const {
    +  return new ClientIncidentReport_IncidentData_BinaryIntegrityIncident;
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_file_basename()) {
    +      if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        file_basename_->clear();
    +      }
    +    }
    +    if (has_signature()) {
    +      if (signature_ != NULL) signature_->::safe_browsing::ClientDownloadRequest_SignatureInfo::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_IncidentData_BinaryIntegrityIncident::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string file_basename = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_file_basename()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_signature;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_signature:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_signature()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +  // optional string file_basename = 1;
    +  if (has_file_basename()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->file_basename(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 2;
    +  if (has_signature()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->signature(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    +}
    +
    +int ClientIncidentReport_IncidentData_BinaryIntegrityIncident::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string file_basename = 1;
    +    if (has_file_basename()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->file_basename());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 2;
    +    if (has_signature()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->signature());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::MergeFrom(const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_file_basename()) {
    +      set_file_basename(from.file_basename());
    +    }
    +    if (from.has_signature()) {
    +      mutable_signature()->::safe_browsing::ClientDownloadRequest_SignatureInfo::MergeFrom(from.signature());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::CopyFrom(const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_IncidentData_BinaryIntegrityIncident::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::Swap(ClientIncidentReport_IncidentData_BinaryIntegrityIncident* other) {
    +  if (other != this) {
    +    std::swap(file_basename_, other->file_basename_);
    +    std::swap(signature_, other->signature_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_IncidentData_BinaryIntegrityIncident::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_IncidentData_BlacklistLoadIncident::kPathFieldNumber;
    +const int ClientIncidentReport_IncidentData_BlacklistLoadIncident::kDigestFieldNumber;
    +const int ClientIncidentReport_IncidentData_BlacklistLoadIncident::kVersionFieldNumber;
    +const int ClientIncidentReport_IncidentData_BlacklistLoadIncident::kBlacklistInitializedFieldNumber;
    +const int ClientIncidentReport_IncidentData_BlacklistLoadIncident::kSignatureFieldNumber;
    +const int ClientIncidentReport_IncidentData_BlacklistLoadIncident::kImageHeadersFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_IncidentData_BlacklistLoadIncident::ClientIncidentReport_IncidentData_BlacklistLoadIncident()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  digest_ = const_cast< ::safe_browsing::ClientDownloadRequest_Digests*>(
    +      ::safe_browsing::ClientDownloadRequest_Digests::internal_default_instance());
    +#else
    +  digest_ = const_cast< ::safe_browsing::ClientDownloadRequest_Digests*>(&::safe_browsing::ClientDownloadRequest_Digests::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(
    +      ::safe_browsing::ClientDownloadRequest_SignatureInfo::internal_default_instance());
    +#else
    +  signature_ = const_cast< ::safe_browsing::ClientDownloadRequest_SignatureInfo*>(&::safe_browsing::ClientDownloadRequest_SignatureInfo::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(
    +      ::safe_browsing::ClientDownloadRequest_ImageHeaders::internal_default_instance());
    +#else
    +  image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(&::safe_browsing::ClientDownloadRequest_ImageHeaders::default_instance());
    +#endif
    +}
    +
    +ClientIncidentReport_IncidentData_BlacklistLoadIncident::ClientIncidentReport_IncidentData_BlacklistLoadIncident(const ClientIncidentReport_IncidentData_BlacklistLoadIncident& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  digest_ = NULL;
    +  version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  blacklist_initialized_ = false;
    +  signature_ = NULL;
    +  image_headers_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_IncidentData_BlacklistLoadIncident::~ClientIncidentReport_IncidentData_BlacklistLoadIncident() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::SharedDtor() {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete path_;
    +  }
    +  if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete version_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete digest_;
    +    delete signature_;
    +    delete image_headers_;
    +  }
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_IncidentData_BlacklistLoadIncident& ClientIncidentReport_IncidentData_BlacklistLoadIncident::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_IncidentData_BlacklistLoadIncident* ClientIncidentReport_IncidentData_BlacklistLoadIncident::default_instance_ = NULL;
    +
    +ClientIncidentReport_IncidentData_BlacklistLoadIncident* ClientIncidentReport_IncidentData_BlacklistLoadIncident::New() const {
    +  return new ClientIncidentReport_IncidentData_BlacklistLoadIncident;
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::Clear() {
    +  if (_has_bits_[0 / 32] & 63) {
    +    if (has_path()) {
    +      if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        path_->clear();
    +      }
    +    }
    +    if (has_digest()) {
    +      if (digest_ != NULL) digest_->::safe_browsing::ClientDownloadRequest_Digests::Clear();
    +    }
    +    if (has_version()) {
    +      if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        version_->clear();
    +      }
    +    }
    +    blacklist_initialized_ = false;
    +    if (has_signature()) {
    +      if (signature_ != NULL) signature_->::safe_browsing::ClientDownloadRequest_SignatureInfo::Clear();
    +    }
    +    if (has_image_headers()) {
    +      if (image_headers_ != NULL) image_headers_->::safe_browsing::ClientDownloadRequest_ImageHeaders::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string path = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_path()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_digest;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.Digests digest = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_digest:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_digest()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_version;
    +        break;
    +      }
    +
    +      // optional string version = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_version:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_version()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_blacklist_initialized;
    +        break;
    +      }
    +
    +      // optional bool blacklist_initialized = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_blacklist_initialized:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &blacklist_initialized_)));
    +          set_has_blacklist_initialized();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(42)) goto parse_signature;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +      case 5: {
    +        if (tag == 42) {
    +         parse_signature:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_signature()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(50)) goto parse_image_headers;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +      case 6: {
    +        if (tag == 50) {
    +         parse_image_headers:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_image_headers()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +  // optional string path = 1;
    +  if (has_path()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->path(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.Digests digest = 2;
    +  if (has_digest()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->digest(), output);
    +  }
    +
    +  // optional string version = 3;
    +  if (has_version()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      3, this->version(), output);
    +  }
    +
    +  // optional bool blacklist_initialized = 4;
    +  if (has_blacklist_initialized()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->blacklist_initialized(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +  if (has_signature()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      5, this->signature(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +  if (has_image_headers()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      6, this->image_headers(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    +}
    +
    +int ClientIncidentReport_IncidentData_BlacklistLoadIncident::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string path = 1;
    +    if (has_path()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->path());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.Digests digest = 2;
    +    if (has_digest()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->digest());
    +    }
    +
    +    // optional string version = 3;
    +    if (has_version()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->version());
    +    }
    +
    +    // optional bool blacklist_initialized = 4;
    +    if (has_blacklist_initialized()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +    if (has_signature()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->signature());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +    if (has_image_headers()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->image_headers());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::MergeFrom(const ClientIncidentReport_IncidentData_BlacklistLoadIncident& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_path()) {
    +      set_path(from.path());
    +    }
    +    if (from.has_digest()) {
    +      mutable_digest()->::safe_browsing::ClientDownloadRequest_Digests::MergeFrom(from.digest());
    +    }
    +    if (from.has_version()) {
    +      set_version(from.version());
    +    }
    +    if (from.has_blacklist_initialized()) {
    +      set_blacklist_initialized(from.blacklist_initialized());
    +    }
    +    if (from.has_signature()) {
    +      mutable_signature()->::safe_browsing::ClientDownloadRequest_SignatureInfo::MergeFrom(from.signature());
    +    }
    +    if (from.has_image_headers()) {
    +      mutable_image_headers()->::safe_browsing::ClientDownloadRequest_ImageHeaders::MergeFrom(from.image_headers());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::CopyFrom(const ClientIncidentReport_IncidentData_BlacklistLoadIncident& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_IncidentData_BlacklistLoadIncident::Swap(ClientIncidentReport_IncidentData_BlacklistLoadIncident* other) {
    +  if (other != this) {
    +    std::swap(path_, other->path_);
    +    std::swap(digest_, other->digest_);
    +    std::swap(version_, other->version_);
    +    std::swap(blacklist_initialized_, other->blacklist_initialized_);
    +    std::swap(signature_, other->signature_);
    +    std::swap(image_headers_, other->image_headers_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_IncidentData_BlacklistLoadIncident::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::kVariationsSeedSignatureFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident(const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  variations_seed_signature_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::~ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::SharedDtor() {
    +  if (variations_seed_signature_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete variations_seed_signature_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::default_instance_ = NULL;
    +
    +ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::New() const {
    +  return new ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident;
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::Clear() {
    +  if (has_variations_seed_signature()) {
    +    if (variations_seed_signature_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +      variations_seed_signature_->clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string variations_seed_signature = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_variations_seed_signature()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +  // optional string variations_seed_signature = 1;
    +  if (has_variations_seed_signature()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->variations_seed_signature(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    +}
    +
    +int ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string variations_seed_signature = 1;
    +    if (has_variations_seed_signature()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->variations_seed_signature());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::MergeFrom(const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_variations_seed_signature()) {
    +      set_variations_seed_signature(from.variations_seed_signature());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::CopyFrom(const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::Swap(ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* other) {
    +  if (other != this) {
    +    std::swap(variations_seed_signature_, other->variations_seed_signature_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_IncidentData_ScriptRequestIncident::kScriptDigestFieldNumber;
    +const int ClientIncidentReport_IncidentData_ScriptRequestIncident::kInclusionOriginFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_IncidentData_ScriptRequestIncident::ClientIncidentReport_IncidentData_ScriptRequestIncident()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_IncidentData_ScriptRequestIncident::ClientIncidentReport_IncidentData_ScriptRequestIncident(const ClientIncidentReport_IncidentData_ScriptRequestIncident& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  script_digest_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  inclusion_origin_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_IncidentData_ScriptRequestIncident::~ClientIncidentReport_IncidentData_ScriptRequestIncident() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::SharedDtor() {
    +  if (script_digest_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete script_digest_;
    +  }
    +  if (inclusion_origin_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete inclusion_origin_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_IncidentData_ScriptRequestIncident& ClientIncidentReport_IncidentData_ScriptRequestIncident::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_IncidentData_ScriptRequestIncident* ClientIncidentReport_IncidentData_ScriptRequestIncident::default_instance_ = NULL;
    +
    +ClientIncidentReport_IncidentData_ScriptRequestIncident* ClientIncidentReport_IncidentData_ScriptRequestIncident::New() const {
    +  return new ClientIncidentReport_IncidentData_ScriptRequestIncident;
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_script_digest()) {
    +      if (script_digest_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        script_digest_->clear();
    +      }
    +    }
    +    if (has_inclusion_origin()) {
    +      if (inclusion_origin_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        inclusion_origin_->clear();
    +      }
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_IncidentData_ScriptRequestIncident::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string script_digest = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_script_digest()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_inclusion_origin;
    +        break;
    +      }
    +
    +      // optional string inclusion_origin = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_inclusion_origin:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_inclusion_origin()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +  // optional string script_digest = 1;
    +  if (has_script_digest()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->script_digest(), output);
    +  }
    +
    +  // optional string inclusion_origin = 2;
    +  if (has_inclusion_origin()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->inclusion_origin(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    +}
    +
    +int ClientIncidentReport_IncidentData_ScriptRequestIncident::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string script_digest = 1;
    +    if (has_script_digest()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->script_digest());
    +    }
    +
    +    // optional string inclusion_origin = 2;
    +    if (has_inclusion_origin()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->inclusion_origin());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::MergeFrom(const ClientIncidentReport_IncidentData_ScriptRequestIncident& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_script_digest()) {
    +      set_script_digest(from.script_digest());
    +    }
    +    if (from.has_inclusion_origin()) {
    +      set_inclusion_origin(from.inclusion_origin());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::CopyFrom(const ClientIncidentReport_IncidentData_ScriptRequestIncident& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_IncidentData_ScriptRequestIncident::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_IncidentData_ScriptRequestIncident::Swap(ClientIncidentReport_IncidentData_ScriptRequestIncident* other) {
    +  if (other != this) {
    +    std::swap(script_digest_, other->script_digest_);
    +    std::swap(inclusion_origin_, other->inclusion_origin_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_IncidentData_ScriptRequestIncident::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_IncidentData::kIncidentTimeMsecFieldNumber;
    +const int ClientIncidentReport_IncidentData::kTrackedPreferenceFieldNumber;
    +const int ClientIncidentReport_IncidentData::kBinaryIntegrityFieldNumber;
    +const int ClientIncidentReport_IncidentData::kBlacklistLoadFieldNumber;
    +const int ClientIncidentReport_IncidentData::kVariationsSeedSignatureFieldNumber;
    +const int ClientIncidentReport_IncidentData::kScriptRequestFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_IncidentData::ClientIncidentReport_IncidentData()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.IncidentData)
    +}
    +
    +void ClientIncidentReport_IncidentData::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  tracked_preference_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident*>(
    +      ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident::internal_default_instance());
    +#else
    +  tracked_preference_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident*>(&::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  binary_integrity_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident*>(
    +      ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident::internal_default_instance());
    +#else
    +  binary_integrity_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident*>(&::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  blacklist_load_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident*>(
    +      ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident::internal_default_instance());
    +#else
    +  blacklist_load_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident*>(&::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  variations_seed_signature_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident*>(
    +      ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::internal_default_instance());
    +#else
    +  variations_seed_signature_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident*>(&::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  script_request_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident*>(
    +      ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident::internal_default_instance());
    +#else
    +  script_request_ = const_cast< ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident*>(&::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident::default_instance());
    +#endif
    +}
    +
    +ClientIncidentReport_IncidentData::ClientIncidentReport_IncidentData(const ClientIncidentReport_IncidentData& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.IncidentData)
    +}
    +
    +void ClientIncidentReport_IncidentData::SharedCtor() {
    +  _cached_size_ = 0;
    +  incident_time_msec_ = GOOGLE_LONGLONG(0);
    +  tracked_preference_ = NULL;
    +  binary_integrity_ = NULL;
    +  blacklist_load_ = NULL;
    +  variations_seed_signature_ = NULL;
    +  script_request_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_IncidentData::~ClientIncidentReport_IncidentData() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.IncidentData)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_IncidentData::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete tracked_preference_;
    +    delete binary_integrity_;
    +    delete blacklist_load_;
    +    delete variations_seed_signature_;
    +    delete script_request_;
    +  }
    +}
    +
    +void ClientIncidentReport_IncidentData::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_IncidentData& ClientIncidentReport_IncidentData::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_IncidentData* ClientIncidentReport_IncidentData::default_instance_ = NULL;
    +
    +ClientIncidentReport_IncidentData* ClientIncidentReport_IncidentData::New() const {
    +  return new ClientIncidentReport_IncidentData;
    +}
    +
    +void ClientIncidentReport_IncidentData::Clear() {
    +  if (_has_bits_[0 / 32] & 63) {
    +    incident_time_msec_ = GOOGLE_LONGLONG(0);
    +    if (has_tracked_preference()) {
    +      if (tracked_preference_ != NULL) tracked_preference_->::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident::Clear();
    +    }
    +    if (has_binary_integrity()) {
    +      if (binary_integrity_ != NULL) binary_integrity_->::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident::Clear();
    +    }
    +    if (has_blacklist_load()) {
    +      if (blacklist_load_ != NULL) blacklist_load_->::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident::Clear();
    +    }
    +    if (has_variations_seed_signature()) {
    +      if (variations_seed_signature_ != NULL) variations_seed_signature_->::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::Clear();
    +    }
    +    if (has_script_request()) {
    +      if (script_request_ != NULL) script_request_->::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_IncidentData::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.IncidentData)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional int64 incident_time_msec = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
    +                 input, &incident_time_msec_)));
    +          set_has_incident_time_msec();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_tracked_preference;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident tracked_preference = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_tracked_preference:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_tracked_preference()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_binary_integrity;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident binary_integrity = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_binary_integrity:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_binary_integrity()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_blacklist_load;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident blacklist_load = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_blacklist_load:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_blacklist_load()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(50)) goto parse_variations_seed_signature;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident variations_seed_signature = 6;
    +      case 6: {
    +        if (tag == 50) {
    +         parse_variations_seed_signature:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_variations_seed_signature()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(58)) goto parse_script_request;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident script_request = 7;
    +      case 7: {
    +        if (tag == 58) {
    +         parse_script_request:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_script_request()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.IncidentData)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.IncidentData)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_IncidentData::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.IncidentData)
    +  // optional int64 incident_time_msec = 1;
    +  if (has_incident_time_msec()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->incident_time_msec(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident tracked_preference = 2;
    +  if (has_tracked_preference()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->tracked_preference(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident binary_integrity = 3;
    +  if (has_binary_integrity()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      3, this->binary_integrity(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident blacklist_load = 4;
    +  if (has_blacklist_load()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      4, this->blacklist_load(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident variations_seed_signature = 6;
    +  if (has_variations_seed_signature()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      6, this->variations_seed_signature(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident script_request = 7;
    +  if (has_script_request()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      7, this->script_request(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.IncidentData)
    +}
    +
    +int ClientIncidentReport_IncidentData::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional int64 incident_time_msec = 1;
    +    if (has_incident_time_msec()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int64Size(
    +          this->incident_time_msec());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident tracked_preference = 2;
    +    if (has_tracked_preference()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->tracked_preference());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident binary_integrity = 3;
    +    if (has_binary_integrity()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->binary_integrity());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident blacklist_load = 4;
    +    if (has_blacklist_load()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->blacklist_load());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident variations_seed_signature = 6;
    +    if (has_variations_seed_signature()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->variations_seed_signature());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident script_request = 7;
    +    if (has_script_request()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->script_request());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_IncidentData::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_IncidentData::MergeFrom(const ClientIncidentReport_IncidentData& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_incident_time_msec()) {
    +      set_incident_time_msec(from.incident_time_msec());
    +    }
    +    if (from.has_tracked_preference()) {
    +      mutable_tracked_preference()->::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident::MergeFrom(from.tracked_preference());
    +    }
    +    if (from.has_binary_integrity()) {
    +      mutable_binary_integrity()->::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident::MergeFrom(from.binary_integrity());
    +    }
    +    if (from.has_blacklist_load()) {
    +      mutable_blacklist_load()->::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident::MergeFrom(from.blacklist_load());
    +    }
    +    if (from.has_variations_seed_signature()) {
    +      mutable_variations_seed_signature()->::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::MergeFrom(from.variations_seed_signature());
    +    }
    +    if (from.has_script_request()) {
    +      mutable_script_request()->::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident::MergeFrom(from.script_request());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_IncidentData::CopyFrom(const ClientIncidentReport_IncidentData& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_IncidentData::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_IncidentData::Swap(ClientIncidentReport_IncidentData* other) {
    +  if (other != this) {
    +    std::swap(incident_time_msec_, other->incident_time_msec_);
    +    std::swap(tracked_preference_, other->tracked_preference_);
    +    std::swap(binary_integrity_, other->binary_integrity_);
    +    std::swap(blacklist_load_, other->blacklist_load_);
    +    std::swap(variations_seed_signature_, other->variations_seed_signature_);
    +    std::swap(script_request_, other->script_request_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_IncidentData::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.IncidentData";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_DownloadDetails::kTokenFieldNumber;
    +const int ClientIncidentReport_DownloadDetails::kDownloadFieldNumber;
    +const int ClientIncidentReport_DownloadDetails::kDownloadTimeMsecFieldNumber;
    +const int ClientIncidentReport_DownloadDetails::kOpenTimeMsecFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_DownloadDetails::ClientIncidentReport_DownloadDetails()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.DownloadDetails)
    +}
    +
    +void ClientIncidentReport_DownloadDetails::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  download_ = const_cast< ::safe_browsing::ClientDownloadRequest*>(
    +      ::safe_browsing::ClientDownloadRequest::internal_default_instance());
    +#else
    +  download_ = const_cast< ::safe_browsing::ClientDownloadRequest*>(&::safe_browsing::ClientDownloadRequest::default_instance());
    +#endif
    +}
    +
    +ClientIncidentReport_DownloadDetails::ClientIncidentReport_DownloadDetails(const ClientIncidentReport_DownloadDetails& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.DownloadDetails)
    +}
    +
    +void ClientIncidentReport_DownloadDetails::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  download_ = NULL;
    +  download_time_msec_ = GOOGLE_LONGLONG(0);
    +  open_time_msec_ = GOOGLE_LONGLONG(0);
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_DownloadDetails::~ClientIncidentReport_DownloadDetails() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.DownloadDetails)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_DownloadDetails::SharedDtor() {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete token_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete download_;
    +  }
    +}
    +
    +void ClientIncidentReport_DownloadDetails::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_DownloadDetails& ClientIncidentReport_DownloadDetails::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_DownloadDetails* ClientIncidentReport_DownloadDetails::default_instance_ = NULL;
    +
    +ClientIncidentReport_DownloadDetails* ClientIncidentReport_DownloadDetails::New() const {
    +  return new ClientIncidentReport_DownloadDetails;
    +}
    +
    +void ClientIncidentReport_DownloadDetails::Clear() {
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 15) {
    +    ZR_(download_time_msec_, open_time_msec_);
    +    if (has_token()) {
    +      if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        token_->clear();
    +      }
    +    }
    +    if (has_download()) {
    +      if (download_ != NULL) download_->::safe_browsing::ClientDownloadRequest::Clear();
    +    }
    +  }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_DownloadDetails::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.DownloadDetails)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional bytes token = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
    +                input, this->mutable_token()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_download;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest download = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_download:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_download()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_download_time_msec;
    +        break;
    +      }
    +
    +      // optional int64 download_time_msec = 3;
    +      case 3: {
    +        if (tag == 24) {
    +         parse_download_time_msec:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
    +                 input, &download_time_msec_)));
    +          set_has_download_time_msec();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_open_time_msec;
    +        break;
    +      }
    +
    +      // optional int64 open_time_msec = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_open_time_msec:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
    +                 input, &open_time_msec_)));
    +          set_has_open_time_msec();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.DownloadDetails)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.DownloadDetails)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_DownloadDetails::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.DownloadDetails)
    +  // optional bytes token = 1;
    +  if (has_token()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
    +      1, this->token(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest download = 2;
    +  if (has_download()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->download(), output);
    +  }
    +
    +  // optional int64 download_time_msec = 3;
    +  if (has_download_time_msec()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->download_time_msec(), output);
    +  }
    +
    +  // optional int64 open_time_msec = 4;
    +  if (has_open_time_msec()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->open_time_msec(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.DownloadDetails)
    +}
    +
    +int ClientIncidentReport_DownloadDetails::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional bytes token = 1;
    +    if (has_token()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::BytesSize(
    +          this->token());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest download = 2;
    +    if (has_download()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->download());
    +    }
    +
    +    // optional int64 download_time_msec = 3;
    +    if (has_download_time_msec()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int64Size(
    +          this->download_time_msec());
    +    }
    +
    +    // optional int64 open_time_msec = 4;
    +    if (has_open_time_msec()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int64Size(
    +          this->open_time_msec());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_DownloadDetails::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_DownloadDetails::MergeFrom(const ClientIncidentReport_DownloadDetails& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_token()) {
    +      set_token(from.token());
    +    }
    +    if (from.has_download()) {
    +      mutable_download()->::safe_browsing::ClientDownloadRequest::MergeFrom(from.download());
    +    }
    +    if (from.has_download_time_msec()) {
    +      set_download_time_msec(from.download_time_msec());
    +    }
    +    if (from.has_open_time_msec()) {
    +      set_open_time_msec(from.open_time_msec());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_DownloadDetails::CopyFrom(const ClientIncidentReport_DownloadDetails& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_DownloadDetails::IsInitialized() const {
    +
    +  if (has_download()) {
    +    if (!this->download().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void ClientIncidentReport_DownloadDetails::Swap(ClientIncidentReport_DownloadDetails* other) {
    +  if (other != this) {
    +    std::swap(token_, other->token_);
    +    std::swap(download_, other->download_);
    +    std::swap(download_time_msec_, other->download_time_msec_);
    +    std::swap(open_time_msec_, other->open_time_msec_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_DownloadDetails::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.DownloadDetails";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_EnvironmentData_OS::kOsNameFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_OS::kOsVersionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData_OS::ClientIncidentReport_EnvironmentData_OS()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_EnvironmentData_OS::ClientIncidentReport_EnvironmentData_OS(const ClientIncidentReport_EnvironmentData_OS& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  os_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  os_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData_OS::~ClientIncidentReport_EnvironmentData_OS() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::SharedDtor() {
    +  if (os_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete os_name_;
    +  }
    +  if (os_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete os_version_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData_OS& ClientIncidentReport_EnvironmentData_OS::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData_OS* ClientIncidentReport_EnvironmentData_OS::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData_OS* ClientIncidentReport_EnvironmentData_OS::New() const {
    +  return new ClientIncidentReport_EnvironmentData_OS;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_os_name()) {
    +      if (os_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        os_name_->clear();
    +      }
    +    }
    +    if (has_os_version()) {
    +      if (os_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        os_version_->clear();
    +      }
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_OS::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string os_name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_os_name()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_os_version;
    +        break;
    +      }
    +
    +      // optional string os_version = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_os_version:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_os_version()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +  // optional string os_name = 1;
    +  if (has_os_name()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->os_name(), output);
    +  }
    +
    +  // optional string os_version = 2;
    +  if (has_os_version()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->os_version(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    +}
    +
    +int ClientIncidentReport_EnvironmentData_OS::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string os_name = 1;
    +    if (has_os_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->os_name());
    +    }
    +
    +    // optional string os_version = 2;
    +    if (has_os_version()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->os_version());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::MergeFrom(const ClientIncidentReport_EnvironmentData_OS& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_os_name()) {
    +      set_os_name(from.os_name());
    +    }
    +    if (from.has_os_version()) {
    +      set_os_version(from.os_version());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::CopyFrom(const ClientIncidentReport_EnvironmentData_OS& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_OS::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_OS::Swap(ClientIncidentReport_EnvironmentData_OS* other) {
    +  if (other != this) {
    +    std::swap(os_name_, other->os_name_);
    +    std::swap(os_version_, other->os_version_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData_OS::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData.OS";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_EnvironmentData_Machine::kCpuArchitectureFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Machine::kCpuVendorFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Machine::kCpuidFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData_Machine::ClientIncidentReport_EnvironmentData_Machine()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_EnvironmentData_Machine::ClientIncidentReport_EnvironmentData_Machine(const ClientIncidentReport_EnvironmentData_Machine& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  cpu_architecture_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  cpu_vendor_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  cpuid_ = 0u;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData_Machine::~ClientIncidentReport_EnvironmentData_Machine() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::SharedDtor() {
    +  if (cpu_architecture_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete cpu_architecture_;
    +  }
    +  if (cpu_vendor_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete cpu_vendor_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData_Machine& ClientIncidentReport_EnvironmentData_Machine::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData_Machine* ClientIncidentReport_EnvironmentData_Machine::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData_Machine* ClientIncidentReport_EnvironmentData_Machine::New() const {
    +  return new ClientIncidentReport_EnvironmentData_Machine;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::Clear() {
    +  if (_has_bits_[0 / 32] & 7) {
    +    if (has_cpu_architecture()) {
    +      if (cpu_architecture_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        cpu_architecture_->clear();
    +      }
    +    }
    +    if (has_cpu_vendor()) {
    +      if (cpu_vendor_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        cpu_vendor_->clear();
    +      }
    +    }
    +    cpuid_ = 0u;
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Machine::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string cpu_architecture = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_cpu_architecture()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_cpu_vendor;
    +        break;
    +      }
    +
    +      // optional string cpu_vendor = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_cpu_vendor:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_cpu_vendor()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_cpuid;
    +        break;
    +      }
    +
    +      // optional uint32 cpuid = 3;
    +      case 3: {
    +        if (tag == 24) {
    +         parse_cpuid:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
    +                 input, &cpuid_)));
    +          set_has_cpuid();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +  // optional string cpu_architecture = 1;
    +  if (has_cpu_architecture()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->cpu_architecture(), output);
    +  }
    +
    +  // optional string cpu_vendor = 2;
    +  if (has_cpu_vendor()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->cpu_vendor(), output);
    +  }
    +
    +  // optional uint32 cpuid = 3;
    +  if (has_cpuid()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->cpuid(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    +}
    +
    +int ClientIncidentReport_EnvironmentData_Machine::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string cpu_architecture = 1;
    +    if (has_cpu_architecture()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->cpu_architecture());
    +    }
    +
    +    // optional string cpu_vendor = 2;
    +    if (has_cpu_vendor()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->cpu_vendor());
    +    }
    +
    +    // optional uint32 cpuid = 3;
    +    if (has_cpuid()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt32Size(
    +          this->cpuid());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::MergeFrom(const ClientIncidentReport_EnvironmentData_Machine& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_cpu_architecture()) {
    +      set_cpu_architecture(from.cpu_architecture());
    +    }
    +    if (from.has_cpu_vendor()) {
    +      set_cpu_vendor(from.cpu_vendor());
    +    }
    +    if (from.has_cpuid()) {
    +      set_cpuid(from.cpuid());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::CopyFrom(const ClientIncidentReport_EnvironmentData_Machine& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Machine::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Machine::Swap(ClientIncidentReport_EnvironmentData_Machine* other) {
    +  if (other != this) {
    +    std::swap(cpu_architecture_, other->cpu_architecture_);
    +    std::swap(cpu_vendor_, other->cpu_vendor_);
    +    std::swap(cpuid_, other->cpuid_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData_Machine::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData.Machine";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +bool ClientIncidentReport_EnvironmentData_Process_Channel_IsValid(int value) {
    +  switch(value) {
    +    case 0:
    +    case 1:
    +    case 2:
    +    case 3:
    +    case 4:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::CHANNEL_UNKNOWN;
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::CHANNEL_CANARY;
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::CHANNEL_DEV;
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::CHANNEL_BETA;
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::CHANNEL_STABLE;
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::Channel_MIN;
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::Channel_MAX;
    +const int ClientIncidentReport_EnvironmentData_Process::Channel_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_EnvironmentData_Process_Patch::kFunctionFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process_Patch::kTargetDllFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData_Process_Patch::ClientIncidentReport_EnvironmentData_Process_Patch()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_Patch::ClientIncidentReport_EnvironmentData_Process_Patch(const ClientIncidentReport_EnvironmentData_Process_Patch& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  function_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  target_dll_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_Patch::~ClientIncidentReport_EnvironmentData_Process_Patch() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::SharedDtor() {
    +  if (function_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete function_;
    +  }
    +  if (target_dll_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete target_dll_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData_Process_Patch& ClientIncidentReport_EnvironmentData_Process_Patch::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_Patch* ClientIncidentReport_EnvironmentData_Process_Patch::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData_Process_Patch* ClientIncidentReport_EnvironmentData_Process_Patch::New() const {
    +  return new ClientIncidentReport_EnvironmentData_Process_Patch;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_function()) {
    +      if (function_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        function_->clear();
    +      }
    +    }
    +    if (has_target_dll()) {
    +      if (target_dll_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        target_dll_->clear();
    +      }
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_Patch::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string function = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_function()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_target_dll;
    +        break;
    +      }
    +
    +      // optional string target_dll = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_target_dll:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_target_dll()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +  // optional string function = 1;
    +  if (has_function()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->function(), output);
    +  }
    +
    +  // optional string target_dll = 2;
    +  if (has_target_dll()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->target_dll(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    +}
    +
    +int ClientIncidentReport_EnvironmentData_Process_Patch::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string function = 1;
    +    if (has_function()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->function());
    +    }
    +
    +    // optional string target_dll = 2;
    +    if (has_target_dll()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->target_dll());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::MergeFrom(const ClientIncidentReport_EnvironmentData_Process_Patch& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_function()) {
    +      set_function(from.function());
    +    }
    +    if (from.has_target_dll()) {
    +      set_target_dll(from.target_dll());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::CopyFrom(const ClientIncidentReport_EnvironmentData_Process_Patch& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_Patch::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Patch::Swap(ClientIncidentReport_EnvironmentData_Process_Patch* other) {
    +  if (other != this) {
    +    std::swap(function_, other->function_);
    +    std::swap(target_dll_, other->target_dll_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData_Process_Patch::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData_Process_NetworkProvider::ClientIncidentReport_EnvironmentData_Process_NetworkProvider()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_NetworkProvider::ClientIncidentReport_EnvironmentData_Process_NetworkProvider(const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::SharedCtor() {
    +  _cached_size_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_NetworkProvider::~ClientIncidentReport_EnvironmentData_Process_NetworkProvider() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& ClientIncidentReport_EnvironmentData_Process_NetworkProvider::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_NetworkProvider* ClientIncidentReport_EnvironmentData_Process_NetworkProvider::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData_Process_NetworkProvider* ClientIncidentReport_EnvironmentData_Process_NetworkProvider::New() const {
    +  return new ClientIncidentReport_EnvironmentData_Process_NetworkProvider;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::Clear() {
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_NetworkProvider::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +  handle_unusual:
    +    if (tag == 0 ||
    +        ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +        ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +      goto success;
    +    }
    +    DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +        input, tag, &unknown_fields_stream));
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    +}
    +
    +int ClientIncidentReport_EnvironmentData_Process_NetworkProvider::ByteSize() const {
    +  int total_size = 0;
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::MergeFrom(const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::CopyFrom(const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_NetworkProvider::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_NetworkProvider::Swap(ClientIncidentReport_EnvironmentData_Process_NetworkProvider* other) {
    +  if (other != this) {
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData_Process_NetworkProvider::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +bool ClientIncidentReport_EnvironmentData_Process_Dll_Feature_IsValid(int value) {
    +  switch(value) {
    +    case 0:
    +    case 1:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const ClientIncidentReport_EnvironmentData_Process_Dll_Feature ClientIncidentReport_EnvironmentData_Process_Dll::UNKNOWN;
    +const ClientIncidentReport_EnvironmentData_Process_Dll_Feature ClientIncidentReport_EnvironmentData_Process_Dll::LSP;
    +const ClientIncidentReport_EnvironmentData_Process_Dll_Feature ClientIncidentReport_EnvironmentData_Process_Dll::Feature_MIN;
    +const ClientIncidentReport_EnvironmentData_Process_Dll_Feature ClientIncidentReport_EnvironmentData_Process_Dll::Feature_MAX;
    +const int ClientIncidentReport_EnvironmentData_Process_Dll::Feature_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_EnvironmentData_Process_Dll::kPathFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process_Dll::kBaseAddressFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process_Dll::kLengthFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process_Dll::kFeatureFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process_Dll::kImageHeadersFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData_Process_Dll::ClientIncidentReport_EnvironmentData_Process_Dll()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(
    +      ::safe_browsing::ClientDownloadRequest_ImageHeaders::internal_default_instance());
    +#else
    +  image_headers_ = const_cast< ::safe_browsing::ClientDownloadRequest_ImageHeaders*>(&::safe_browsing::ClientDownloadRequest_ImageHeaders::default_instance());
    +#endif
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_Dll::ClientIncidentReport_EnvironmentData_Process_Dll(const ClientIncidentReport_EnvironmentData_Process_Dll& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  base_address_ = GOOGLE_ULONGLONG(0);
    +  length_ = 0u;
    +  image_headers_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_Dll::~ClientIncidentReport_EnvironmentData_Process_Dll() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::SharedDtor() {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete path_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete image_headers_;
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData_Process_Dll& ClientIncidentReport_EnvironmentData_Process_Dll::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_Dll* ClientIncidentReport_EnvironmentData_Process_Dll::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData_Process_Dll* ClientIncidentReport_EnvironmentData_Process_Dll::New() const {
    +  return new ClientIncidentReport_EnvironmentData_Process_Dll;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::Clear() {
    +  if (_has_bits_[0 / 32] & 23) {
    +    if (has_path()) {
    +      if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        path_->clear();
    +      }
    +    }
    +    base_address_ = GOOGLE_ULONGLONG(0);
    +    length_ = 0u;
    +    if (has_image_headers()) {
    +      if (image_headers_ != NULL) image_headers_->::safe_browsing::ClientDownloadRequest_ImageHeaders::Clear();
    +    }
    +  }
    +  feature_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_Dll::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string path = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_path()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_base_address;
    +        break;
    +      }
    +
    +      // optional uint64 base_address = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_base_address:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
    +                 input, &base_address_)));
    +          set_has_base_address();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_length;
    +        break;
    +      }
    +
    +      // optional uint32 length = 3;
    +      case 3: {
    +        if (tag == 24) {
    +         parse_length:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
    +                 input, &length_)));
    +          set_has_length();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_feature;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.Feature feature = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_feature:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature_IsValid(value)) {
    +            add_feature(static_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
    +          }
    +        } else if (tag == 34) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(
    +                 input,
    +                 &::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature_IsValid,
    +                 this->mutable_feature())));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_feature;
    +        if (input->ExpectTag(42)) goto parse_image_headers;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 5;
    +      case 5: {
    +        if (tag == 42) {
    +         parse_image_headers:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_image_headers()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +  // optional string path = 1;
    +  if (has_path()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->path(), output);
    +  }
    +
    +  // optional uint64 base_address = 2;
    +  if (has_base_address()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->base_address(), output);
    +  }
    +
    +  // optional uint32 length = 3;
    +  if (has_length()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->length(), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.Feature feature = 4;
    +  for (int i = 0; i < this->feature_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      4, this->feature(i), output);
    +  }
    +
    +  // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 5;
    +  if (has_image_headers()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      5, this->image_headers(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    +}
    +
    +int ClientIncidentReport_EnvironmentData_Process_Dll::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string path = 1;
    +    if (has_path()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->path());
    +    }
    +
    +    // optional uint64 base_address = 2;
    +    if (has_base_address()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt64Size(
    +          this->base_address());
    +    }
    +
    +    // optional uint32 length = 3;
    +    if (has_length()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt32Size(
    +          this->length());
    +    }
    +
    +    // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 5;
    +    if (has_image_headers()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->image_headers());
    +    }
    +
    +  }
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.Feature feature = 4;
    +  {
    +    int data_size = 0;
    +    for (int i = 0; i < this->feature_size(); i++) {
    +      data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(
    +        this->feature(i));
    +    }
    +    total_size += 1 * this->feature_size() + data_size;
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::MergeFrom(const ClientIncidentReport_EnvironmentData_Process_Dll& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  feature_.MergeFrom(from.feature_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_path()) {
    +      set_path(from.path());
    +    }
    +    if (from.has_base_address()) {
    +      set_base_address(from.base_address());
    +    }
    +    if (from.has_length()) {
    +      set_length(from.length());
    +    }
    +    if (from.has_image_headers()) {
    +      mutable_image_headers()->::safe_browsing::ClientDownloadRequest_ImageHeaders::MergeFrom(from.image_headers());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::CopyFrom(const ClientIncidentReport_EnvironmentData_Process_Dll& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_Dll::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_Dll::Swap(ClientIncidentReport_EnvironmentData_Process_Dll* other) {
    +  if (other != this) {
    +    std::swap(path_, other->path_);
    +    std::swap(base_address_, other->base_address_);
    +    std::swap(length_, other->length_);
    +    feature_.Swap(&other->feature_);
    +    std::swap(image_headers_, other->image_headers_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData_Process_Dll::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +bool ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_IsValid(int value) {
    +  switch(value) {
    +    case 0:
    +    case 1:
    +    case 2:
    +    case 3:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState::UNKNOWN;
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState::MODULE_STATE_UNKNOWN;
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState::MODULE_STATE_UNMODIFIED;
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState::MODULE_STATE_MODIFIED;
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState::ModifiedState_MIN;
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState::ModifiedState_MAX;
    +const int ClientIncidentReport_EnvironmentData_Process_ModuleState::ModifiedState_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_EnvironmentData_Process_ModuleState::kNameFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process_ModuleState::kModifiedStateFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process_ModuleState::kModifiedExportFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData_Process_ModuleState::ClientIncidentReport_EnvironmentData_Process_ModuleState()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_ModuleState::ClientIncidentReport_EnvironmentData_Process_ModuleState(const ClientIncidentReport_EnvironmentData_Process_ModuleState& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  modified_state_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_ModuleState::~ClientIncidentReport_EnvironmentData_Process_ModuleState() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState& ClientIncidentReport_EnvironmentData_Process_ModuleState::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process_ModuleState* ClientIncidentReport_EnvironmentData_Process_ModuleState::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData_Process_ModuleState* ClientIncidentReport_EnvironmentData_Process_ModuleState::New() const {
    +  return new ClientIncidentReport_EnvironmentData_Process_ModuleState;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    modified_state_ = 0;
    +  }
    +  modified_export_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_ModuleState::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_modified_state;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.ModifiedState modified_state = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_modified_state:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_IsValid(value)) {
    +            set_modified_state(static_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_modified_export;
    +        break;
    +      }
    +
    +      // repeated string modified_export = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_modified_export:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->add_modified_export()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_modified_export;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.ModifiedState modified_state = 2;
    +  if (has_modified_state()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      2, this->modified_state(), output);
    +  }
    +
    +  // repeated string modified_export = 3;
    +  for (int i = 0; i < this->modified_export_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteString(
    +      3, this->modified_export(i), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    +}
    +
    +int ClientIncidentReport_EnvironmentData_Process_ModuleState::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.ModifiedState modified_state = 2;
    +    if (has_modified_state()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->modified_state());
    +    }
    +
    +  }
    +  // repeated string modified_export = 3;
    +  total_size += 1 * this->modified_export_size();
    +  for (int i = 0; i < this->modified_export_size(); i++) {
    +    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
    +      this->modified_export(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::MergeFrom(const ClientIncidentReport_EnvironmentData_Process_ModuleState& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  modified_export_.MergeFrom(from.modified_export_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_modified_state()) {
    +      set_modified_state(from.modified_state());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::CopyFrom(const ClientIncidentReport_EnvironmentData_Process_ModuleState& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process_ModuleState::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process_ModuleState::Swap(ClientIncidentReport_EnvironmentData_Process_ModuleState* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    std::swap(modified_state_, other->modified_state_);
    +    modified_export_.Swap(&other->modified_export_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData_Process_ModuleState::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_EnvironmentData_Process::kVersionFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kOBSOLETEDllsFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kPatchesFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kNetworkProvidersFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kChromeUpdateChannelFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kUptimeMsecFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kMetricsConsentFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kExtendedConsentFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kDllFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kBlacklistedDllFieldNumber;
    +const int ClientIncidentReport_EnvironmentData_Process::kModuleStateFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData_Process::ClientIncidentReport_EnvironmentData_Process()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process::ClientIncidentReport_EnvironmentData_Process(const ClientIncidentReport_EnvironmentData_Process& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  chrome_update_channel_ = 0;
    +  uptime_msec_ = GOOGLE_LONGLONG(0);
    +  metrics_consent_ = false;
    +  extended_consent_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process::~ClientIncidentReport_EnvironmentData_Process() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::SharedDtor() {
    +  if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete version_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData_Process& ClientIncidentReport_EnvironmentData_Process::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData_Process* ClientIncidentReport_EnvironmentData_Process::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData_Process* ClientIncidentReport_EnvironmentData_Process::New() const {
    +  return new ClientIncidentReport_EnvironmentData_Process;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::Clear() {
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 241) {
    +    ZR_(uptime_msec_, extended_consent_);
    +    if (has_version()) {
    +      if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        version_->clear();
    +      }
    +    }
    +  }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  obsolete_dlls_.Clear();
    +  patches_.Clear();
    +  network_providers_.Clear();
    +  dll_.Clear();
    +  blacklisted_dll_.Clear();
    +  module_state_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string version = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_version()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_OBSOLETE_dlls;
    +        break;
    +      }
    +
    +      // repeated string OBSOLETE_dlls = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_OBSOLETE_dlls:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->add_obsolete_dlls()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_OBSOLETE_dlls;
    +        if (input->ExpectTag(26)) goto parse_patches;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch patches = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_patches:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_patches()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_patches;
    +        if (input->ExpectTag(34)) goto parse_network_providers;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider network_providers = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_network_providers:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_network_providers()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_network_providers;
    +        if (input->ExpectTag(40)) goto parse_chrome_update_channel;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Channel chrome_update_channel = 5;
    +      case 5: {
    +        if (tag == 40) {
    +         parse_chrome_update_channel:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel_IsValid(value)) {
    +            set_chrome_update_channel(static_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel >(value));
    +          } else {
    +            unknown_fields_stream.WriteVarint32(tag);
    +            unknown_fields_stream.WriteVarint32(value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(48)) goto parse_uptime_msec;
    +        break;
    +      }
    +
    +      // optional int64 uptime_msec = 6;
    +      case 6: {
    +        if (tag == 48) {
    +         parse_uptime_msec:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
    +                 input, &uptime_msec_)));
    +          set_has_uptime_msec();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(56)) goto parse_metrics_consent;
    +        break;
    +      }
    +
    +      // optional bool metrics_consent = 7;
    +      case 7: {
    +        if (tag == 56) {
    +         parse_metrics_consent:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &metrics_consent_)));
    +          set_has_metrics_consent();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(64)) goto parse_extended_consent;
    +        break;
    +      }
    +
    +      // optional bool extended_consent = 8;
    +      case 8: {
    +        if (tag == 64) {
    +         parse_extended_consent:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &extended_consent_)));
    +          set_has_extended_consent();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(74)) goto parse_dll;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll dll = 9;
    +      case 9: {
    +        if (tag == 74) {
    +         parse_dll:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_dll()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(74)) goto parse_dll;
    +        if (input->ExpectTag(82)) goto parse_blacklisted_dll;
    +        break;
    +      }
    +
    +      // repeated string blacklisted_dll = 10;
    +      case 10: {
    +        if (tag == 82) {
    +         parse_blacklisted_dll:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->add_blacklisted_dll()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(82)) goto parse_blacklisted_dll;
    +        if (input->ExpectTag(90)) goto parse_module_state;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState module_state = 11;
    +      case 11: {
    +        if (tag == 90) {
    +         parse_module_state:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_module_state()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(90)) goto parse_module_state;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +  // optional string version = 1;
    +  if (has_version()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->version(), output);
    +  }
    +
    +  // repeated string OBSOLETE_dlls = 2;
    +  for (int i = 0; i < this->obsolete_dlls_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteString(
    +      2, this->obsolete_dlls(i), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch patches = 3;
    +  for (int i = 0; i < this->patches_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      3, this->patches(i), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider network_providers = 4;
    +  for (int i = 0; i < this->network_providers_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      4, this->network_providers(i), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Channel chrome_update_channel = 5;
    +  if (has_chrome_update_channel()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      5, this->chrome_update_channel(), output);
    +  }
    +
    +  // optional int64 uptime_msec = 6;
    +  if (has_uptime_msec()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt64(6, this->uptime_msec(), output);
    +  }
    +
    +  // optional bool metrics_consent = 7;
    +  if (has_metrics_consent()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->metrics_consent(), output);
    +  }
    +
    +  // optional bool extended_consent = 8;
    +  if (has_extended_consent()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(8, this->extended_consent(), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll dll = 9;
    +  for (int i = 0; i < this->dll_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      9, this->dll(i), output);
    +  }
    +
    +  // repeated string blacklisted_dll = 10;
    +  for (int i = 0; i < this->blacklisted_dll_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteString(
    +      10, this->blacklisted_dll(i), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState module_state = 11;
    +  for (int i = 0; i < this->module_state_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      11, this->module_state(i), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    +}
    +
    +int ClientIncidentReport_EnvironmentData_Process::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string version = 1;
    +    if (has_version()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->version());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Channel chrome_update_channel = 5;
    +    if (has_chrome_update_channel()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->chrome_update_channel());
    +    }
    +
    +    // optional int64 uptime_msec = 6;
    +    if (has_uptime_msec()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int64Size(
    +          this->uptime_msec());
    +    }
    +
    +    // optional bool metrics_consent = 7;
    +    if (has_metrics_consent()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional bool extended_consent = 8;
    +    if (has_extended_consent()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  // repeated string OBSOLETE_dlls = 2;
    +  total_size += 1 * this->obsolete_dlls_size();
    +  for (int i = 0; i < this->obsolete_dlls_size(); i++) {
    +    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
    +      this->obsolete_dlls(i));
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch patches = 3;
    +  total_size += 1 * this->patches_size();
    +  for (int i = 0; i < this->patches_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->patches(i));
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider network_providers = 4;
    +  total_size += 1 * this->network_providers_size();
    +  for (int i = 0; i < this->network_providers_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->network_providers(i));
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll dll = 9;
    +  total_size += 1 * this->dll_size();
    +  for (int i = 0; i < this->dll_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->dll(i));
    +  }
    +
    +  // repeated string blacklisted_dll = 10;
    +  total_size += 1 * this->blacklisted_dll_size();
    +  for (int i = 0; i < this->blacklisted_dll_size(); i++) {
    +    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
    +      this->blacklisted_dll(i));
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState module_state = 11;
    +  total_size += 1 * this->module_state_size();
    +  for (int i = 0; i < this->module_state_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->module_state(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::MergeFrom(const ClientIncidentReport_EnvironmentData_Process& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  obsolete_dlls_.MergeFrom(from.obsolete_dlls_);
    +  patches_.MergeFrom(from.patches_);
    +  network_providers_.MergeFrom(from.network_providers_);
    +  dll_.MergeFrom(from.dll_);
    +  blacklisted_dll_.MergeFrom(from.blacklisted_dll_);
    +  module_state_.MergeFrom(from.module_state_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_version()) {
    +      set_version(from.version());
    +    }
    +    if (from.has_chrome_update_channel()) {
    +      set_chrome_update_channel(from.chrome_update_channel());
    +    }
    +    if (from.has_uptime_msec()) {
    +      set_uptime_msec(from.uptime_msec());
    +    }
    +    if (from.has_metrics_consent()) {
    +      set_metrics_consent(from.metrics_consent());
    +    }
    +    if (from.has_extended_consent()) {
    +      set_extended_consent(from.extended_consent());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::CopyFrom(const ClientIncidentReport_EnvironmentData_Process& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData_Process::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData_Process::Swap(ClientIncidentReport_EnvironmentData_Process* other) {
    +  if (other != this) {
    +    std::swap(version_, other->version_);
    +    obsolete_dlls_.Swap(&other->obsolete_dlls_);
    +    patches_.Swap(&other->patches_);
    +    network_providers_.Swap(&other->network_providers_);
    +    std::swap(chrome_update_channel_, other->chrome_update_channel_);
    +    std::swap(uptime_msec_, other->uptime_msec_);
    +    std::swap(metrics_consent_, other->metrics_consent_);
    +    std::swap(extended_consent_, other->extended_consent_);
    +    dll_.Swap(&other->dll_);
    +    blacklisted_dll_.Swap(&other->blacklisted_dll_);
    +    module_state_.Swap(&other->module_state_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData_Process::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData.Process";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport_EnvironmentData::kOsFieldNumber;
    +const int ClientIncidentReport_EnvironmentData::kMachineFieldNumber;
    +const int ClientIncidentReport_EnvironmentData::kProcessFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport_EnvironmentData::ClientIncidentReport_EnvironmentData()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport.EnvironmentData)
    +}
    +
    +void ClientIncidentReport_EnvironmentData::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  os_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_OS*>(
    +      ::safe_browsing::ClientIncidentReport_EnvironmentData_OS::internal_default_instance());
    +#else
    +  os_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_OS*>(&::safe_browsing::ClientIncidentReport_EnvironmentData_OS::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  machine_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine*>(
    +      ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine::internal_default_instance());
    +#else
    +  machine_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine*>(&::safe_browsing::ClientIncidentReport_EnvironmentData_Machine::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  process_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process*>(
    +      ::safe_browsing::ClientIncidentReport_EnvironmentData_Process::internal_default_instance());
    +#else
    +  process_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process*>(&::safe_browsing::ClientIncidentReport_EnvironmentData_Process::default_instance());
    +#endif
    +}
    +
    +ClientIncidentReport_EnvironmentData::ClientIncidentReport_EnvironmentData(const ClientIncidentReport_EnvironmentData& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport.EnvironmentData)
    +}
    +
    +void ClientIncidentReport_EnvironmentData::SharedCtor() {
    +  _cached_size_ = 0;
    +  os_ = NULL;
    +  machine_ = NULL;
    +  process_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport_EnvironmentData::~ClientIncidentReport_EnvironmentData() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport.EnvironmentData)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport_EnvironmentData::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete os_;
    +    delete machine_;
    +    delete process_;
    +  }
    +}
    +
    +void ClientIncidentReport_EnvironmentData::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport_EnvironmentData& ClientIncidentReport_EnvironmentData::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport_EnvironmentData* ClientIncidentReport_EnvironmentData::default_instance_ = NULL;
    +
    +ClientIncidentReport_EnvironmentData* ClientIncidentReport_EnvironmentData::New() const {
    +  return new ClientIncidentReport_EnvironmentData;
    +}
    +
    +void ClientIncidentReport_EnvironmentData::Clear() {
    +  if (_has_bits_[0 / 32] & 7) {
    +    if (has_os()) {
    +      if (os_ != NULL) os_->::safe_browsing::ClientIncidentReport_EnvironmentData_OS::Clear();
    +    }
    +    if (has_machine()) {
    +      if (machine_ != NULL) machine_->::safe_browsing::ClientIncidentReport_EnvironmentData_Machine::Clear();
    +    }
    +    if (has_process()) {
    +      if (process_ != NULL) process_->::safe_browsing::ClientIncidentReport_EnvironmentData_Process::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport_EnvironmentData::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport.EnvironmentData)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional .safe_browsing.ClientIncidentReport.EnvironmentData.OS os = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_os()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_machine;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Machine machine = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_machine:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_machine()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_process;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process process = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_process:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_process()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport.EnvironmentData)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport.EnvironmentData)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport_EnvironmentData::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport.EnvironmentData)
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.OS os = 1;
    +  if (has_os()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      1, this->os(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Machine machine = 2;
    +  if (has_machine()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->machine(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process process = 3;
    +  if (has_process()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      3, this->process(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport.EnvironmentData)
    +}
    +
    +int ClientIncidentReport_EnvironmentData::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional .safe_browsing.ClientIncidentReport.EnvironmentData.OS os = 1;
    +    if (has_os()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->os());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Machine machine = 2;
    +    if (has_machine()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->machine());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process process = 3;
    +    if (has_process()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->process());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport_EnvironmentData::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport_EnvironmentData::MergeFrom(const ClientIncidentReport_EnvironmentData& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_os()) {
    +      mutable_os()->::safe_browsing::ClientIncidentReport_EnvironmentData_OS::MergeFrom(from.os());
    +    }
    +    if (from.has_machine()) {
    +      mutable_machine()->::safe_browsing::ClientIncidentReport_EnvironmentData_Machine::MergeFrom(from.machine());
    +    }
    +    if (from.has_process()) {
    +      mutable_process()->::safe_browsing::ClientIncidentReport_EnvironmentData_Process::MergeFrom(from.process());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport_EnvironmentData::CopyFrom(const ClientIncidentReport_EnvironmentData& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport_EnvironmentData::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentReport_EnvironmentData::Swap(ClientIncidentReport_EnvironmentData* other) {
    +  if (other != this) {
    +    std::swap(os_, other->os_);
    +    std::swap(machine_, other->machine_);
    +    std::swap(process_, other->process_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport_EnvironmentData::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport.EnvironmentData";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentReport::kIncidentFieldNumber;
    +const int ClientIncidentReport::kDownloadFieldNumber;
    +const int ClientIncidentReport::kEnvironmentFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentReport::ClientIncidentReport()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentReport)
    +}
    +
    +void ClientIncidentReport::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  download_ = const_cast< ::safe_browsing::ClientIncidentReport_DownloadDetails*>(
    +      ::safe_browsing::ClientIncidentReport_DownloadDetails::internal_default_instance());
    +#else
    +  download_ = const_cast< ::safe_browsing::ClientIncidentReport_DownloadDetails*>(&::safe_browsing::ClientIncidentReport_DownloadDetails::default_instance());
    +#endif
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  environment_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData*>(
    +      ::safe_browsing::ClientIncidentReport_EnvironmentData::internal_default_instance());
    +#else
    +  environment_ = const_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData*>(&::safe_browsing::ClientIncidentReport_EnvironmentData::default_instance());
    +#endif
    +}
    +
    +ClientIncidentReport::ClientIncidentReport(const ClientIncidentReport& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentReport)
    +}
    +
    +void ClientIncidentReport::SharedCtor() {
    +  _cached_size_ = 0;
    +  download_ = NULL;
    +  environment_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentReport::~ClientIncidentReport() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentReport)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentReport::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete download_;
    +    delete environment_;
    +  }
    +}
    +
    +void ClientIncidentReport::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentReport& ClientIncidentReport::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentReport* ClientIncidentReport::default_instance_ = NULL;
    +
    +ClientIncidentReport* ClientIncidentReport::New() const {
    +  return new ClientIncidentReport;
    +}
    +
    +void ClientIncidentReport::Clear() {
    +  if (_has_bits_[0 / 32] & 6) {
    +    if (has_download()) {
    +      if (download_ != NULL) download_->::safe_browsing::ClientIncidentReport_DownloadDetails::Clear();
    +    }
    +    if (has_environment()) {
    +      if (environment_ != NULL) environment_->::safe_browsing::ClientIncidentReport_EnvironmentData::Clear();
    +    }
    +  }
    +  incident_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentReport::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentReport)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // repeated .safe_browsing.ClientIncidentReport.IncidentData incident = 1;
    +      case 1: {
    +        if (tag == 10) {
    +         parse_incident:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_incident()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(10)) goto parse_incident;
    +        if (input->ExpectTag(18)) goto parse_download;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_download:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_download()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_environment;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.EnvironmentData environment = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_environment:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_environment()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentReport)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentReport)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentReport::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentReport)
    +  // repeated .safe_browsing.ClientIncidentReport.IncidentData incident = 1;
    +  for (int i = 0; i < this->incident_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      1, this->incident(i), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +  if (has_download()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->download(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData environment = 3;
    +  if (has_environment()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      3, this->environment(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentReport)
    +}
    +
    +int ClientIncidentReport::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    +    // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +    if (has_download()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->download());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.EnvironmentData environment = 3;
    +    if (has_environment()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->environment());
    +    }
    +
    +  }
    +  // repeated .safe_browsing.ClientIncidentReport.IncidentData incident = 1;
    +  total_size += 1 * this->incident_size();
    +  for (int i = 0; i < this->incident_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->incident(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentReport::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentReport::MergeFrom(const ClientIncidentReport& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  incident_.MergeFrom(from.incident_);
    +  if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    +    if (from.has_download()) {
    +      mutable_download()->::safe_browsing::ClientIncidentReport_DownloadDetails::MergeFrom(from.download());
    +    }
    +    if (from.has_environment()) {
    +      mutable_environment()->::safe_browsing::ClientIncidentReport_EnvironmentData::MergeFrom(from.environment());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentReport::CopyFrom(const ClientIncidentReport& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentReport::IsInitialized() const {
    +
    +  if (has_download()) {
    +    if (!this->download().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void ClientIncidentReport::Swap(ClientIncidentReport* other) {
    +  if (other != this) {
    +    incident_.Swap(&other->incident_);
    +    std::swap(download_, other->download_);
    +    std::swap(environment_, other->environment_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentReport::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentReport";
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentResponse_EnvironmentRequest::kDllIndexFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentResponse_EnvironmentRequest::ClientIncidentResponse_EnvironmentRequest()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentResponse_EnvironmentRequest::ClientIncidentResponse_EnvironmentRequest(const ClientIncidentResponse_EnvironmentRequest& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::SharedCtor() {
    +  _cached_size_ = 0;
    +  dll_index_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentResponse_EnvironmentRequest::~ClientIncidentResponse_EnvironmentRequest() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentResponse_EnvironmentRequest& ClientIncidentResponse_EnvironmentRequest::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentResponse_EnvironmentRequest* ClientIncidentResponse_EnvironmentRequest::default_instance_ = NULL;
    +
    +ClientIncidentResponse_EnvironmentRequest* ClientIncidentResponse_EnvironmentRequest::New() const {
    +  return new ClientIncidentResponse_EnvironmentRequest;
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::Clear() {
    +  dll_index_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentResponse_EnvironmentRequest::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional int32 dll_index = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &dll_index_)));
    +          set_has_dll_index();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +  // optional int32 dll_index = 1;
    +  if (has_dll_index()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->dll_index(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    +}
    +
    +int ClientIncidentResponse_EnvironmentRequest::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional int32 dll_index = 1;
    +    if (has_dll_index()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->dll_index());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::MergeFrom(const ClientIncidentResponse_EnvironmentRequest& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_dll_index()) {
    +      set_dll_index(from.dll_index());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::CopyFrom(const ClientIncidentResponse_EnvironmentRequest& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentResponse_EnvironmentRequest::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentResponse_EnvironmentRequest::Swap(ClientIncidentResponse_EnvironmentRequest* other) {
    +  if (other != this) {
    +    std::swap(dll_index_, other->dll_index_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentResponse_EnvironmentRequest::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentResponse.EnvironmentRequest";
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int ClientIncidentResponse::kTokenFieldNumber;
    +const int ClientIncidentResponse::kDownloadRequestedFieldNumber;
    +const int ClientIncidentResponse::kEnvironmentRequestsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ClientIncidentResponse::ClientIncidentResponse()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.ClientIncidentResponse)
    +}
    +
    +void ClientIncidentResponse::InitAsDefaultInstance() {
    +}
    +
    +ClientIncidentResponse::ClientIncidentResponse(const ClientIncidentResponse& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.ClientIncidentResponse)
    +}
    +
    +void ClientIncidentResponse::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  download_requested_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ClientIncidentResponse::~ClientIncidentResponse() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.ClientIncidentResponse)
    +  SharedDtor();
    +}
    +
    +void ClientIncidentResponse::SharedDtor() {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete token_;
    +  }
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +  }
    +}
    +
    +void ClientIncidentResponse::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ClientIncidentResponse& ClientIncidentResponse::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +ClientIncidentResponse* ClientIncidentResponse::default_instance_ = NULL;
    +
    +ClientIncidentResponse* ClientIncidentResponse::New() const {
    +  return new ClientIncidentResponse;
    +}
    +
    +void ClientIncidentResponse::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_token()) {
    +      if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        token_->clear();
    +      }
    +    }
    +    download_requested_ = false;
    +  }
    +  environment_requests_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool ClientIncidentResponse::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.ClientIncidentResponse)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional bytes token = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
    +                input, this->mutable_token()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_download_requested;
    +        break;
    +      }
    +
    +      // optional bool download_requested = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_download_requested:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &download_requested_)));
    +          set_has_download_requested();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_environment_requests;
    +        break;
    +      }
    +
    +      // repeated .safe_browsing.ClientIncidentResponse.EnvironmentRequest environment_requests = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_environment_requests:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_environment_requests()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_environment_requests;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.ClientIncidentResponse)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.ClientIncidentResponse)
    +  return false;
    +#undef DO_
    +}
    +
    +void ClientIncidentResponse::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.ClientIncidentResponse)
    +  // optional bytes token = 1;
    +  if (has_token()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
    +      1, this->token(), output);
    +  }
    +
    +  // optional bool download_requested = 2;
    +  if (has_download_requested()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->download_requested(), output);
    +  }
    +
    +  // repeated .safe_browsing.ClientIncidentResponse.EnvironmentRequest environment_requests = 3;
    +  for (int i = 0; i < this->environment_requests_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      3, this->environment_requests(i), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.ClientIncidentResponse)
    +}
    +
    +int ClientIncidentResponse::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional bytes token = 1;
    +    if (has_token()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::BytesSize(
    +          this->token());
    +    }
    +
    +    // optional bool download_requested = 2;
    +    if (has_download_requested()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  // repeated .safe_browsing.ClientIncidentResponse.EnvironmentRequest environment_requests = 3;
    +  total_size += 1 * this->environment_requests_size();
    +  for (int i = 0; i < this->environment_requests_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->environment_requests(i));
    +  }
    +
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ClientIncidentResponse::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void ClientIncidentResponse::MergeFrom(const ClientIncidentResponse& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  environment_requests_.MergeFrom(from.environment_requests_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_token()) {
    +      set_token(from.token());
    +    }
    +    if (from.has_download_requested()) {
    +      set_download_requested(from.download_requested());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void ClientIncidentResponse::CopyFrom(const ClientIncidentResponse& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ClientIncidentResponse::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void ClientIncidentResponse::Swap(ClientIncidentResponse* other) {
    +  if (other != this) {
    +    std::swap(token_, other->token_);
    +    std::swap(download_requested_, other->download_requested_);
    +    environment_requests_.Swap(&other->environment_requests_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string ClientIncidentResponse::GetTypeName() const {
    +  return "safe_browsing.ClientIncidentResponse";
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int DownloadMetadata::kDownloadIdFieldNumber;
    +const int DownloadMetadata::kDownloadFieldNumber;
    +#endif  // !_MSC_VER
    +
    +DownloadMetadata::DownloadMetadata()
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:safe_browsing.DownloadMetadata)
    +}
    +
    +void DownloadMetadata::InitAsDefaultInstance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  download_ = const_cast< ::safe_browsing::ClientIncidentReport_DownloadDetails*>(
    +      ::safe_browsing::ClientIncidentReport_DownloadDetails::internal_default_instance());
    +#else
    +  download_ = const_cast< ::safe_browsing::ClientIncidentReport_DownloadDetails*>(&::safe_browsing::ClientIncidentReport_DownloadDetails::default_instance());
    +#endif
    +}
    +
    +DownloadMetadata::DownloadMetadata(const DownloadMetadata& from)
    +  : ::google::protobuf::MessageLite() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:safe_browsing.DownloadMetadata)
    +}
    +
    +void DownloadMetadata::SharedCtor() {
    +  _cached_size_ = 0;
    +  download_id_ = 0u;
    +  download_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +DownloadMetadata::~DownloadMetadata() {
    +  // @@protoc_insertion_point(destructor:safe_browsing.DownloadMetadata)
    +  SharedDtor();
    +}
    +
    +void DownloadMetadata::SharedDtor() {
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  if (this != &default_instance()) {
    +  #else
    +  if (this != default_instance_) {
    +  #endif
    +    delete download_;
    +  }
    +}
    +
    +void DownloadMetadata::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const DownloadMetadata& DownloadMetadata::default_instance() {
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  protobuf_AddDesc_csd_2eproto();
    +#else
    +  if (default_instance_ == NULL) protobuf_AddDesc_csd_2eproto();
    +#endif
    +  return *default_instance_;
    +}
    +
    +DownloadMetadata* DownloadMetadata::default_instance_ = NULL;
    +
    +DownloadMetadata* DownloadMetadata::New() const {
    +  return new DownloadMetadata;
    +}
    +
    +void DownloadMetadata::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    download_id_ = 0u;
    +    if (has_download()) {
    +      if (download_ != NULL) download_->::safe_browsing::ClientIncidentReport_DownloadDetails::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->clear();
    +}
    +
    +bool DownloadMetadata::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  ::google::protobuf::io::StringOutputStream unknown_fields_string(
    +      mutable_unknown_fields());
    +  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
    +      &unknown_fields_string);
    +  // @@protoc_insertion_point(parse_start:safe_browsing.DownloadMetadata)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional uint32 download_id = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
    +                 input, &download_id_)));
    +          set_has_download_id();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_download;
    +        break;
    +      }
    +
    +      // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_download:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_download()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
    +            input, tag, &unknown_fields_stream));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:safe_browsing.DownloadMetadata)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:safe_browsing.DownloadMetadata)
    +  return false;
    +#undef DO_
    +}
    +
    +void DownloadMetadata::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:safe_browsing.DownloadMetadata)
    +  // optional uint32 download_id = 1;
    +  if (has_download_id()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->download_id(), output);
    +  }
    +
    +  // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +  if (has_download()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessage(
    +      2, this->download(), output);
    +  }
    +
    +  output->WriteRaw(unknown_fields().data(),
    +                   unknown_fields().size());
    +  // @@protoc_insertion_point(serialize_end:safe_browsing.DownloadMetadata)
    +}
    +
    +int DownloadMetadata::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional uint32 download_id = 1;
    +    if (has_download_id()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt32Size(
    +          this->download_id());
    +    }
    +
    +    // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +    if (has_download()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->download());
    +    }
    +
    +  }
    +  total_size += unknown_fields().size();
    +
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void DownloadMetadata::CheckTypeAndMergeFrom(
    +    const ::google::protobuf::MessageLite& from) {
    +  MergeFrom(*::google::protobuf::down_cast(&from));
    +}
    +
    +void DownloadMetadata::MergeFrom(const DownloadMetadata& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_download_id()) {
    +      set_download_id(from.download_id());
    +    }
    +    if (from.has_download()) {
    +      mutable_download()->::safe_browsing::ClientIncidentReport_DownloadDetails::MergeFrom(from.download());
    +    }
    +  }
    +  mutable_unknown_fields()->append(from.unknown_fields());
    +}
    +
    +void DownloadMetadata::CopyFrom(const DownloadMetadata& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool DownloadMetadata::IsInitialized() const {
    +
    +  if (has_download()) {
    +    if (!this->download().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void DownloadMetadata::Swap(DownloadMetadata* other) {
    +  if (other != this) {
    +    std::swap(download_id_, other->download_id_);
    +    std::swap(download_, other->download_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.swap(other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::std::string DownloadMetadata::GetTypeName() const {
    +  return "safe_browsing.DownloadMetadata";
    +}
    +
    +
     // @@protoc_insertion_point(namespace_scope)
     
     }  // namespace safe_browsing
    diff --git a/toolkit/components/downloads/csd.pb.h b/toolkit/components/downloads/csd.pb.h
    index 8380488d2af6..b2e8734be89b 100644
    --- a/toolkit/components/downloads/csd.pb.h
    +++ b/toolkit/components/downloads/csd.pb.h
    @@ -8,18 +8,19 @@
     
     #include 
     
    -#if GOOGLE_PROTOBUF_VERSION < 2004000
    +#if GOOGLE_PROTOBUF_VERSION < 2006000
     #error This file was generated by a newer version of protoc which is
     #error incompatible with your Protocol Buffer headers.  Please update
     #error your headers.
     #endif
    -#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
    +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
     #error This file was generated by an older version of protoc which is
     #error incompatible with your Protocol Buffer headers.  Please
     #error regenerate this file with a newer version of protoc.
     #endif
     
     #include 
    +#include 
     #include 
     #include 
     // @@protoc_insertion_point(includes)
    @@ -31,6 +32,12 @@ void  protobuf_AddDesc_csd_2eproto();
     void protobuf_AssignDesc_csd_2eproto();
     void protobuf_ShutdownFile_csd_2eproto();
     
    +class ClientPhishingRequest;
    +class ClientPhishingRequest_Feature;
    +class ClientPhishingResponse;
    +class ClientMalwareRequest;
    +class ClientMalwareRequest_UrlInfo;
    +class ClientMalwareResponse;
     class ClientDownloadRequest;
     class ClientDownloadRequest_Digests;
     class ClientDownloadRequest_Resource;
    @@ -40,8 +47,31 @@ class ClientDownloadRequest_SignatureInfo;
     class ClientDownloadRequest_PEImageHeaders;
     class ClientDownloadRequest_PEImageHeaders_DebugData;
     class ClientDownloadRequest_ImageHeaders;
    +class ClientDownloadRequest_ArchivedBinary;
     class ClientDownloadResponse;
     class ClientDownloadResponse_MoreInfo;
    +class ClientDownloadReport;
    +class ClientDownloadReport_UserInformation;
    +class ClientUploadResponse;
    +class ClientIncidentReport;
    +class ClientIncidentReport_IncidentData;
    +class ClientIncidentReport_IncidentData_TrackedPreferenceIncident;
    +class ClientIncidentReport_IncidentData_BinaryIntegrityIncident;
    +class ClientIncidentReport_IncidentData_BlacklistLoadIncident;
    +class ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident;
    +class ClientIncidentReport_IncidentData_ScriptRequestIncident;
    +class ClientIncidentReport_DownloadDetails;
    +class ClientIncidentReport_EnvironmentData;
    +class ClientIncidentReport_EnvironmentData_OS;
    +class ClientIncidentReport_EnvironmentData_Machine;
    +class ClientIncidentReport_EnvironmentData_Process;
    +class ClientIncidentReport_EnvironmentData_Process_Patch;
    +class ClientIncidentReport_EnvironmentData_Process_NetworkProvider;
    +class ClientIncidentReport_EnvironmentData_Process_Dll;
    +class ClientIncidentReport_EnvironmentData_Process_ModuleState;
    +class ClientIncidentResponse;
    +class ClientIncidentResponse_EnvironmentRequest;
    +class DownloadMetadata;
     
     enum ClientDownloadRequest_ResourceType {
       ClientDownloadRequest_ResourceType_DOWNLOAD_URL = 0,
    @@ -78,153 +108,241 @@ const ClientDownloadResponse_Verdict ClientDownloadResponse_Verdict_Verdict_MIN
     const ClientDownloadResponse_Verdict ClientDownloadResponse_Verdict_Verdict_MAX = ClientDownloadResponse_Verdict_DANGEROUS_HOST;
     const int ClientDownloadResponse_Verdict_Verdict_ARRAYSIZE = ClientDownloadResponse_Verdict_Verdict_MAX + 1;
     
    +enum ClientDownloadReport_Reason {
    +  ClientDownloadReport_Reason_SHARE = 0,
    +  ClientDownloadReport_Reason_FALSE_POSITIVE = 1,
    +  ClientDownloadReport_Reason_APPEAL = 2
    +};
    +bool ClientDownloadReport_Reason_IsValid(int value);
    +const ClientDownloadReport_Reason ClientDownloadReport_Reason_Reason_MIN = ClientDownloadReport_Reason_SHARE;
    +const ClientDownloadReport_Reason ClientDownloadReport_Reason_Reason_MAX = ClientDownloadReport_Reason_APPEAL;
    +const int ClientDownloadReport_Reason_Reason_ARRAYSIZE = ClientDownloadReport_Reason_Reason_MAX + 1;
    +
    +enum ClientUploadResponse_UploadStatus {
    +  ClientUploadResponse_UploadStatus_SUCCESS = 0,
    +  ClientUploadResponse_UploadStatus_UPLOAD_FAILURE = 1
    +};
    +bool ClientUploadResponse_UploadStatus_IsValid(int value);
    +const ClientUploadResponse_UploadStatus ClientUploadResponse_UploadStatus_UploadStatus_MIN = ClientUploadResponse_UploadStatus_SUCCESS;
    +const ClientUploadResponse_UploadStatus ClientUploadResponse_UploadStatus_UploadStatus_MAX = ClientUploadResponse_UploadStatus_UPLOAD_FAILURE;
    +const int ClientUploadResponse_UploadStatus_UploadStatus_ARRAYSIZE = ClientUploadResponse_UploadStatus_UploadStatus_MAX + 1;
    +
    +enum ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState {
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_UNKNOWN = 0,
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_CLEARED = 1,
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_WEAK_LEGACY_OBSOLETE = 2,
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_CHANGED = 3,
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_UNTRUSTED_UNKNOWN_VALUE = 4
    +};
    +bool ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_IsValid(int value);
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_ValueState_MIN = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_UNKNOWN;
    +const ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_ValueState_MAX = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_UNTRUSTED_UNKNOWN_VALUE;
    +const int ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_ValueState_ARRAYSIZE = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_ValueState_MAX + 1;
    +
    +enum ClientIncidentReport_EnvironmentData_Process_Dll_Feature {
    +  ClientIncidentReport_EnvironmentData_Process_Dll_Feature_UNKNOWN = 0,
    +  ClientIncidentReport_EnvironmentData_Process_Dll_Feature_LSP = 1
    +};
    +bool ClientIncidentReport_EnvironmentData_Process_Dll_Feature_IsValid(int value);
    +const ClientIncidentReport_EnvironmentData_Process_Dll_Feature ClientIncidentReport_EnvironmentData_Process_Dll_Feature_Feature_MIN = ClientIncidentReport_EnvironmentData_Process_Dll_Feature_UNKNOWN;
    +const ClientIncidentReport_EnvironmentData_Process_Dll_Feature ClientIncidentReport_EnvironmentData_Process_Dll_Feature_Feature_MAX = ClientIncidentReport_EnvironmentData_Process_Dll_Feature_LSP;
    +const int ClientIncidentReport_EnvironmentData_Process_Dll_Feature_Feature_ARRAYSIZE = ClientIncidentReport_EnvironmentData_Process_Dll_Feature_Feature_MAX + 1;
    +
    +enum ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState {
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_UNKNOWN = 0,
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_MODULE_STATE_UNKNOWN = 1,
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_MODULE_STATE_UNMODIFIED = 2,
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_MODULE_STATE_MODIFIED = 3
    +};
    +bool ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_IsValid(int value);
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_ModifiedState_MIN = ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_UNKNOWN;
    +const ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_ModifiedState_MAX = ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_MODULE_STATE_MODIFIED;
    +const int ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_ModifiedState_ARRAYSIZE = ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_ModifiedState_MAX + 1;
    +
    +enum ClientIncidentReport_EnvironmentData_Process_Channel {
    +  ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_UNKNOWN = 0,
    +  ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_CANARY = 1,
    +  ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_DEV = 2,
    +  ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_BETA = 3,
    +  ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_STABLE = 4
    +};
    +bool ClientIncidentReport_EnvironmentData_Process_Channel_IsValid(int value);
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process_Channel_Channel_MIN = ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_UNKNOWN;
    +const ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process_Channel_Channel_MAX = ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_STABLE;
    +const int ClientIncidentReport_EnvironmentData_Process_Channel_Channel_ARRAYSIZE = ClientIncidentReport_EnvironmentData_Process_Channel_Channel_MAX + 1;
    +
     // ===================================================================
     
    -class ClientDownloadRequest_Digests : public ::google::protobuf::MessageLite {
    +class ClientPhishingRequest_Feature : public ::google::protobuf::MessageLite {
      public:
    -  ClientDownloadRequest_Digests();
    -  virtual ~ClientDownloadRequest_Digests();
    -  
    -  ClientDownloadRequest_Digests(const ClientDownloadRequest_Digests& from);
    -  
    -  inline ClientDownloadRequest_Digests& operator=(const ClientDownloadRequest_Digests& from) {
    +  ClientPhishingRequest_Feature();
    +  virtual ~ClientPhishingRequest_Feature();
    +
    +  ClientPhishingRequest_Feature(const ClientPhishingRequest_Feature& from);
    +
    +  inline ClientPhishingRequest_Feature& operator=(const ClientPhishingRequest_Feature& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    -  static const ClientDownloadRequest_Digests& default_instance();
    -  
    -  void Swap(ClientDownloadRequest_Digests* other);
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientPhishingRequest_Feature& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientPhishingRequest_Feature* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientPhishingRequest_Feature* other);
    +
       // implements Message ----------------------------------------------
    -  
    -  ClientDownloadRequest_Digests* New() const;
    +
    +  ClientPhishingRequest_Feature* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    -  void CopyFrom(const ClientDownloadRequest_Digests& from);
    -  void MergeFrom(const ClientDownloadRequest_Digests& from);
    +  void CopyFrom(const ClientPhishingRequest_Feature& from);
    +  void MergeFrom(const ClientPhishingRequest_Feature& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    -  // optional bytes sha256 = 1;
    -  inline bool has_sha256() const;
    -  inline void clear_sha256();
    -  static const int kSha256FieldNumber = 1;
    -  inline const ::std::string& sha256() const;
    -  inline void set_sha256(const ::std::string& value);
    -  inline void set_sha256(const char* value);
    -  inline void set_sha256(const void* value, size_t size);
    -  inline ::std::string* mutable_sha256();
    -  inline ::std::string* release_sha256();
    -  
    -  // optional bytes sha1 = 2;
    -  inline bool has_sha1() const;
    -  inline void clear_sha1();
    -  static const int kSha1FieldNumber = 2;
    -  inline const ::std::string& sha1() const;
    -  inline void set_sha1(const ::std::string& value);
    -  inline void set_sha1(const char* value);
    -  inline void set_sha1(const void* value, size_t size);
    -  inline ::std::string* mutable_sha1();
    -  inline ::std::string* release_sha1();
    -  
    -  // optional bytes md5 = 3;
    -  inline bool has_md5() const;
    -  inline void clear_md5();
    -  static const int kMd5FieldNumber = 3;
    -  inline const ::std::string& md5() const;
    -  inline void set_md5(const ::std::string& value);
    -  inline void set_md5(const char* value);
    -  inline void set_md5(const void* value, size_t size);
    -  inline ::std::string* mutable_md5();
    -  inline ::std::string* release_md5();
    -  
    -  // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.Digests)
    +
    +  // required string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // required double value = 2;
    +  inline bool has_value() const;
    +  inline void clear_value();
    +  static const int kValueFieldNumber = 2;
    +  inline double value() const;
    +  inline void set_value(double value);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientPhishingRequest.Feature)
      private:
    -  inline void set_has_sha256();
    -  inline void clear_has_sha256();
    -  inline void set_has_sha1();
    -  inline void clear_has_sha1();
    -  inline void set_has_md5();
    -  inline void clear_has_md5();
    -  
    -  ::std::string* sha256_;
    -  ::std::string* sha1_;
    -  ::std::string* md5_;
    -  
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_value();
    +  inline void clear_has_value();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
    -  
    +  ::std::string* name_;
    +  double value_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
    -  static ClientDownloadRequest_Digests* default_instance_;
    +  static ClientPhishingRequest_Feature* default_instance_;
     };
     // -------------------------------------------------------------------
     
    -class ClientDownloadRequest_Resource : public ::google::protobuf::MessageLite {
    +class ClientPhishingRequest : public ::google::protobuf::MessageLite {
      public:
    -  ClientDownloadRequest_Resource();
    -  virtual ~ClientDownloadRequest_Resource();
    -  
    -  ClientDownloadRequest_Resource(const ClientDownloadRequest_Resource& from);
    -  
    -  inline ClientDownloadRequest_Resource& operator=(const ClientDownloadRequest_Resource& from) {
    +  ClientPhishingRequest();
    +  virtual ~ClientPhishingRequest();
    +
    +  ClientPhishingRequest(const ClientPhishingRequest& from);
    +
    +  inline ClientPhishingRequest& operator=(const ClientPhishingRequest& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    -  static const ClientDownloadRequest_Resource& default_instance();
    -  
    -  void Swap(ClientDownloadRequest_Resource* other);
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientPhishingRequest& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientPhishingRequest* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientPhishingRequest* other);
    +
       // implements Message ----------------------------------------------
    -  
    -  ClientDownloadRequest_Resource* New() const;
    +
    +  ClientPhishingRequest* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    -  void CopyFrom(const ClientDownloadRequest_Resource& from);
    -  void MergeFrom(const ClientDownloadRequest_Resource& from);
    +  void CopyFrom(const ClientPhishingRequest& from);
    +  void MergeFrom(const ClientPhishingRequest& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
    +  typedef ClientPhishingRequest_Feature Feature;
    +
       // accessors -------------------------------------------------------
    -  
    -  // required string url = 1;
    +
    +  // optional string url = 1;
       inline bool has_url() const;
       inline void clear_url();
       static const int kUrlFieldNumber = 1;
    @@ -234,25 +352,336 @@ class ClientDownloadRequest_Resource : public ::google::protobuf::MessageLite {
       inline void set_url(const char* value, size_t size);
       inline ::std::string* mutable_url();
       inline ::std::string* release_url();
    -  
    -  // required .safe_browsing.ClientDownloadRequest.ResourceType type = 2;
    -  inline bool has_type() const;
    -  inline void clear_type();
    -  static const int kTypeFieldNumber = 2;
    -  inline ::safe_browsing::ClientDownloadRequest_ResourceType type() const;
    -  inline void set_type(::safe_browsing::ClientDownloadRequest_ResourceType value);
    -  
    -  // optional bytes remote_ip = 3;
    -  inline bool has_remote_ip() const;
    -  inline void clear_remote_ip();
    -  static const int kRemoteIpFieldNumber = 3;
    -  inline const ::std::string& remote_ip() const;
    -  inline void set_remote_ip(const ::std::string& value);
    -  inline void set_remote_ip(const char* value);
    -  inline void set_remote_ip(const void* value, size_t size);
    -  inline ::std::string* mutable_remote_ip();
    -  inline ::std::string* release_remote_ip();
    -  
    +  inline void set_allocated_url(::std::string* url);
    +
    +  // optional bytes OBSOLETE_hash_prefix = 10;
    +  inline bool has_obsolete_hash_prefix() const;
    +  inline void clear_obsolete_hash_prefix();
    +  static const int kOBSOLETEHashPrefixFieldNumber = 10;
    +  inline const ::std::string& obsolete_hash_prefix() const;
    +  inline void set_obsolete_hash_prefix(const ::std::string& value);
    +  inline void set_obsolete_hash_prefix(const char* value);
    +  inline void set_obsolete_hash_prefix(const void* value, size_t size);
    +  inline ::std::string* mutable_obsolete_hash_prefix();
    +  inline ::std::string* release_obsolete_hash_prefix();
    +  inline void set_allocated_obsolete_hash_prefix(::std::string* obsolete_hash_prefix);
    +
    +  // required float client_score = 2;
    +  inline bool has_client_score() const;
    +  inline void clear_client_score();
    +  static const int kClientScoreFieldNumber = 2;
    +  inline float client_score() const;
    +  inline void set_client_score(float value);
    +
    +  // optional bool is_phishing = 4;
    +  inline bool has_is_phishing() const;
    +  inline void clear_is_phishing();
    +  static const int kIsPhishingFieldNumber = 4;
    +  inline bool is_phishing() const;
    +  inline void set_is_phishing(bool value);
    +
    +  // repeated .safe_browsing.ClientPhishingRequest.Feature feature_map = 5;
    +  inline int feature_map_size() const;
    +  inline void clear_feature_map();
    +  static const int kFeatureMapFieldNumber = 5;
    +  inline const ::safe_browsing::ClientPhishingRequest_Feature& feature_map(int index) const;
    +  inline ::safe_browsing::ClientPhishingRequest_Feature* mutable_feature_map(int index);
    +  inline ::safe_browsing::ClientPhishingRequest_Feature* add_feature_map();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >&
    +      feature_map() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >*
    +      mutable_feature_map();
    +
    +  // optional int32 model_version = 6;
    +  inline bool has_model_version() const;
    +  inline void clear_model_version();
    +  static const int kModelVersionFieldNumber = 6;
    +  inline ::google::protobuf::int32 model_version() const;
    +  inline void set_model_version(::google::protobuf::int32 value);
    +
    +  // repeated .safe_browsing.ClientPhishingRequest.Feature non_model_feature_map = 8;
    +  inline int non_model_feature_map_size() const;
    +  inline void clear_non_model_feature_map();
    +  static const int kNonModelFeatureMapFieldNumber = 8;
    +  inline const ::safe_browsing::ClientPhishingRequest_Feature& non_model_feature_map(int index) const;
    +  inline ::safe_browsing::ClientPhishingRequest_Feature* mutable_non_model_feature_map(int index);
    +  inline ::safe_browsing::ClientPhishingRequest_Feature* add_non_model_feature_map();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >&
    +      non_model_feature_map() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >*
    +      mutable_non_model_feature_map();
    +
    +  // optional string OBSOLETE_referrer_url = 9;
    +  inline bool has_obsolete_referrer_url() const;
    +  inline void clear_obsolete_referrer_url();
    +  static const int kOBSOLETEReferrerUrlFieldNumber = 9;
    +  inline const ::std::string& obsolete_referrer_url() const;
    +  inline void set_obsolete_referrer_url(const ::std::string& value);
    +  inline void set_obsolete_referrer_url(const char* value);
    +  inline void set_obsolete_referrer_url(const char* value, size_t size);
    +  inline ::std::string* mutable_obsolete_referrer_url();
    +  inline ::std::string* release_obsolete_referrer_url();
    +  inline void set_allocated_obsolete_referrer_url(::std::string* obsolete_referrer_url);
    +
    +  // repeated uint32 shingle_hashes = 12 [packed = true];
    +  inline int shingle_hashes_size() const;
    +  inline void clear_shingle_hashes();
    +  static const int kShingleHashesFieldNumber = 12;
    +  inline ::google::protobuf::uint32 shingle_hashes(int index) const;
    +  inline void set_shingle_hashes(int index, ::google::protobuf::uint32 value);
    +  inline void add_shingle_hashes(::google::protobuf::uint32 value);
    +  inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
    +      shingle_hashes() const;
    +  inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
    +      mutable_shingle_hashes();
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientPhishingRequest)
    + private:
    +  inline void set_has_url();
    +  inline void clear_has_url();
    +  inline void set_has_obsolete_hash_prefix();
    +  inline void clear_has_obsolete_hash_prefix();
    +  inline void set_has_client_score();
    +  inline void clear_has_client_score();
    +  inline void set_has_is_phishing();
    +  inline void clear_has_is_phishing();
    +  inline void set_has_model_version();
    +  inline void clear_has_model_version();
    +  inline void set_has_obsolete_referrer_url();
    +  inline void clear_has_obsolete_referrer_url();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* url_;
    +  ::std::string* obsolete_hash_prefix_;
    +  float client_score_;
    +  bool is_phishing_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature > feature_map_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature > non_model_feature_map_;
    +  ::std::string* obsolete_referrer_url_;
    +  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > shingle_hashes_;
    +  mutable int _shingle_hashes_cached_byte_size_;
    +  ::google::protobuf::int32 model_version_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientPhishingRequest* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientPhishingResponse : public ::google::protobuf::MessageLite {
    + public:
    +  ClientPhishingResponse();
    +  virtual ~ClientPhishingResponse();
    +
    +  ClientPhishingResponse(const ClientPhishingResponse& from);
    +
    +  inline ClientPhishingResponse& operator=(const ClientPhishingResponse& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientPhishingResponse& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientPhishingResponse* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientPhishingResponse* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientPhishingResponse* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientPhishingResponse& from);
    +  void MergeFrom(const ClientPhishingResponse& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // required bool phishy = 1;
    +  inline bool has_phishy() const;
    +  inline void clear_phishy();
    +  static const int kPhishyFieldNumber = 1;
    +  inline bool phishy() const;
    +  inline void set_phishy(bool value);
    +
    +  // repeated string OBSOLETE_whitelist_expression = 2;
    +  inline int obsolete_whitelist_expression_size() const;
    +  inline void clear_obsolete_whitelist_expression();
    +  static const int kOBSOLETEWhitelistExpressionFieldNumber = 2;
    +  inline const ::std::string& obsolete_whitelist_expression(int index) const;
    +  inline ::std::string* mutable_obsolete_whitelist_expression(int index);
    +  inline void set_obsolete_whitelist_expression(int index, const ::std::string& value);
    +  inline void set_obsolete_whitelist_expression(int index, const char* value);
    +  inline void set_obsolete_whitelist_expression(int index, const char* value, size_t size);
    +  inline ::std::string* add_obsolete_whitelist_expression();
    +  inline void add_obsolete_whitelist_expression(const ::std::string& value);
    +  inline void add_obsolete_whitelist_expression(const char* value);
    +  inline void add_obsolete_whitelist_expression(const char* value, size_t size);
    +  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& obsolete_whitelist_expression() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_obsolete_whitelist_expression();
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientPhishingResponse)
    + private:
    +  inline void set_has_phishy();
    +  inline void clear_has_phishy();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::std::string> obsolete_whitelist_expression_;
    +  bool phishy_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientPhishingResponse* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientMalwareRequest_UrlInfo : public ::google::protobuf::MessageLite {
    + public:
    +  ClientMalwareRequest_UrlInfo();
    +  virtual ~ClientMalwareRequest_UrlInfo();
    +
    +  ClientMalwareRequest_UrlInfo(const ClientMalwareRequest_UrlInfo& from);
    +
    +  inline ClientMalwareRequest_UrlInfo& operator=(const ClientMalwareRequest_UrlInfo& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientMalwareRequest_UrlInfo& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientMalwareRequest_UrlInfo* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientMalwareRequest_UrlInfo* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientMalwareRequest_UrlInfo* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientMalwareRequest_UrlInfo& from);
    +  void MergeFrom(const ClientMalwareRequest_UrlInfo& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // required string ip = 1;
    +  inline bool has_ip() const;
    +  inline void clear_ip();
    +  static const int kIpFieldNumber = 1;
    +  inline const ::std::string& ip() const;
    +  inline void set_ip(const ::std::string& value);
    +  inline void set_ip(const char* value);
    +  inline void set_ip(const char* value, size_t size);
    +  inline ::std::string* mutable_ip();
    +  inline ::std::string* release_ip();
    +  inline void set_allocated_ip(::std::string* ip);
    +
    +  // required string url = 2;
    +  inline bool has_url() const;
    +  inline void clear_url();
    +  static const int kUrlFieldNumber = 2;
    +  inline const ::std::string& url() const;
    +  inline void set_url(const ::std::string& value);
    +  inline void set_url(const char* value);
    +  inline void set_url(const char* value, size_t size);
    +  inline ::std::string* mutable_url();
    +  inline ::std::string* release_url();
    +  inline void set_allocated_url(::std::string* url);
    +
    +  // optional string method = 3;
    +  inline bool has_method() const;
    +  inline void clear_method();
    +  static const int kMethodFieldNumber = 3;
    +  inline const ::std::string& method() const;
    +  inline void set_method(const ::std::string& value);
    +  inline void set_method(const char* value);
    +  inline void set_method(const char* value, size_t size);
    +  inline ::std::string* mutable_method();
    +  inline ::std::string* release_method();
    +  inline void set_allocated_method(::std::string* method);
    +
       // optional string referrer = 4;
       inline bool has_referrer() const;
       inline void clear_referrer();
    @@ -263,7 +692,527 @@ class ClientDownloadRequest_Resource : public ::google::protobuf::MessageLite {
       inline void set_referrer(const char* value, size_t size);
       inline ::std::string* mutable_referrer();
       inline ::std::string* release_referrer();
    -  
    +  inline void set_allocated_referrer(::std::string* referrer);
    +
    +  // optional int32 resource_type = 5;
    +  inline bool has_resource_type() const;
    +  inline void clear_resource_type();
    +  static const int kResourceTypeFieldNumber = 5;
    +  inline ::google::protobuf::int32 resource_type() const;
    +  inline void set_resource_type(::google::protobuf::int32 value);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientMalwareRequest.UrlInfo)
    + private:
    +  inline void set_has_ip();
    +  inline void clear_has_ip();
    +  inline void set_has_url();
    +  inline void clear_has_url();
    +  inline void set_has_method();
    +  inline void clear_has_method();
    +  inline void set_has_referrer();
    +  inline void clear_has_referrer();
    +  inline void set_has_resource_type();
    +  inline void clear_has_resource_type();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* ip_;
    +  ::std::string* url_;
    +  ::std::string* method_;
    +  ::std::string* referrer_;
    +  ::google::protobuf::int32 resource_type_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientMalwareRequest_UrlInfo* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientMalwareRequest : public ::google::protobuf::MessageLite {
    + public:
    +  ClientMalwareRequest();
    +  virtual ~ClientMalwareRequest();
    +
    +  ClientMalwareRequest(const ClientMalwareRequest& from);
    +
    +  inline ClientMalwareRequest& operator=(const ClientMalwareRequest& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientMalwareRequest& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientMalwareRequest* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientMalwareRequest* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientMalwareRequest* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientMalwareRequest& from);
    +  void MergeFrom(const ClientMalwareRequest& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientMalwareRequest_UrlInfo UrlInfo;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // required string url = 1;
    +  inline bool has_url() const;
    +  inline void clear_url();
    +  static const int kUrlFieldNumber = 1;
    +  inline const ::std::string& url() const;
    +  inline void set_url(const ::std::string& value);
    +  inline void set_url(const char* value);
    +  inline void set_url(const char* value, size_t size);
    +  inline ::std::string* mutable_url();
    +  inline ::std::string* release_url();
    +  inline void set_allocated_url(::std::string* url);
    +
    +  // optional string referrer_url = 4;
    +  inline bool has_referrer_url() const;
    +  inline void clear_referrer_url();
    +  static const int kReferrerUrlFieldNumber = 4;
    +  inline const ::std::string& referrer_url() const;
    +  inline void set_referrer_url(const ::std::string& value);
    +  inline void set_referrer_url(const char* value);
    +  inline void set_referrer_url(const char* value, size_t size);
    +  inline ::std::string* mutable_referrer_url();
    +  inline ::std::string* release_referrer_url();
    +  inline void set_allocated_referrer_url(::std::string* referrer_url);
    +
    +  // repeated .safe_browsing.ClientMalwareRequest.UrlInfo bad_ip_url_info = 7;
    +  inline int bad_ip_url_info_size() const;
    +  inline void clear_bad_ip_url_info();
    +  static const int kBadIpUrlInfoFieldNumber = 7;
    +  inline const ::safe_browsing::ClientMalwareRequest_UrlInfo& bad_ip_url_info(int index) const;
    +  inline ::safe_browsing::ClientMalwareRequest_UrlInfo* mutable_bad_ip_url_info(int index);
    +  inline ::safe_browsing::ClientMalwareRequest_UrlInfo* add_bad_ip_url_info();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientMalwareRequest_UrlInfo >&
    +      bad_ip_url_info() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientMalwareRequest_UrlInfo >*
    +      mutable_bad_ip_url_info();
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientMalwareRequest)
    + private:
    +  inline void set_has_url();
    +  inline void clear_has_url();
    +  inline void set_has_referrer_url();
    +  inline void clear_has_referrer_url();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* url_;
    +  ::std::string* referrer_url_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientMalwareRequest_UrlInfo > bad_ip_url_info_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientMalwareRequest* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientMalwareResponse : public ::google::protobuf::MessageLite {
    + public:
    +  ClientMalwareResponse();
    +  virtual ~ClientMalwareResponse();
    +
    +  ClientMalwareResponse(const ClientMalwareResponse& from);
    +
    +  inline ClientMalwareResponse& operator=(const ClientMalwareResponse& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientMalwareResponse& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientMalwareResponse* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientMalwareResponse* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientMalwareResponse* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientMalwareResponse& from);
    +  void MergeFrom(const ClientMalwareResponse& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // required bool blacklist = 1;
    +  inline bool has_blacklist() const;
    +  inline void clear_blacklist();
    +  static const int kBlacklistFieldNumber = 1;
    +  inline bool blacklist() const;
    +  inline void set_blacklist(bool value);
    +
    +  // optional string bad_ip = 2;
    +  inline bool has_bad_ip() const;
    +  inline void clear_bad_ip();
    +  static const int kBadIpFieldNumber = 2;
    +  inline const ::std::string& bad_ip() const;
    +  inline void set_bad_ip(const ::std::string& value);
    +  inline void set_bad_ip(const char* value);
    +  inline void set_bad_ip(const char* value, size_t size);
    +  inline ::std::string* mutable_bad_ip();
    +  inline ::std::string* release_bad_ip();
    +  inline void set_allocated_bad_ip(::std::string* bad_ip);
    +
    +  // optional string bad_url = 3;
    +  inline bool has_bad_url() const;
    +  inline void clear_bad_url();
    +  static const int kBadUrlFieldNumber = 3;
    +  inline const ::std::string& bad_url() const;
    +  inline void set_bad_url(const ::std::string& value);
    +  inline void set_bad_url(const char* value);
    +  inline void set_bad_url(const char* value, size_t size);
    +  inline ::std::string* mutable_bad_url();
    +  inline ::std::string* release_bad_url();
    +  inline void set_allocated_bad_url(::std::string* bad_url);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientMalwareResponse)
    + private:
    +  inline void set_has_blacklist();
    +  inline void clear_has_blacklist();
    +  inline void set_has_bad_ip();
    +  inline void clear_has_bad_ip();
    +  inline void set_has_bad_url();
    +  inline void clear_has_bad_url();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* bad_ip_;
    +  ::std::string* bad_url_;
    +  bool blacklist_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientMalwareResponse* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientDownloadRequest_Digests : public ::google::protobuf::MessageLite {
    + public:
    +  ClientDownloadRequest_Digests();
    +  virtual ~ClientDownloadRequest_Digests();
    +
    +  ClientDownloadRequest_Digests(const ClientDownloadRequest_Digests& from);
    +
    +  inline ClientDownloadRequest_Digests& operator=(const ClientDownloadRequest_Digests& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientDownloadRequest_Digests& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_Digests* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientDownloadRequest_Digests* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientDownloadRequest_Digests* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientDownloadRequest_Digests& from);
    +  void MergeFrom(const ClientDownloadRequest_Digests& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bytes sha256 = 1;
    +  inline bool has_sha256() const;
    +  inline void clear_sha256();
    +  static const int kSha256FieldNumber = 1;
    +  inline const ::std::string& sha256() const;
    +  inline void set_sha256(const ::std::string& value);
    +  inline void set_sha256(const char* value);
    +  inline void set_sha256(const void* value, size_t size);
    +  inline ::std::string* mutable_sha256();
    +  inline ::std::string* release_sha256();
    +  inline void set_allocated_sha256(::std::string* sha256);
    +
    +  // optional bytes sha1 = 2;
    +  inline bool has_sha1() const;
    +  inline void clear_sha1();
    +  static const int kSha1FieldNumber = 2;
    +  inline const ::std::string& sha1() const;
    +  inline void set_sha1(const ::std::string& value);
    +  inline void set_sha1(const char* value);
    +  inline void set_sha1(const void* value, size_t size);
    +  inline ::std::string* mutable_sha1();
    +  inline ::std::string* release_sha1();
    +  inline void set_allocated_sha1(::std::string* sha1);
    +
    +  // optional bytes md5 = 3;
    +  inline bool has_md5() const;
    +  inline void clear_md5();
    +  static const int kMd5FieldNumber = 3;
    +  inline const ::std::string& md5() const;
    +  inline void set_md5(const ::std::string& value);
    +  inline void set_md5(const char* value);
    +  inline void set_md5(const void* value, size_t size);
    +  inline ::std::string* mutable_md5();
    +  inline ::std::string* release_md5();
    +  inline void set_allocated_md5(::std::string* md5);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.Digests)
    + private:
    +  inline void set_has_sha256();
    +  inline void clear_has_sha256();
    +  inline void set_has_sha1();
    +  inline void clear_has_sha1();
    +  inline void set_has_md5();
    +  inline void clear_has_md5();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* sha256_;
    +  ::std::string* sha1_;
    +  ::std::string* md5_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientDownloadRequest_Digests* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientDownloadRequest_Resource : public ::google::protobuf::MessageLite {
    + public:
    +  ClientDownloadRequest_Resource();
    +  virtual ~ClientDownloadRequest_Resource();
    +
    +  ClientDownloadRequest_Resource(const ClientDownloadRequest_Resource& from);
    +
    +  inline ClientDownloadRequest_Resource& operator=(const ClientDownloadRequest_Resource& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientDownloadRequest_Resource& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_Resource* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientDownloadRequest_Resource* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientDownloadRequest_Resource* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientDownloadRequest_Resource& from);
    +  void MergeFrom(const ClientDownloadRequest_Resource& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // required string url = 1;
    +  inline bool has_url() const;
    +  inline void clear_url();
    +  static const int kUrlFieldNumber = 1;
    +  inline const ::std::string& url() const;
    +  inline void set_url(const ::std::string& value);
    +  inline void set_url(const char* value);
    +  inline void set_url(const char* value, size_t size);
    +  inline ::std::string* mutable_url();
    +  inline ::std::string* release_url();
    +  inline void set_allocated_url(::std::string* url);
    +
    +  // required .safe_browsing.ClientDownloadRequest.ResourceType type = 2;
    +  inline bool has_type() const;
    +  inline void clear_type();
    +  static const int kTypeFieldNumber = 2;
    +  inline ::safe_browsing::ClientDownloadRequest_ResourceType type() const;
    +  inline void set_type(::safe_browsing::ClientDownloadRequest_ResourceType value);
    +
    +  // optional bytes remote_ip = 3;
    +  inline bool has_remote_ip() const;
    +  inline void clear_remote_ip();
    +  static const int kRemoteIpFieldNumber = 3;
    +  inline const ::std::string& remote_ip() const;
    +  inline void set_remote_ip(const ::std::string& value);
    +  inline void set_remote_ip(const char* value);
    +  inline void set_remote_ip(const void* value, size_t size);
    +  inline ::std::string* mutable_remote_ip();
    +  inline ::std::string* release_remote_ip();
    +  inline void set_allocated_remote_ip(::std::string* remote_ip);
    +
    +  // optional string referrer = 4;
    +  inline bool has_referrer() const;
    +  inline void clear_referrer();
    +  static const int kReferrerFieldNumber = 4;
    +  inline const ::std::string& referrer() const;
    +  inline void set_referrer(const ::std::string& value);
    +  inline void set_referrer(const char* value);
    +  inline void set_referrer(const char* value, size_t size);
    +  inline ::std::string* mutable_referrer();
    +  inline ::std::string* release_referrer();
    +  inline void set_allocated_referrer(::std::string* referrer);
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.Resource)
      private:
       inline void set_has_url();
    @@ -274,19 +1223,23 @@ class ClientDownloadRequest_Resource : public ::google::protobuf::MessageLite {
       inline void clear_has_remote_ip();
       inline void set_has_referrer();
       inline void clear_has_referrer();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::std::string* url_;
       ::std::string* remote_ip_;
       ::std::string* referrer_;
       int type_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest_Resource* default_instance_;
     };
    @@ -296,45 +1249,63 @@ class ClientDownloadRequest_CertificateChain_Element : public ::google::protobuf
      public:
       ClientDownloadRequest_CertificateChain_Element();
       virtual ~ClientDownloadRequest_CertificateChain_Element();
    -  
    +
       ClientDownloadRequest_CertificateChain_Element(const ClientDownloadRequest_CertificateChain_Element& from);
    -  
    +
       inline ClientDownloadRequest_CertificateChain_Element& operator=(const ClientDownloadRequest_CertificateChain_Element& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadRequest_CertificateChain_Element& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_CertificateChain_Element* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadRequest_CertificateChain_Element* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadRequest_CertificateChain_Element* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadRequest_CertificateChain_Element& from);
       void MergeFrom(const ClientDownloadRequest_CertificateChain_Element& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional bytes certificate = 1;
       inline bool has_certificate() const;
       inline void clear_certificate();
    @@ -345,21 +1316,26 @@ class ClientDownloadRequest_CertificateChain_Element : public ::google::protobuf
       inline void set_certificate(const void* value, size_t size);
       inline ::std::string* mutable_certificate();
       inline ::std::string* release_certificate();
    -  
    +  inline void set_allocated_certificate(::std::string* certificate);
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.CertificateChain.Element)
      private:
       inline void set_has_certificate();
       inline void clear_has_certificate();
    -  
    -  ::std::string* certificate_;
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
    -  
    +  ::std::string* certificate_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest_CertificateChain_Element* default_instance_;
     };
    @@ -369,47 +1345,65 @@ class ClientDownloadRequest_CertificateChain : public ::google::protobuf::Messag
      public:
       ClientDownloadRequest_CertificateChain();
       virtual ~ClientDownloadRequest_CertificateChain();
    -  
    +
       ClientDownloadRequest_CertificateChain(const ClientDownloadRequest_CertificateChain& from);
    -  
    +
       inline ClientDownloadRequest_CertificateChain& operator=(const ClientDownloadRequest_CertificateChain& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadRequest_CertificateChain& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_CertificateChain* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadRequest_CertificateChain* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadRequest_CertificateChain* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadRequest_CertificateChain& from);
       void MergeFrom(const ClientDownloadRequest_CertificateChain& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef ClientDownloadRequest_CertificateChain_Element Element;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // repeated .safe_browsing.ClientDownloadRequest.CertificateChain.Element element = 1;
       inline int element_size() const;
       inline void clear_element();
    @@ -421,19 +1415,23 @@ class ClientDownloadRequest_CertificateChain : public ::google::protobuf::Messag
           element() const;
       inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain_Element >*
           mutable_element();
    -  
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.CertificateChain)
      private:
    -  
    -  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain_Element > element_;
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
    -  
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain_Element > element_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest_CertificateChain* default_instance_;
     };
    @@ -443,45 +1441,63 @@ class ClientDownloadRequest_SignatureInfo : public ::google::protobuf::MessageLi
      public:
       ClientDownloadRequest_SignatureInfo();
       virtual ~ClientDownloadRequest_SignatureInfo();
    -  
    +
       ClientDownloadRequest_SignatureInfo(const ClientDownloadRequest_SignatureInfo& from);
    -  
    +
       inline ClientDownloadRequest_SignatureInfo& operator=(const ClientDownloadRequest_SignatureInfo& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadRequest_SignatureInfo& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_SignatureInfo* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadRequest_SignatureInfo* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadRequest_SignatureInfo* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadRequest_SignatureInfo& from);
       void MergeFrom(const ClientDownloadRequest_SignatureInfo& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // repeated .safe_browsing.ClientDownloadRequest.CertificateChain certificate_chain = 1;
       inline int certificate_chain_size() const;
       inline void clear_certificate_chain();
    @@ -493,29 +1509,33 @@ class ClientDownloadRequest_SignatureInfo : public ::google::protobuf::MessageLi
           certificate_chain() const;
       inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain >*
           mutable_certificate_chain();
    -  
    +
       // optional bool trusted = 2;
       inline bool has_trusted() const;
       inline void clear_trusted();
       static const int kTrustedFieldNumber = 2;
       inline bool trusted() const;
       inline void set_trusted(bool value);
    -  
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.SignatureInfo)
      private:
       inline void set_has_trusted();
       inline void clear_has_trusted();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain > certificate_chain_;
       bool trusted_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest_SignatureInfo* default_instance_;
     };
    @@ -525,45 +1545,63 @@ class ClientDownloadRequest_PEImageHeaders_DebugData : public ::google::protobuf
      public:
       ClientDownloadRequest_PEImageHeaders_DebugData();
       virtual ~ClientDownloadRequest_PEImageHeaders_DebugData();
    -  
    +
       ClientDownloadRequest_PEImageHeaders_DebugData(const ClientDownloadRequest_PEImageHeaders_DebugData& from);
    -  
    +
       inline ClientDownloadRequest_PEImageHeaders_DebugData& operator=(const ClientDownloadRequest_PEImageHeaders_DebugData& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadRequest_PEImageHeaders_DebugData& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_PEImageHeaders_DebugData* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadRequest_PEImageHeaders_DebugData* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadRequest_PEImageHeaders_DebugData* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadRequest_PEImageHeaders_DebugData& from);
       void MergeFrom(const ClientDownloadRequest_PEImageHeaders_DebugData& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional bytes directory_entry = 1;
       inline bool has_directory_entry() const;
       inline void clear_directory_entry();
    @@ -574,7 +1612,8 @@ class ClientDownloadRequest_PEImageHeaders_DebugData : public ::google::protobuf
       inline void set_directory_entry(const void* value, size_t size);
       inline ::std::string* mutable_directory_entry();
       inline ::std::string* release_directory_entry();
    -  
    +  inline void set_allocated_directory_entry(::std::string* directory_entry);
    +
       // optional bytes raw_data = 2;
       inline bool has_raw_data() const;
       inline void clear_raw_data();
    @@ -585,24 +1624,29 @@ class ClientDownloadRequest_PEImageHeaders_DebugData : public ::google::protobuf
       inline void set_raw_data(const void* value, size_t size);
       inline ::std::string* mutable_raw_data();
       inline ::std::string* release_raw_data();
    -  
    +  inline void set_allocated_raw_data(::std::string* raw_data);
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData)
      private:
       inline void set_has_directory_entry();
       inline void clear_has_directory_entry();
       inline void set_has_raw_data();
       inline void clear_has_raw_data();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::std::string* directory_entry_;
       ::std::string* raw_data_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest_PEImageHeaders_DebugData* default_instance_;
     };
    @@ -612,47 +1656,65 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
      public:
       ClientDownloadRequest_PEImageHeaders();
       virtual ~ClientDownloadRequest_PEImageHeaders();
    -  
    +
       ClientDownloadRequest_PEImageHeaders(const ClientDownloadRequest_PEImageHeaders& from);
    -  
    +
       inline ClientDownloadRequest_PEImageHeaders& operator=(const ClientDownloadRequest_PEImageHeaders& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadRequest_PEImageHeaders& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_PEImageHeaders* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadRequest_PEImageHeaders* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadRequest_PEImageHeaders* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadRequest_PEImageHeaders& from);
       void MergeFrom(const ClientDownloadRequest_PEImageHeaders& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef ClientDownloadRequest_PEImageHeaders_DebugData DebugData;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional bytes dos_header = 1;
       inline bool has_dos_header() const;
       inline void clear_dos_header();
    @@ -663,7 +1725,8 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       inline void set_dos_header(const void* value, size_t size);
       inline ::std::string* mutable_dos_header();
       inline ::std::string* release_dos_header();
    -  
    +  inline void set_allocated_dos_header(::std::string* dos_header);
    +
       // optional bytes file_header = 2;
       inline bool has_file_header() const;
       inline void clear_file_header();
    @@ -674,7 +1737,8 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       inline void set_file_header(const void* value, size_t size);
       inline ::std::string* mutable_file_header();
       inline ::std::string* release_file_header();
    -  
    +  inline void set_allocated_file_header(::std::string* file_header);
    +
       // optional bytes optional_headers32 = 3;
       inline bool has_optional_headers32() const;
       inline void clear_optional_headers32();
    @@ -685,7 +1749,8 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       inline void set_optional_headers32(const void* value, size_t size);
       inline ::std::string* mutable_optional_headers32();
       inline ::std::string* release_optional_headers32();
    -  
    +  inline void set_allocated_optional_headers32(::std::string* optional_headers32);
    +
       // optional bytes optional_headers64 = 4;
       inline bool has_optional_headers64() const;
       inline void clear_optional_headers64();
    @@ -696,7 +1761,8 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       inline void set_optional_headers64(const void* value, size_t size);
       inline ::std::string* mutable_optional_headers64();
       inline ::std::string* release_optional_headers64();
    -  
    +  inline void set_allocated_optional_headers64(::std::string* optional_headers64);
    +
       // repeated bytes section_header = 5;
       inline int section_header_size() const;
       inline void clear_section_header();
    @@ -712,7 +1778,7 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       inline void add_section_header(const void* value, size_t size);
       inline const ::google::protobuf::RepeatedPtrField< ::std::string>& section_header() const;
       inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_section_header();
    -  
    +
       // optional bytes export_section_data = 6;
       inline bool has_export_section_data() const;
       inline void clear_export_section_data();
    @@ -723,7 +1789,8 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       inline void set_export_section_data(const void* value, size_t size);
       inline ::std::string* mutable_export_section_data();
       inline ::std::string* release_export_section_data();
    -  
    +  inline void set_allocated_export_section_data(::std::string* export_section_data);
    +
       // repeated .safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData debug_data = 7;
       inline int debug_data_size() const;
       inline void clear_debug_data();
    @@ -735,7 +1802,7 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
           debug_data() const;
       inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_PEImageHeaders_DebugData >*
           mutable_debug_data();
    -  
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.PEImageHeaders)
      private:
       inline void set_has_dos_header();
    @@ -748,7 +1815,11 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       inline void clear_has_optional_headers64();
       inline void set_has_export_section_data();
       inline void clear_has_export_section_data();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::std::string* dos_header_;
       ::std::string* file_header_;
       ::std::string* optional_headers32_;
    @@ -756,14 +1827,14 @@ class ClientDownloadRequest_PEImageHeaders : public ::google::protobuf::MessageL
       ::google::protobuf::RepeatedPtrField< ::std::string> section_header_;
       ::std::string* export_section_data_;
       ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_PEImageHeaders_DebugData > debug_data_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest_PEImageHeaders* default_instance_;
     };
    @@ -773,45 +1844,63 @@ class ClientDownloadRequest_ImageHeaders : public ::google::protobuf::MessageLit
      public:
       ClientDownloadRequest_ImageHeaders();
       virtual ~ClientDownloadRequest_ImageHeaders();
    -  
    +
       ClientDownloadRequest_ImageHeaders(const ClientDownloadRequest_ImageHeaders& from);
    -  
    +
       inline ClientDownloadRequest_ImageHeaders& operator=(const ClientDownloadRequest_ImageHeaders& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadRequest_ImageHeaders& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_ImageHeaders* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadRequest_ImageHeaders* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadRequest_ImageHeaders* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadRequest_ImageHeaders& from);
       void MergeFrom(const ClientDownloadRequest_ImageHeaders& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional .safe_browsing.ClientDownloadRequest.PEImageHeaders pe_headers = 1;
       inline bool has_pe_headers() const;
       inline void clear_pe_headers();
    @@ -819,74 +1908,250 @@ class ClientDownloadRequest_ImageHeaders : public ::google::protobuf::MessageLit
       inline const ::safe_browsing::ClientDownloadRequest_PEImageHeaders& pe_headers() const;
       inline ::safe_browsing::ClientDownloadRequest_PEImageHeaders* mutable_pe_headers();
       inline ::safe_browsing::ClientDownloadRequest_PEImageHeaders* release_pe_headers();
    -  
    +  inline void set_allocated_pe_headers(::safe_browsing::ClientDownloadRequest_PEImageHeaders* pe_headers);
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.ImageHeaders)
      private:
       inline void set_has_pe_headers();
       inline void clear_has_pe_headers();
    -  
    -  ::safe_browsing::ClientDownloadRequest_PEImageHeaders* pe_headers_;
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
       mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
    -  
    +  ::safe_browsing::ClientDownloadRequest_PEImageHeaders* pe_headers_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest_ImageHeaders* default_instance_;
     };
     // -------------------------------------------------------------------
     
    +class ClientDownloadRequest_ArchivedBinary : public ::google::protobuf::MessageLite {
    + public:
    +  ClientDownloadRequest_ArchivedBinary();
    +  virtual ~ClientDownloadRequest_ArchivedBinary();
    +
    +  ClientDownloadRequest_ArchivedBinary(const ClientDownloadRequest_ArchivedBinary& from);
    +
    +  inline ClientDownloadRequest_ArchivedBinary& operator=(const ClientDownloadRequest_ArchivedBinary& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientDownloadRequest_ArchivedBinary& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest_ArchivedBinary* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientDownloadRequest_ArchivedBinary* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientDownloadRequest_ArchivedBinary* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientDownloadRequest_ArchivedBinary& from);
    +  void MergeFrom(const ClientDownloadRequest_ArchivedBinary& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string file_basename = 1;
    +  inline bool has_file_basename() const;
    +  inline void clear_file_basename();
    +  static const int kFileBasenameFieldNumber = 1;
    +  inline const ::std::string& file_basename() const;
    +  inline void set_file_basename(const ::std::string& value);
    +  inline void set_file_basename(const char* value);
    +  inline void set_file_basename(const char* value, size_t size);
    +  inline ::std::string* mutable_file_basename();
    +  inline ::std::string* release_file_basename();
    +  inline void set_allocated_file_basename(::std::string* file_basename);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 2;
    +  inline bool has_download_type() const;
    +  inline void clear_download_type();
    +  static const int kDownloadTypeFieldNumber = 2;
    +  inline ::safe_browsing::ClientDownloadRequest_DownloadType download_type() const;
    +  inline void set_download_type(::safe_browsing::ClientDownloadRequest_DownloadType value);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.Digests digests = 3;
    +  inline bool has_digests() const;
    +  inline void clear_digests();
    +  static const int kDigestsFieldNumber = 3;
    +  inline const ::safe_browsing::ClientDownloadRequest_Digests& digests() const;
    +  inline ::safe_browsing::ClientDownloadRequest_Digests* mutable_digests();
    +  inline ::safe_browsing::ClientDownloadRequest_Digests* release_digests();
    +  inline void set_allocated_digests(::safe_browsing::ClientDownloadRequest_Digests* digests);
    +
    +  // optional int64 length = 4;
    +  inline bool has_length() const;
    +  inline void clear_length();
    +  static const int kLengthFieldNumber = 4;
    +  inline ::google::protobuf::int64 length() const;
    +  inline void set_length(::google::protobuf::int64 value);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +  inline bool has_signature() const;
    +  inline void clear_signature();
    +  static const int kSignatureFieldNumber = 5;
    +  inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& signature() const;
    +  inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* mutable_signature();
    +  inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* release_signature();
    +  inline void set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +  inline bool has_image_headers() const;
    +  inline void clear_image_headers();
    +  static const int kImageHeadersFieldNumber = 6;
    +  inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& image_headers() const;
    +  inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* mutable_image_headers();
    +  inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* release_image_headers();
    +  inline void set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest.ArchivedBinary)
    + private:
    +  inline void set_has_file_basename();
    +  inline void clear_has_file_basename();
    +  inline void set_has_download_type();
    +  inline void clear_has_download_type();
    +  inline void set_has_digests();
    +  inline void clear_has_digests();
    +  inline void set_has_length();
    +  inline void clear_has_length();
    +  inline void set_has_signature();
    +  inline void clear_has_signature();
    +  inline void set_has_image_headers();
    +  inline void clear_has_image_headers();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* file_basename_;
    +  ::safe_browsing::ClientDownloadRequest_Digests* digests_;
    +  ::google::protobuf::int64 length_;
    +  ::safe_browsing::ClientDownloadRequest_SignatureInfo* signature_;
    +  ::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers_;
    +  int download_type_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientDownloadRequest_ArchivedBinary* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
     class ClientDownloadRequest : public ::google::protobuf::MessageLite {
      public:
       ClientDownloadRequest();
       virtual ~ClientDownloadRequest();
    -  
    +
       ClientDownloadRequest(const ClientDownloadRequest& from);
    -  
    +
       inline ClientDownloadRequest& operator=(const ClientDownloadRequest& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadRequest& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadRequest* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadRequest* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadRequest* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadRequest& from);
       void MergeFrom(const ClientDownloadRequest& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef ClientDownloadRequest_Digests Digests;
       typedef ClientDownloadRequest_Resource Resource;
       typedef ClientDownloadRequest_CertificateChain CertificateChain;
       typedef ClientDownloadRequest_SignatureInfo SignatureInfo;
       typedef ClientDownloadRequest_PEImageHeaders PEImageHeaders;
       typedef ClientDownloadRequest_ImageHeaders ImageHeaders;
    -  
    +  typedef ClientDownloadRequest_ArchivedBinary ArchivedBinary;
    +
       typedef ClientDownloadRequest_ResourceType ResourceType;
       static const ResourceType DOWNLOAD_URL = ClientDownloadRequest_ResourceType_DOWNLOAD_URL;
       static const ResourceType DOWNLOAD_REDIRECT = ClientDownloadRequest_ResourceType_DOWNLOAD_REDIRECT;
    @@ -901,7 +2166,7 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
         ClientDownloadRequest_ResourceType_ResourceType_MAX;
       static const int ResourceType_ARRAYSIZE =
         ClientDownloadRequest_ResourceType_ResourceType_ARRAYSIZE;
    -  
    +
       typedef ClientDownloadRequest_DownloadType DownloadType;
       static const DownloadType WIN_EXECUTABLE = ClientDownloadRequest_DownloadType_WIN_EXECUTABLE;
       static const DownloadType CHROME_EXTENSION = ClientDownloadRequest_DownloadType_CHROME_EXTENSION;
    @@ -917,9 +2182,9 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
         ClientDownloadRequest_DownloadType_DownloadType_MAX;
       static const int DownloadType_ARRAYSIZE =
         ClientDownloadRequest_DownloadType_DownloadType_ARRAYSIZE;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // required string url = 1;
       inline bool has_url() const;
       inline void clear_url();
    @@ -930,7 +2195,8 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       inline void set_url(const char* value, size_t size);
       inline ::std::string* mutable_url();
       inline ::std::string* release_url();
    -  
    +  inline void set_allocated_url(::std::string* url);
    +
       // required .safe_browsing.ClientDownloadRequest.Digests digests = 2;
       inline bool has_digests() const;
       inline void clear_digests();
    @@ -938,14 +2204,15 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       inline const ::safe_browsing::ClientDownloadRequest_Digests& digests() const;
       inline ::safe_browsing::ClientDownloadRequest_Digests* mutable_digests();
       inline ::safe_browsing::ClientDownloadRequest_Digests* release_digests();
    -  
    +  inline void set_allocated_digests(::safe_browsing::ClientDownloadRequest_Digests* digests);
    +
       // required int64 length = 3;
       inline bool has_length() const;
       inline void clear_length();
       static const int kLengthFieldNumber = 3;
       inline ::google::protobuf::int64 length() const;
       inline void set_length(::google::protobuf::int64 value);
    -  
    +
       // repeated .safe_browsing.ClientDownloadRequest.Resource resources = 4;
       inline int resources_size() const;
       inline void clear_resources();
    @@ -957,7 +2224,7 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
           resources() const;
       inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_Resource >*
           mutable_resources();
    -  
    +
       // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
       inline bool has_signature() const;
       inline void clear_signature();
    @@ -965,14 +2232,15 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& signature() const;
       inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* mutable_signature();
       inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* release_signature();
    -  
    +  inline void set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature);
    +
       // optional bool user_initiated = 6;
       inline bool has_user_initiated() const;
       inline void clear_user_initiated();
       static const int kUserInitiatedFieldNumber = 6;
       inline bool user_initiated() const;
       inline void set_user_initiated(bool value);
    -  
    +
       // optional string file_basename = 9;
       inline bool has_file_basename() const;
       inline void clear_file_basename();
    @@ -983,14 +2251,15 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       inline void set_file_basename(const char* value, size_t size);
       inline ::std::string* mutable_file_basename();
       inline ::std::string* release_file_basename();
    -  
    +  inline void set_allocated_file_basename(::std::string* file_basename);
    +
       // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 10 [default = WIN_EXECUTABLE];
       inline bool has_download_type() const;
       inline void clear_download_type();
       static const int kDownloadTypeFieldNumber = 10;
       inline ::safe_browsing::ClientDownloadRequest_DownloadType download_type() const;
       inline void set_download_type(::safe_browsing::ClientDownloadRequest_DownloadType value);
    -  
    +
       // optional string locale = 11;
       inline bool has_locale() const;
       inline void clear_locale();
    @@ -1001,7 +2270,8 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       inline void set_locale(const char* value, size_t size);
       inline ::std::string* mutable_locale();
       inline ::std::string* release_locale();
    -  
    +  inline void set_allocated_locale(::std::string* locale);
    +
       // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 18;
       inline bool has_image_headers() const;
       inline void clear_image_headers();
    @@ -1009,7 +2279,20 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& image_headers() const;
       inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* mutable_image_headers();
       inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* release_image_headers();
    -  
    +  inline void set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers);
    +
    +  // repeated .safe_browsing.ClientDownloadRequest.ArchivedBinary archived_binary = 22;
    +  inline int archived_binary_size() const;
    +  inline void clear_archived_binary();
    +  static const int kArchivedBinaryFieldNumber = 22;
    +  inline const ::safe_browsing::ClientDownloadRequest_ArchivedBinary& archived_binary(int index) const;
    +  inline ::safe_browsing::ClientDownloadRequest_ArchivedBinary* mutable_archived_binary(int index);
    +  inline ::safe_browsing::ClientDownloadRequest_ArchivedBinary* add_archived_binary();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_ArchivedBinary >&
    +      archived_binary() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_ArchivedBinary >*
    +      mutable_archived_binary();
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadRequest)
      private:
       inline void set_has_url();
    @@ -1030,7 +2313,11 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       inline void clear_has_locale();
       inline void set_has_image_headers();
       inline void clear_has_image_headers();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::std::string* url_;
       ::safe_browsing::ClientDownloadRequest_Digests* digests_;
       ::google::protobuf::int64 length_;
    @@ -1041,14 +2328,15 @@ class ClientDownloadRequest : public ::google::protobuf::MessageLite {
       int download_type_;
       ::std::string* locale_;
       ::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(10 + 31) / 32];
    -  
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_ArchivedBinary > archived_binary_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadRequest* default_instance_;
     };
    @@ -1058,45 +2346,63 @@ class ClientDownloadResponse_MoreInfo : public ::google::protobuf::MessageLite {
      public:
       ClientDownloadResponse_MoreInfo();
       virtual ~ClientDownloadResponse_MoreInfo();
    -  
    +
       ClientDownloadResponse_MoreInfo(const ClientDownloadResponse_MoreInfo& from);
    -  
    +
       inline ClientDownloadResponse_MoreInfo& operator=(const ClientDownloadResponse_MoreInfo& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadResponse_MoreInfo& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadResponse_MoreInfo* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadResponse_MoreInfo* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadResponse_MoreInfo* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadResponse_MoreInfo& from);
       void MergeFrom(const ClientDownloadResponse_MoreInfo& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // optional string description = 1;
       inline bool has_description() const;
       inline void clear_description();
    @@ -1107,7 +2413,8 @@ class ClientDownloadResponse_MoreInfo : public ::google::protobuf::MessageLite {
       inline void set_description(const char* value, size_t size);
       inline ::std::string* mutable_description();
       inline ::std::string* release_description();
    -  
    +  inline void set_allocated_description(::std::string* description);
    +
       // optional string url = 2;
       inline bool has_url() const;
       inline void clear_url();
    @@ -1118,24 +2425,29 @@ class ClientDownloadResponse_MoreInfo : public ::google::protobuf::MessageLite {
       inline void set_url(const char* value, size_t size);
       inline ::std::string* mutable_url();
       inline ::std::string* release_url();
    -  
    +  inline void set_allocated_url(::std::string* url);
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadResponse.MoreInfo)
      private:
       inline void set_has_description();
       inline void clear_has_description();
       inline void set_has_url();
       inline void clear_has_url();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::std::string* description_;
       ::std::string* url_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadResponse_MoreInfo* default_instance_;
     };
    @@ -1145,45 +2457,63 @@ class ClientDownloadResponse : public ::google::protobuf::MessageLite {
      public:
       ClientDownloadResponse();
       virtual ~ClientDownloadResponse();
    -  
    +
       ClientDownloadResponse(const ClientDownloadResponse& from);
    -  
    +
       inline ClientDownloadResponse& operator=(const ClientDownloadResponse& from) {
         CopyFrom(from);
         return *this;
       }
    -  
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
       static const ClientDownloadResponse& default_instance();
    -  
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadResponse* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
       void Swap(ClientDownloadResponse* other);
    -  
    +
       // implements Message ----------------------------------------------
    -  
    +
       ClientDownloadResponse* New() const;
       void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
       void CopyFrom(const ClientDownloadResponse& from);
       void MergeFrom(const ClientDownloadResponse& from);
       void Clear();
       bool IsInitialized() const;
    -  
    +
       int ByteSize() const;
       bool MergePartialFromCodedStream(
           ::google::protobuf::io::CodedInputStream* input);
       void SerializeWithCachedSizes(
           ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
       int GetCachedSize() const { return _cached_size_; }
       private:
       void SharedCtor();
       void SharedDtor();
       void SetCachedSize(int size) const;
       public:
    -  
       ::std::string GetTypeName() const;
    -  
    +
       // nested types ----------------------------------------------------
    -  
    +
       typedef ClientDownloadResponse_MoreInfo MoreInfo;
    -  
    +
       typedef ClientDownloadResponse_Verdict Verdict;
       static const Verdict SAFE = ClientDownloadResponse_Verdict_SAFE;
       static const Verdict DANGEROUS = ClientDownloadResponse_Verdict_DANGEROUS;
    @@ -1199,16 +2529,16 @@ class ClientDownloadResponse : public ::google::protobuf::MessageLite {
         ClientDownloadResponse_Verdict_Verdict_MAX;
       static const int Verdict_ARRAYSIZE =
         ClientDownloadResponse_Verdict_Verdict_ARRAYSIZE;
    -  
    +
       // accessors -------------------------------------------------------
    -  
    +
       // required .safe_browsing.ClientDownloadResponse.Verdict verdict = 1;
       inline bool has_verdict() const;
       inline void clear_verdict();
       static const int kVerdictFieldNumber = 1;
       inline ::safe_browsing::ClientDownloadResponse_Verdict verdict() const;
       inline void set_verdict(::safe_browsing::ClientDownloadResponse_Verdict value);
    -  
    +
       // optional .safe_browsing.ClientDownloadResponse.MoreInfo more_info = 2;
       inline bool has_more_info() const;
       inline void clear_more_info();
    @@ -1216,7 +2546,8 @@ class ClientDownloadResponse : public ::google::protobuf::MessageLite {
       inline const ::safe_browsing::ClientDownloadResponse_MoreInfo& more_info() const;
       inline ::safe_browsing::ClientDownloadResponse_MoreInfo* mutable_more_info();
       inline ::safe_browsing::ClientDownloadResponse_MoreInfo* release_more_info();
    -  
    +  inline void set_allocated_more_info(::safe_browsing::ClientDownloadResponse_MoreInfo* more_info);
    +
       // optional bytes token = 3;
       inline bool has_token() const;
       inline void clear_token();
    @@ -1227,7 +2558,8 @@ class ClientDownloadResponse : public ::google::protobuf::MessageLite {
       inline void set_token(const void* value, size_t size);
       inline ::std::string* mutable_token();
       inline ::std::string* release_token();
    -  
    +  inline void set_allocated_token(::std::string* token);
    +
       // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadResponse)
      private:
       inline void set_has_verdict();
    @@ -1236,26 +2568,4107 @@ class ClientDownloadResponse : public ::google::protobuf::MessageLite {
       inline void clear_has_more_info();
       inline void set_has_token();
       inline void clear_has_token();
    -  
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
       ::safe_browsing::ClientDownloadResponse_MoreInfo* more_info_;
       ::std::string* token_;
       int verdict_;
    -  
    -  mutable int _cached_size_;
    -  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
    -  
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
       friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
       friend void protobuf_AssignDesc_csd_2eproto();
       friend void protobuf_ShutdownFile_csd_2eproto();
    -  
    +
       void InitAsDefaultInstance();
       static ClientDownloadResponse* default_instance_;
     };
    +// -------------------------------------------------------------------
    +
    +class ClientDownloadReport_UserInformation : public ::google::protobuf::MessageLite {
    + public:
    +  ClientDownloadReport_UserInformation();
    +  virtual ~ClientDownloadReport_UserInformation();
    +
    +  ClientDownloadReport_UserInformation(const ClientDownloadReport_UserInformation& from);
    +
    +  inline ClientDownloadReport_UserInformation& operator=(const ClientDownloadReport_UserInformation& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientDownloadReport_UserInformation& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadReport_UserInformation* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientDownloadReport_UserInformation* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientDownloadReport_UserInformation* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientDownloadReport_UserInformation& from);
    +  void MergeFrom(const ClientDownloadReport_UserInformation& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string email = 1;
    +  inline bool has_email() const;
    +  inline void clear_email();
    +  static const int kEmailFieldNumber = 1;
    +  inline const ::std::string& email() const;
    +  inline void set_email(const ::std::string& value);
    +  inline void set_email(const char* value);
    +  inline void set_email(const char* value, size_t size);
    +  inline ::std::string* mutable_email();
    +  inline ::std::string* release_email();
    +  inline void set_allocated_email(::std::string* email);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadReport.UserInformation)
    + private:
    +  inline void set_has_email();
    +  inline void clear_has_email();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* email_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientDownloadReport_UserInformation* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientDownloadReport : public ::google::protobuf::MessageLite {
    + public:
    +  ClientDownloadReport();
    +  virtual ~ClientDownloadReport();
    +
    +  ClientDownloadReport(const ClientDownloadReport& from);
    +
    +  inline ClientDownloadReport& operator=(const ClientDownloadReport& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientDownloadReport& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientDownloadReport* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientDownloadReport* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientDownloadReport* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientDownloadReport& from);
    +  void MergeFrom(const ClientDownloadReport& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientDownloadReport_UserInformation UserInformation;
    +
    +  typedef ClientDownloadReport_Reason Reason;
    +  static const Reason SHARE = ClientDownloadReport_Reason_SHARE;
    +  static const Reason FALSE_POSITIVE = ClientDownloadReport_Reason_FALSE_POSITIVE;
    +  static const Reason APPEAL = ClientDownloadReport_Reason_APPEAL;
    +  static inline bool Reason_IsValid(int value) {
    +    return ClientDownloadReport_Reason_IsValid(value);
    +  }
    +  static const Reason Reason_MIN =
    +    ClientDownloadReport_Reason_Reason_MIN;
    +  static const Reason Reason_MAX =
    +    ClientDownloadReport_Reason_Reason_MAX;
    +  static const int Reason_ARRAYSIZE =
    +    ClientDownloadReport_Reason_Reason_ARRAYSIZE;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional .safe_browsing.ClientDownloadReport.Reason reason = 1;
    +  inline bool has_reason() const;
    +  inline void clear_reason();
    +  static const int kReasonFieldNumber = 1;
    +  inline ::safe_browsing::ClientDownloadReport_Reason reason() const;
    +  inline void set_reason(::safe_browsing::ClientDownloadReport_Reason value);
    +
    +  // optional .safe_browsing.ClientDownloadRequest download_request = 2;
    +  inline bool has_download_request() const;
    +  inline void clear_download_request();
    +  static const int kDownloadRequestFieldNumber = 2;
    +  inline const ::safe_browsing::ClientDownloadRequest& download_request() const;
    +  inline ::safe_browsing::ClientDownloadRequest* mutable_download_request();
    +  inline ::safe_browsing::ClientDownloadRequest* release_download_request();
    +  inline void set_allocated_download_request(::safe_browsing::ClientDownloadRequest* download_request);
    +
    +  // optional .safe_browsing.ClientDownloadReport.UserInformation user_information = 3;
    +  inline bool has_user_information() const;
    +  inline void clear_user_information();
    +  static const int kUserInformationFieldNumber = 3;
    +  inline const ::safe_browsing::ClientDownloadReport_UserInformation& user_information() const;
    +  inline ::safe_browsing::ClientDownloadReport_UserInformation* mutable_user_information();
    +  inline ::safe_browsing::ClientDownloadReport_UserInformation* release_user_information();
    +  inline void set_allocated_user_information(::safe_browsing::ClientDownloadReport_UserInformation* user_information);
    +
    +  // optional bytes comment = 4;
    +  inline bool has_comment() const;
    +  inline void clear_comment();
    +  static const int kCommentFieldNumber = 4;
    +  inline const ::std::string& comment() const;
    +  inline void set_comment(const ::std::string& value);
    +  inline void set_comment(const char* value);
    +  inline void set_comment(const void* value, size_t size);
    +  inline ::std::string* mutable_comment();
    +  inline ::std::string* release_comment();
    +  inline void set_allocated_comment(::std::string* comment);
    +
    +  // optional .safe_browsing.ClientDownloadResponse download_response = 5;
    +  inline bool has_download_response() const;
    +  inline void clear_download_response();
    +  static const int kDownloadResponseFieldNumber = 5;
    +  inline const ::safe_browsing::ClientDownloadResponse& download_response() const;
    +  inline ::safe_browsing::ClientDownloadResponse* mutable_download_response();
    +  inline ::safe_browsing::ClientDownloadResponse* release_download_response();
    +  inline void set_allocated_download_response(::safe_browsing::ClientDownloadResponse* download_response);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientDownloadReport)
    + private:
    +  inline void set_has_reason();
    +  inline void clear_has_reason();
    +  inline void set_has_download_request();
    +  inline void clear_has_download_request();
    +  inline void set_has_user_information();
    +  inline void clear_has_user_information();
    +  inline void set_has_comment();
    +  inline void clear_has_comment();
    +  inline void set_has_download_response();
    +  inline void clear_has_download_response();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::safe_browsing::ClientDownloadRequest* download_request_;
    +  ::safe_browsing::ClientDownloadReport_UserInformation* user_information_;
    +  ::std::string* comment_;
    +  ::safe_browsing::ClientDownloadResponse* download_response_;
    +  int reason_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientDownloadReport* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientUploadResponse : public ::google::protobuf::MessageLite {
    + public:
    +  ClientUploadResponse();
    +  virtual ~ClientUploadResponse();
    +
    +  ClientUploadResponse(const ClientUploadResponse& from);
    +
    +  inline ClientUploadResponse& operator=(const ClientUploadResponse& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientUploadResponse& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientUploadResponse* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientUploadResponse* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientUploadResponse* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientUploadResponse& from);
    +  void MergeFrom(const ClientUploadResponse& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientUploadResponse_UploadStatus UploadStatus;
    +  static const UploadStatus SUCCESS = ClientUploadResponse_UploadStatus_SUCCESS;
    +  static const UploadStatus UPLOAD_FAILURE = ClientUploadResponse_UploadStatus_UPLOAD_FAILURE;
    +  static inline bool UploadStatus_IsValid(int value) {
    +    return ClientUploadResponse_UploadStatus_IsValid(value);
    +  }
    +  static const UploadStatus UploadStatus_MIN =
    +    ClientUploadResponse_UploadStatus_UploadStatus_MIN;
    +  static const UploadStatus UploadStatus_MAX =
    +    ClientUploadResponse_UploadStatus_UploadStatus_MAX;
    +  static const int UploadStatus_ARRAYSIZE =
    +    ClientUploadResponse_UploadStatus_UploadStatus_ARRAYSIZE;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional .safe_browsing.ClientUploadResponse.UploadStatus status = 1;
    +  inline bool has_status() const;
    +  inline void clear_status();
    +  static const int kStatusFieldNumber = 1;
    +  inline ::safe_browsing::ClientUploadResponse_UploadStatus status() const;
    +  inline void set_status(::safe_browsing::ClientUploadResponse_UploadStatus value);
    +
    +  // optional string permalink = 2;
    +  inline bool has_permalink() const;
    +  inline void clear_permalink();
    +  static const int kPermalinkFieldNumber = 2;
    +  inline const ::std::string& permalink() const;
    +  inline void set_permalink(const ::std::string& value);
    +  inline void set_permalink(const char* value);
    +  inline void set_permalink(const char* value, size_t size);
    +  inline ::std::string* mutable_permalink();
    +  inline ::std::string* release_permalink();
    +  inline void set_allocated_permalink(::std::string* permalink);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientUploadResponse)
    + private:
    +  inline void set_has_status();
    +  inline void clear_has_status();
    +  inline void set_has_permalink();
    +  inline void clear_has_permalink();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* permalink_;
    +  int status_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientUploadResponse* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_IncidentData_TrackedPreferenceIncident : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident();
    +  virtual ~ClientIncidentReport_IncidentData_TrackedPreferenceIncident();
    +
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident(const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& from);
    +
    +  inline ClientIncidentReport_IncidentData_TrackedPreferenceIncident& operator=(const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_IncidentData_TrackedPreferenceIncident* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_IncidentData_TrackedPreferenceIncident* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_IncidentData_TrackedPreferenceIncident* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& from);
    +  void MergeFrom(const ClientIncidentReport_IncidentData_TrackedPreferenceIncident& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ValueState;
    +  static const ValueState UNKNOWN = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_UNKNOWN;
    +  static const ValueState CLEARED = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_CLEARED;
    +  static const ValueState WEAK_LEGACY_OBSOLETE = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_WEAK_LEGACY_OBSOLETE;
    +  static const ValueState CHANGED = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_CHANGED;
    +  static const ValueState UNTRUSTED_UNKNOWN_VALUE = ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_UNTRUSTED_UNKNOWN_VALUE;
    +  static inline bool ValueState_IsValid(int value) {
    +    return ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_IsValid(value);
    +  }
    +  static const ValueState ValueState_MIN =
    +    ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_ValueState_MIN;
    +  static const ValueState ValueState_MAX =
    +    ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_ValueState_MAX;
    +  static const int ValueState_ARRAYSIZE =
    +    ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_ValueState_ARRAYSIZE;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string path = 1;
    +  inline bool has_path() const;
    +  inline void clear_path();
    +  static const int kPathFieldNumber = 1;
    +  inline const ::std::string& path() const;
    +  inline void set_path(const ::std::string& value);
    +  inline void set_path(const char* value);
    +  inline void set_path(const char* value, size_t size);
    +  inline ::std::string* mutable_path();
    +  inline ::std::string* release_path();
    +  inline void set_allocated_path(::std::string* path);
    +
    +  // optional string atomic_value = 2;
    +  inline bool has_atomic_value() const;
    +  inline void clear_atomic_value();
    +  static const int kAtomicValueFieldNumber = 2;
    +  inline const ::std::string& atomic_value() const;
    +  inline void set_atomic_value(const ::std::string& value);
    +  inline void set_atomic_value(const char* value);
    +  inline void set_atomic_value(const char* value, size_t size);
    +  inline ::std::string* mutable_atomic_value();
    +  inline ::std::string* release_atomic_value();
    +  inline void set_allocated_atomic_value(::std::string* atomic_value);
    +
    +  // repeated string split_key = 3;
    +  inline int split_key_size() const;
    +  inline void clear_split_key();
    +  static const int kSplitKeyFieldNumber = 3;
    +  inline const ::std::string& split_key(int index) const;
    +  inline ::std::string* mutable_split_key(int index);
    +  inline void set_split_key(int index, const ::std::string& value);
    +  inline void set_split_key(int index, const char* value);
    +  inline void set_split_key(int index, const char* value, size_t size);
    +  inline ::std::string* add_split_key();
    +  inline void add_split_key(const ::std::string& value);
    +  inline void add_split_key(const char* value);
    +  inline void add_split_key(const char* value, size_t size);
    +  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& split_key() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_split_key();
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.ValueState value_state = 4;
    +  inline bool has_value_state() const;
    +  inline void clear_value_state();
    +  static const int kValueStateFieldNumber = 4;
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState value_state() const;
    +  inline void set_value_state(::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState value);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident)
    + private:
    +  inline void set_has_path();
    +  inline void clear_has_path();
    +  inline void set_has_atomic_value();
    +  inline void clear_has_atomic_value();
    +  inline void set_has_value_state();
    +  inline void clear_has_value_state();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* path_;
    +  ::std::string* atomic_value_;
    +  ::google::protobuf::RepeatedPtrField< ::std::string> split_key_;
    +  int value_state_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_IncidentData_TrackedPreferenceIncident* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_IncidentData_BinaryIntegrityIncident : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_IncidentData_BinaryIntegrityIncident();
    +  virtual ~ClientIncidentReport_IncidentData_BinaryIntegrityIncident();
    +
    +  ClientIncidentReport_IncidentData_BinaryIntegrityIncident(const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& from);
    +
    +  inline ClientIncidentReport_IncidentData_BinaryIntegrityIncident& operator=(const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_IncidentData_BinaryIntegrityIncident* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_IncidentData_BinaryIntegrityIncident* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_IncidentData_BinaryIntegrityIncident* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& from);
    +  void MergeFrom(const ClientIncidentReport_IncidentData_BinaryIntegrityIncident& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string file_basename = 1;
    +  inline bool has_file_basename() const;
    +  inline void clear_file_basename();
    +  static const int kFileBasenameFieldNumber = 1;
    +  inline const ::std::string& file_basename() const;
    +  inline void set_file_basename(const ::std::string& value);
    +  inline void set_file_basename(const char* value);
    +  inline void set_file_basename(const char* value, size_t size);
    +  inline ::std::string* mutable_file_basename();
    +  inline ::std::string* release_file_basename();
    +  inline void set_allocated_file_basename(::std::string* file_basename);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 2;
    +  inline bool has_signature() const;
    +  inline void clear_signature();
    +  static const int kSignatureFieldNumber = 2;
    +  inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& signature() const;
    +  inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* mutable_signature();
    +  inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* release_signature();
    +  inline void set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident)
    + private:
    +  inline void set_has_file_basename();
    +  inline void clear_has_file_basename();
    +  inline void set_has_signature();
    +  inline void clear_has_signature();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* file_basename_;
    +  ::safe_browsing::ClientDownloadRequest_SignatureInfo* signature_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_IncidentData_BinaryIntegrityIncident* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_IncidentData_BlacklistLoadIncident : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_IncidentData_BlacklistLoadIncident();
    +  virtual ~ClientIncidentReport_IncidentData_BlacklistLoadIncident();
    +
    +  ClientIncidentReport_IncidentData_BlacklistLoadIncident(const ClientIncidentReport_IncidentData_BlacklistLoadIncident& from);
    +
    +  inline ClientIncidentReport_IncidentData_BlacklistLoadIncident& operator=(const ClientIncidentReport_IncidentData_BlacklistLoadIncident& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_IncidentData_BlacklistLoadIncident& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_IncidentData_BlacklistLoadIncident* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_IncidentData_BlacklistLoadIncident* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_IncidentData_BlacklistLoadIncident* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_IncidentData_BlacklistLoadIncident& from);
    +  void MergeFrom(const ClientIncidentReport_IncidentData_BlacklistLoadIncident& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string path = 1;
    +  inline bool has_path() const;
    +  inline void clear_path();
    +  static const int kPathFieldNumber = 1;
    +  inline const ::std::string& path() const;
    +  inline void set_path(const ::std::string& value);
    +  inline void set_path(const char* value);
    +  inline void set_path(const char* value, size_t size);
    +  inline ::std::string* mutable_path();
    +  inline ::std::string* release_path();
    +  inline void set_allocated_path(::std::string* path);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.Digests digest = 2;
    +  inline bool has_digest() const;
    +  inline void clear_digest();
    +  static const int kDigestFieldNumber = 2;
    +  inline const ::safe_browsing::ClientDownloadRequest_Digests& digest() const;
    +  inline ::safe_browsing::ClientDownloadRequest_Digests* mutable_digest();
    +  inline ::safe_browsing::ClientDownloadRequest_Digests* release_digest();
    +  inline void set_allocated_digest(::safe_browsing::ClientDownloadRequest_Digests* digest);
    +
    +  // optional string version = 3;
    +  inline bool has_version() const;
    +  inline void clear_version();
    +  static const int kVersionFieldNumber = 3;
    +  inline const ::std::string& version() const;
    +  inline void set_version(const ::std::string& value);
    +  inline void set_version(const char* value);
    +  inline void set_version(const char* value, size_t size);
    +  inline ::std::string* mutable_version();
    +  inline ::std::string* release_version();
    +  inline void set_allocated_version(::std::string* version);
    +
    +  // optional bool blacklist_initialized = 4;
    +  inline bool has_blacklist_initialized() const;
    +  inline void clear_blacklist_initialized();
    +  static const int kBlacklistInitializedFieldNumber = 4;
    +  inline bool blacklist_initialized() const;
    +  inline void set_blacklist_initialized(bool value);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +  inline bool has_signature() const;
    +  inline void clear_signature();
    +  static const int kSignatureFieldNumber = 5;
    +  inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& signature() const;
    +  inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* mutable_signature();
    +  inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* release_signature();
    +  inline void set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature);
    +
    +  // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +  inline bool has_image_headers() const;
    +  inline void clear_image_headers();
    +  static const int kImageHeadersFieldNumber = 6;
    +  inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& image_headers() const;
    +  inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* mutable_image_headers();
    +  inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* release_image_headers();
    +  inline void set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident)
    + private:
    +  inline void set_has_path();
    +  inline void clear_has_path();
    +  inline void set_has_digest();
    +  inline void clear_has_digest();
    +  inline void set_has_version();
    +  inline void clear_has_version();
    +  inline void set_has_blacklist_initialized();
    +  inline void clear_has_blacklist_initialized();
    +  inline void set_has_signature();
    +  inline void clear_has_signature();
    +  inline void set_has_image_headers();
    +  inline void clear_has_image_headers();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* path_;
    +  ::safe_browsing::ClientDownloadRequest_Digests* digest_;
    +  ::std::string* version_;
    +  ::safe_browsing::ClientDownloadRequest_SignatureInfo* signature_;
    +  ::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers_;
    +  bool blacklist_initialized_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_IncidentData_BlacklistLoadIncident* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident();
    +  virtual ~ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident();
    +
    +  ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident(const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& from);
    +
    +  inline ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& operator=(const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& from);
    +  void MergeFrom(const ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string variations_seed_signature = 1;
    +  inline bool has_variations_seed_signature() const;
    +  inline void clear_variations_seed_signature();
    +  static const int kVariationsSeedSignatureFieldNumber = 1;
    +  inline const ::std::string& variations_seed_signature() const;
    +  inline void set_variations_seed_signature(const ::std::string& value);
    +  inline void set_variations_seed_signature(const char* value);
    +  inline void set_variations_seed_signature(const char* value, size_t size);
    +  inline ::std::string* mutable_variations_seed_signature();
    +  inline ::std::string* release_variations_seed_signature();
    +  inline void set_allocated_variations_seed_signature(::std::string* variations_seed_signature);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident)
    + private:
    +  inline void set_has_variations_seed_signature();
    +  inline void clear_has_variations_seed_signature();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* variations_seed_signature_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_IncidentData_ScriptRequestIncident : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_IncidentData_ScriptRequestIncident();
    +  virtual ~ClientIncidentReport_IncidentData_ScriptRequestIncident();
    +
    +  ClientIncidentReport_IncidentData_ScriptRequestIncident(const ClientIncidentReport_IncidentData_ScriptRequestIncident& from);
    +
    +  inline ClientIncidentReport_IncidentData_ScriptRequestIncident& operator=(const ClientIncidentReport_IncidentData_ScriptRequestIncident& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_IncidentData_ScriptRequestIncident& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_IncidentData_ScriptRequestIncident* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_IncidentData_ScriptRequestIncident* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_IncidentData_ScriptRequestIncident* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_IncidentData_ScriptRequestIncident& from);
    +  void MergeFrom(const ClientIncidentReport_IncidentData_ScriptRequestIncident& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string script_digest = 1;
    +  inline bool has_script_digest() const;
    +  inline void clear_script_digest();
    +  static const int kScriptDigestFieldNumber = 1;
    +  inline const ::std::string& script_digest() const;
    +  inline void set_script_digest(const ::std::string& value);
    +  inline void set_script_digest(const char* value);
    +  inline void set_script_digest(const char* value, size_t size);
    +  inline ::std::string* mutable_script_digest();
    +  inline ::std::string* release_script_digest();
    +  inline void set_allocated_script_digest(::std::string* script_digest);
    +
    +  // optional string inclusion_origin = 2;
    +  inline bool has_inclusion_origin() const;
    +  inline void clear_inclusion_origin();
    +  static const int kInclusionOriginFieldNumber = 2;
    +  inline const ::std::string& inclusion_origin() const;
    +  inline void set_inclusion_origin(const ::std::string& value);
    +  inline void set_inclusion_origin(const char* value);
    +  inline void set_inclusion_origin(const char* value, size_t size);
    +  inline ::std::string* mutable_inclusion_origin();
    +  inline ::std::string* release_inclusion_origin();
    +  inline void set_allocated_inclusion_origin(::std::string* inclusion_origin);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident)
    + private:
    +  inline void set_has_script_digest();
    +  inline void clear_has_script_digest();
    +  inline void set_has_inclusion_origin();
    +  inline void clear_has_inclusion_origin();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* script_digest_;
    +  ::std::string* inclusion_origin_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_IncidentData_ScriptRequestIncident* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_IncidentData : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_IncidentData();
    +  virtual ~ClientIncidentReport_IncidentData();
    +
    +  ClientIncidentReport_IncidentData(const ClientIncidentReport_IncidentData& from);
    +
    +  inline ClientIncidentReport_IncidentData& operator=(const ClientIncidentReport_IncidentData& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_IncidentData& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_IncidentData* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_IncidentData* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_IncidentData* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_IncidentData& from);
    +  void MergeFrom(const ClientIncidentReport_IncidentData& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentReport_IncidentData_TrackedPreferenceIncident TrackedPreferenceIncident;
    +  typedef ClientIncidentReport_IncidentData_BinaryIntegrityIncident BinaryIntegrityIncident;
    +  typedef ClientIncidentReport_IncidentData_BlacklistLoadIncident BlacklistLoadIncident;
    +  typedef ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident VariationsSeedSignatureIncident;
    +  typedef ClientIncidentReport_IncidentData_ScriptRequestIncident ScriptRequestIncident;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional int64 incident_time_msec = 1;
    +  inline bool has_incident_time_msec() const;
    +  inline void clear_incident_time_msec();
    +  static const int kIncidentTimeMsecFieldNumber = 1;
    +  inline ::google::protobuf::int64 incident_time_msec() const;
    +  inline void set_incident_time_msec(::google::protobuf::int64 value);
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident tracked_preference = 2;
    +  inline bool has_tracked_preference() const;
    +  inline void clear_tracked_preference();
    +  static const int kTrackedPreferenceFieldNumber = 2;
    +  inline const ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident& tracked_preference() const;
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* mutable_tracked_preference();
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* release_tracked_preference();
    +  inline void set_allocated_tracked_preference(::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* tracked_preference);
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident binary_integrity = 3;
    +  inline bool has_binary_integrity() const;
    +  inline void clear_binary_integrity();
    +  static const int kBinaryIntegrityFieldNumber = 3;
    +  inline const ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident& binary_integrity() const;
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* mutable_binary_integrity();
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* release_binary_integrity();
    +  inline void set_allocated_binary_integrity(::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* binary_integrity);
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident blacklist_load = 4;
    +  inline bool has_blacklist_load() const;
    +  inline void clear_blacklist_load();
    +  static const int kBlacklistLoadFieldNumber = 4;
    +  inline const ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident& blacklist_load() const;
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* mutable_blacklist_load();
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* release_blacklist_load();
    +  inline void set_allocated_blacklist_load(::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* blacklist_load);
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident variations_seed_signature = 6;
    +  inline bool has_variations_seed_signature() const;
    +  inline void clear_variations_seed_signature();
    +  static const int kVariationsSeedSignatureFieldNumber = 6;
    +  inline const ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& variations_seed_signature() const;
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* mutable_variations_seed_signature();
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* release_variations_seed_signature();
    +  inline void set_allocated_variations_seed_signature(::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* variations_seed_signature);
    +
    +  // optional .safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident script_request = 7;
    +  inline bool has_script_request() const;
    +  inline void clear_script_request();
    +  static const int kScriptRequestFieldNumber = 7;
    +  inline const ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident& script_request() const;
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* mutable_script_request();
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* release_script_request();
    +  inline void set_allocated_script_request(::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* script_request);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.IncidentData)
    + private:
    +  inline void set_has_incident_time_msec();
    +  inline void clear_has_incident_time_msec();
    +  inline void set_has_tracked_preference();
    +  inline void clear_has_tracked_preference();
    +  inline void set_has_binary_integrity();
    +  inline void clear_has_binary_integrity();
    +  inline void set_has_blacklist_load();
    +  inline void clear_has_blacklist_load();
    +  inline void set_has_variations_seed_signature();
    +  inline void clear_has_variations_seed_signature();
    +  inline void set_has_script_request();
    +  inline void clear_has_script_request();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::int64 incident_time_msec_;
    +  ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* tracked_preference_;
    +  ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* binary_integrity_;
    +  ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* blacklist_load_;
    +  ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* variations_seed_signature_;
    +  ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* script_request_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_IncidentData* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_DownloadDetails : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_DownloadDetails();
    +  virtual ~ClientIncidentReport_DownloadDetails();
    +
    +  ClientIncidentReport_DownloadDetails(const ClientIncidentReport_DownloadDetails& from);
    +
    +  inline ClientIncidentReport_DownloadDetails& operator=(const ClientIncidentReport_DownloadDetails& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_DownloadDetails& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_DownloadDetails* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_DownloadDetails* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_DownloadDetails* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_DownloadDetails& from);
    +  void MergeFrom(const ClientIncidentReport_DownloadDetails& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bytes token = 1;
    +  inline bool has_token() const;
    +  inline void clear_token();
    +  static const int kTokenFieldNumber = 1;
    +  inline const ::std::string& token() const;
    +  inline void set_token(const ::std::string& value);
    +  inline void set_token(const char* value);
    +  inline void set_token(const void* value, size_t size);
    +  inline ::std::string* mutable_token();
    +  inline ::std::string* release_token();
    +  inline void set_allocated_token(::std::string* token);
    +
    +  // optional .safe_browsing.ClientDownloadRequest download = 2;
    +  inline bool has_download() const;
    +  inline void clear_download();
    +  static const int kDownloadFieldNumber = 2;
    +  inline const ::safe_browsing::ClientDownloadRequest& download() const;
    +  inline ::safe_browsing::ClientDownloadRequest* mutable_download();
    +  inline ::safe_browsing::ClientDownloadRequest* release_download();
    +  inline void set_allocated_download(::safe_browsing::ClientDownloadRequest* download);
    +
    +  // optional int64 download_time_msec = 3;
    +  inline bool has_download_time_msec() const;
    +  inline void clear_download_time_msec();
    +  static const int kDownloadTimeMsecFieldNumber = 3;
    +  inline ::google::protobuf::int64 download_time_msec() const;
    +  inline void set_download_time_msec(::google::protobuf::int64 value);
    +
    +  // optional int64 open_time_msec = 4;
    +  inline bool has_open_time_msec() const;
    +  inline void clear_open_time_msec();
    +  static const int kOpenTimeMsecFieldNumber = 4;
    +  inline ::google::protobuf::int64 open_time_msec() const;
    +  inline void set_open_time_msec(::google::protobuf::int64 value);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.DownloadDetails)
    + private:
    +  inline void set_has_token();
    +  inline void clear_has_token();
    +  inline void set_has_download();
    +  inline void clear_has_download();
    +  inline void set_has_download_time_msec();
    +  inline void clear_has_download_time_msec();
    +  inline void set_has_open_time_msec();
    +  inline void clear_has_open_time_msec();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* token_;
    +  ::safe_browsing::ClientDownloadRequest* download_;
    +  ::google::protobuf::int64 download_time_msec_;
    +  ::google::protobuf::int64 open_time_msec_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_DownloadDetails* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData_OS : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData_OS();
    +  virtual ~ClientIncidentReport_EnvironmentData_OS();
    +
    +  ClientIncidentReport_EnvironmentData_OS(const ClientIncidentReport_EnvironmentData_OS& from);
    +
    +  inline ClientIncidentReport_EnvironmentData_OS& operator=(const ClientIncidentReport_EnvironmentData_OS& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData_OS& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData_OS* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData_OS* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData_OS* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData_OS& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData_OS& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string os_name = 1;
    +  inline bool has_os_name() const;
    +  inline void clear_os_name();
    +  static const int kOsNameFieldNumber = 1;
    +  inline const ::std::string& os_name() const;
    +  inline void set_os_name(const ::std::string& value);
    +  inline void set_os_name(const char* value);
    +  inline void set_os_name(const char* value, size_t size);
    +  inline ::std::string* mutable_os_name();
    +  inline ::std::string* release_os_name();
    +  inline void set_allocated_os_name(::std::string* os_name);
    +
    +  // optional string os_version = 2;
    +  inline bool has_os_version() const;
    +  inline void clear_os_version();
    +  static const int kOsVersionFieldNumber = 2;
    +  inline const ::std::string& os_version() const;
    +  inline void set_os_version(const ::std::string& value);
    +  inline void set_os_version(const char* value);
    +  inline void set_os_version(const char* value, size_t size);
    +  inline ::std::string* mutable_os_version();
    +  inline ::std::string* release_os_version();
    +  inline void set_allocated_os_version(::std::string* os_version);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData.OS)
    + private:
    +  inline void set_has_os_name();
    +  inline void clear_has_os_name();
    +  inline void set_has_os_version();
    +  inline void clear_has_os_version();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* os_name_;
    +  ::std::string* os_version_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData_OS* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData_Machine : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData_Machine();
    +  virtual ~ClientIncidentReport_EnvironmentData_Machine();
    +
    +  ClientIncidentReport_EnvironmentData_Machine(const ClientIncidentReport_EnvironmentData_Machine& from);
    +
    +  inline ClientIncidentReport_EnvironmentData_Machine& operator=(const ClientIncidentReport_EnvironmentData_Machine& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData_Machine& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData_Machine* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData_Machine* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData_Machine* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData_Machine& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData_Machine& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string cpu_architecture = 1;
    +  inline bool has_cpu_architecture() const;
    +  inline void clear_cpu_architecture();
    +  static const int kCpuArchitectureFieldNumber = 1;
    +  inline const ::std::string& cpu_architecture() const;
    +  inline void set_cpu_architecture(const ::std::string& value);
    +  inline void set_cpu_architecture(const char* value);
    +  inline void set_cpu_architecture(const char* value, size_t size);
    +  inline ::std::string* mutable_cpu_architecture();
    +  inline ::std::string* release_cpu_architecture();
    +  inline void set_allocated_cpu_architecture(::std::string* cpu_architecture);
    +
    +  // optional string cpu_vendor = 2;
    +  inline bool has_cpu_vendor() const;
    +  inline void clear_cpu_vendor();
    +  static const int kCpuVendorFieldNumber = 2;
    +  inline const ::std::string& cpu_vendor() const;
    +  inline void set_cpu_vendor(const ::std::string& value);
    +  inline void set_cpu_vendor(const char* value);
    +  inline void set_cpu_vendor(const char* value, size_t size);
    +  inline ::std::string* mutable_cpu_vendor();
    +  inline ::std::string* release_cpu_vendor();
    +  inline void set_allocated_cpu_vendor(::std::string* cpu_vendor);
    +
    +  // optional uint32 cpuid = 3;
    +  inline bool has_cpuid() const;
    +  inline void clear_cpuid();
    +  static const int kCpuidFieldNumber = 3;
    +  inline ::google::protobuf::uint32 cpuid() const;
    +  inline void set_cpuid(::google::protobuf::uint32 value);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData.Machine)
    + private:
    +  inline void set_has_cpu_architecture();
    +  inline void clear_has_cpu_architecture();
    +  inline void set_has_cpu_vendor();
    +  inline void clear_has_cpu_vendor();
    +  inline void set_has_cpuid();
    +  inline void clear_has_cpuid();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* cpu_architecture_;
    +  ::std::string* cpu_vendor_;
    +  ::google::protobuf::uint32 cpuid_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData_Machine* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData_Process_Patch : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData_Process_Patch();
    +  virtual ~ClientIncidentReport_EnvironmentData_Process_Patch();
    +
    +  ClientIncidentReport_EnvironmentData_Process_Patch(const ClientIncidentReport_EnvironmentData_Process_Patch& from);
    +
    +  inline ClientIncidentReport_EnvironmentData_Process_Patch& operator=(const ClientIncidentReport_EnvironmentData_Process_Patch& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData_Process_Patch& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData_Process_Patch* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData_Process_Patch* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData_Process_Patch* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData_Process_Patch& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData_Process_Patch& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string function = 1;
    +  inline bool has_function() const;
    +  inline void clear_function();
    +  static const int kFunctionFieldNumber = 1;
    +  inline const ::std::string& function() const;
    +  inline void set_function(const ::std::string& value);
    +  inline void set_function(const char* value);
    +  inline void set_function(const char* value, size_t size);
    +  inline ::std::string* mutable_function();
    +  inline ::std::string* release_function();
    +  inline void set_allocated_function(::std::string* function);
    +
    +  // optional string target_dll = 2;
    +  inline bool has_target_dll() const;
    +  inline void clear_target_dll();
    +  static const int kTargetDllFieldNumber = 2;
    +  inline const ::std::string& target_dll() const;
    +  inline void set_target_dll(const ::std::string& value);
    +  inline void set_target_dll(const char* value);
    +  inline void set_target_dll(const char* value, size_t size);
    +  inline ::std::string* mutable_target_dll();
    +  inline ::std::string* release_target_dll();
    +  inline void set_allocated_target_dll(::std::string* target_dll);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch)
    + private:
    +  inline void set_has_function();
    +  inline void clear_has_function();
    +  inline void set_has_target_dll();
    +  inline void clear_has_target_dll();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* function_;
    +  ::std::string* target_dll_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData_Process_Patch* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData_Process_NetworkProvider : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData_Process_NetworkProvider();
    +  virtual ~ClientIncidentReport_EnvironmentData_Process_NetworkProvider();
    +
    +  ClientIncidentReport_EnvironmentData_Process_NetworkProvider(const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& from);
    +
    +  inline ClientIncidentReport_EnvironmentData_Process_NetworkProvider& operator=(const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData_Process_NetworkProvider* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData_Process_NetworkProvider* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData_Process_NetworkProvider* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData_Process_NetworkProvider& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider)
    + private:
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData_Process_NetworkProvider* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData_Process_Dll : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData_Process_Dll();
    +  virtual ~ClientIncidentReport_EnvironmentData_Process_Dll();
    +
    +  ClientIncidentReport_EnvironmentData_Process_Dll(const ClientIncidentReport_EnvironmentData_Process_Dll& from);
    +
    +  inline ClientIncidentReport_EnvironmentData_Process_Dll& operator=(const ClientIncidentReport_EnvironmentData_Process_Dll& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData_Process_Dll& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData_Process_Dll* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData_Process_Dll* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData_Process_Dll* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData_Process_Dll& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData_Process_Dll& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentReport_EnvironmentData_Process_Dll_Feature Feature;
    +  static const Feature UNKNOWN = ClientIncidentReport_EnvironmentData_Process_Dll_Feature_UNKNOWN;
    +  static const Feature LSP = ClientIncidentReport_EnvironmentData_Process_Dll_Feature_LSP;
    +  static inline bool Feature_IsValid(int value) {
    +    return ClientIncidentReport_EnvironmentData_Process_Dll_Feature_IsValid(value);
    +  }
    +  static const Feature Feature_MIN =
    +    ClientIncidentReport_EnvironmentData_Process_Dll_Feature_Feature_MIN;
    +  static const Feature Feature_MAX =
    +    ClientIncidentReport_EnvironmentData_Process_Dll_Feature_Feature_MAX;
    +  static const int Feature_ARRAYSIZE =
    +    ClientIncidentReport_EnvironmentData_Process_Dll_Feature_Feature_ARRAYSIZE;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string path = 1;
    +  inline bool has_path() const;
    +  inline void clear_path();
    +  static const int kPathFieldNumber = 1;
    +  inline const ::std::string& path() const;
    +  inline void set_path(const ::std::string& value);
    +  inline void set_path(const char* value);
    +  inline void set_path(const char* value, size_t size);
    +  inline ::std::string* mutable_path();
    +  inline ::std::string* release_path();
    +  inline void set_allocated_path(::std::string* path);
    +
    +  // optional uint64 base_address = 2;
    +  inline bool has_base_address() const;
    +  inline void clear_base_address();
    +  static const int kBaseAddressFieldNumber = 2;
    +  inline ::google::protobuf::uint64 base_address() const;
    +  inline void set_base_address(::google::protobuf::uint64 value);
    +
    +  // optional uint32 length = 3;
    +  inline bool has_length() const;
    +  inline void clear_length();
    +  static const int kLengthFieldNumber = 3;
    +  inline ::google::protobuf::uint32 length() const;
    +  inline void set_length(::google::protobuf::uint32 value);
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.Feature feature = 4;
    +  inline int feature_size() const;
    +  inline void clear_feature();
    +  static const int kFeatureFieldNumber = 4;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature feature(int index) const;
    +  inline void set_feature(int index, ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature value);
    +  inline void add_feature(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature value);
    +  inline const ::google::protobuf::RepeatedField& feature() const;
    +  inline ::google::protobuf::RepeatedField* mutable_feature();
    +
    +  // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 5;
    +  inline bool has_image_headers() const;
    +  inline void clear_image_headers();
    +  static const int kImageHeadersFieldNumber = 5;
    +  inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& image_headers() const;
    +  inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* mutable_image_headers();
    +  inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* release_image_headers();
    +  inline void set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll)
    + private:
    +  inline void set_has_path();
    +  inline void clear_has_path();
    +  inline void set_has_base_address();
    +  inline void clear_has_base_address();
    +  inline void set_has_length();
    +  inline void clear_has_length();
    +  inline void set_has_image_headers();
    +  inline void clear_has_image_headers();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* path_;
    +  ::google::protobuf::uint64 base_address_;
    +  ::google::protobuf::RepeatedField feature_;
    +  ::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers_;
    +  ::google::protobuf::uint32 length_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData_Process_Dll* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData_Process_ModuleState : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState();
    +  virtual ~ClientIncidentReport_EnvironmentData_Process_ModuleState();
    +
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState(const ClientIncidentReport_EnvironmentData_Process_ModuleState& from);
    +
    +  inline ClientIncidentReport_EnvironmentData_Process_ModuleState& operator=(const ClientIncidentReport_EnvironmentData_Process_ModuleState& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData_Process_ModuleState& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData_Process_ModuleState* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData_Process_ModuleState* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData_Process_ModuleState* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData_Process_ModuleState& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData_Process_ModuleState& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ModifiedState;
    +  static const ModifiedState UNKNOWN = ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_UNKNOWN;
    +  static const ModifiedState MODULE_STATE_UNKNOWN = ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_MODULE_STATE_UNKNOWN;
    +  static const ModifiedState MODULE_STATE_UNMODIFIED = ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_MODULE_STATE_UNMODIFIED;
    +  static const ModifiedState MODULE_STATE_MODIFIED = ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_MODULE_STATE_MODIFIED;
    +  static inline bool ModifiedState_IsValid(int value) {
    +    return ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_IsValid(value);
    +  }
    +  static const ModifiedState ModifiedState_MIN =
    +    ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_ModifiedState_MIN;
    +  static const ModifiedState ModifiedState_MAX =
    +    ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_ModifiedState_MAX;
    +  static const int ModifiedState_ARRAYSIZE =
    +    ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_ModifiedState_ARRAYSIZE;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.ModifiedState modified_state = 2;
    +  inline bool has_modified_state() const;
    +  inline void clear_modified_state();
    +  static const int kModifiedStateFieldNumber = 2;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState modified_state() const;
    +  inline void set_modified_state(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState value);
    +
    +  // repeated string modified_export = 3;
    +  inline int modified_export_size() const;
    +  inline void clear_modified_export();
    +  static const int kModifiedExportFieldNumber = 3;
    +  inline const ::std::string& modified_export(int index) const;
    +  inline ::std::string* mutable_modified_export(int index);
    +  inline void set_modified_export(int index, const ::std::string& value);
    +  inline void set_modified_export(int index, const char* value);
    +  inline void set_modified_export(int index, const char* value, size_t size);
    +  inline ::std::string* add_modified_export();
    +  inline void add_modified_export(const ::std::string& value);
    +  inline void add_modified_export(const char* value);
    +  inline void add_modified_export(const char* value, size_t size);
    +  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& modified_export() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_modified_export();
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_modified_state();
    +  inline void clear_has_modified_state();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::google::protobuf::RepeatedPtrField< ::std::string> modified_export_;
    +  int modified_state_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData_Process_ModuleState* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData_Process : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData_Process();
    +  virtual ~ClientIncidentReport_EnvironmentData_Process();
    +
    +  ClientIncidentReport_EnvironmentData_Process(const ClientIncidentReport_EnvironmentData_Process& from);
    +
    +  inline ClientIncidentReport_EnvironmentData_Process& operator=(const ClientIncidentReport_EnvironmentData_Process& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData_Process& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData_Process* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData_Process* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData_Process* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData_Process& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData_Process& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentReport_EnvironmentData_Process_Patch Patch;
    +  typedef ClientIncidentReport_EnvironmentData_Process_NetworkProvider NetworkProvider;
    +  typedef ClientIncidentReport_EnvironmentData_Process_Dll Dll;
    +  typedef ClientIncidentReport_EnvironmentData_Process_ModuleState ModuleState;
    +
    +  typedef ClientIncidentReport_EnvironmentData_Process_Channel Channel;
    +  static const Channel CHANNEL_UNKNOWN = ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_UNKNOWN;
    +  static const Channel CHANNEL_CANARY = ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_CANARY;
    +  static const Channel CHANNEL_DEV = ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_DEV;
    +  static const Channel CHANNEL_BETA = ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_BETA;
    +  static const Channel CHANNEL_STABLE = ClientIncidentReport_EnvironmentData_Process_Channel_CHANNEL_STABLE;
    +  static inline bool Channel_IsValid(int value) {
    +    return ClientIncidentReport_EnvironmentData_Process_Channel_IsValid(value);
    +  }
    +  static const Channel Channel_MIN =
    +    ClientIncidentReport_EnvironmentData_Process_Channel_Channel_MIN;
    +  static const Channel Channel_MAX =
    +    ClientIncidentReport_EnvironmentData_Process_Channel_Channel_MAX;
    +  static const int Channel_ARRAYSIZE =
    +    ClientIncidentReport_EnvironmentData_Process_Channel_Channel_ARRAYSIZE;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string version = 1;
    +  inline bool has_version() const;
    +  inline void clear_version();
    +  static const int kVersionFieldNumber = 1;
    +  inline const ::std::string& version() const;
    +  inline void set_version(const ::std::string& value);
    +  inline void set_version(const char* value);
    +  inline void set_version(const char* value, size_t size);
    +  inline ::std::string* mutable_version();
    +  inline ::std::string* release_version();
    +  inline void set_allocated_version(::std::string* version);
    +
    +  // repeated string OBSOLETE_dlls = 2;
    +  inline int obsolete_dlls_size() const;
    +  inline void clear_obsolete_dlls();
    +  static const int kOBSOLETEDllsFieldNumber = 2;
    +  inline const ::std::string& obsolete_dlls(int index) const;
    +  inline ::std::string* mutable_obsolete_dlls(int index);
    +  inline void set_obsolete_dlls(int index, const ::std::string& value);
    +  inline void set_obsolete_dlls(int index, const char* value);
    +  inline void set_obsolete_dlls(int index, const char* value, size_t size);
    +  inline ::std::string* add_obsolete_dlls();
    +  inline void add_obsolete_dlls(const ::std::string& value);
    +  inline void add_obsolete_dlls(const char* value);
    +  inline void add_obsolete_dlls(const char* value, size_t size);
    +  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& obsolete_dlls() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_obsolete_dlls();
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch patches = 3;
    +  inline int patches_size() const;
    +  inline void clear_patches();
    +  static const int kPatchesFieldNumber = 3;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch& patches(int index) const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch* mutable_patches(int index);
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch* add_patches();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch >&
    +      patches() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch >*
    +      mutable_patches();
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider network_providers = 4;
    +  inline int network_providers_size() const;
    +  inline void clear_network_providers();
    +  static const int kNetworkProvidersFieldNumber = 4;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider& network_providers(int index) const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider* mutable_network_providers(int index);
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider* add_network_providers();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider >&
    +      network_providers() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider >*
    +      mutable_network_providers();
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Channel chrome_update_channel = 5;
    +  inline bool has_chrome_update_channel() const;
    +  inline void clear_chrome_update_channel();
    +  static const int kChromeUpdateChannelFieldNumber = 5;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel chrome_update_channel() const;
    +  inline void set_chrome_update_channel(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel value);
    +
    +  // optional int64 uptime_msec = 6;
    +  inline bool has_uptime_msec() const;
    +  inline void clear_uptime_msec();
    +  static const int kUptimeMsecFieldNumber = 6;
    +  inline ::google::protobuf::int64 uptime_msec() const;
    +  inline void set_uptime_msec(::google::protobuf::int64 value);
    +
    +  // optional bool metrics_consent = 7;
    +  inline bool has_metrics_consent() const;
    +  inline void clear_metrics_consent();
    +  static const int kMetricsConsentFieldNumber = 7;
    +  inline bool metrics_consent() const;
    +  inline void set_metrics_consent(bool value);
    +
    +  // optional bool extended_consent = 8;
    +  inline bool has_extended_consent() const;
    +  inline void clear_extended_consent();
    +  static const int kExtendedConsentFieldNumber = 8;
    +  inline bool extended_consent() const;
    +  inline void set_extended_consent(bool value);
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll dll = 9;
    +  inline int dll_size() const;
    +  inline void clear_dll();
    +  static const int kDllFieldNumber = 9;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll& dll(int index) const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll* mutable_dll(int index);
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll* add_dll();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll >&
    +      dll() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll >*
    +      mutable_dll();
    +
    +  // repeated string blacklisted_dll = 10;
    +  inline int blacklisted_dll_size() const;
    +  inline void clear_blacklisted_dll();
    +  static const int kBlacklistedDllFieldNumber = 10;
    +  inline const ::std::string& blacklisted_dll(int index) const;
    +  inline ::std::string* mutable_blacklisted_dll(int index);
    +  inline void set_blacklisted_dll(int index, const ::std::string& value);
    +  inline void set_blacklisted_dll(int index, const char* value);
    +  inline void set_blacklisted_dll(int index, const char* value, size_t size);
    +  inline ::std::string* add_blacklisted_dll();
    +  inline void add_blacklisted_dll(const ::std::string& value);
    +  inline void add_blacklisted_dll(const char* value);
    +  inline void add_blacklisted_dll(const char* value, size_t size);
    +  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& blacklisted_dll() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_blacklisted_dll();
    +
    +  // repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState module_state = 11;
    +  inline int module_state_size() const;
    +  inline void clear_module_state();
    +  static const int kModuleStateFieldNumber = 11;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState& module_state(int index) const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState* mutable_module_state(int index);
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState* add_module_state();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState >&
    +      module_state() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState >*
    +      mutable_module_state();
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData.Process)
    + private:
    +  inline void set_has_version();
    +  inline void clear_has_version();
    +  inline void set_has_chrome_update_channel();
    +  inline void clear_has_chrome_update_channel();
    +  inline void set_has_uptime_msec();
    +  inline void clear_has_uptime_msec();
    +  inline void set_has_metrics_consent();
    +  inline void clear_has_metrics_consent();
    +  inline void set_has_extended_consent();
    +  inline void clear_has_extended_consent();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* version_;
    +  ::google::protobuf::RepeatedPtrField< ::std::string> obsolete_dlls_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch > patches_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider > network_providers_;
    +  ::google::protobuf::int64 uptime_msec_;
    +  int chrome_update_channel_;
    +  bool metrics_consent_;
    +  bool extended_consent_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll > dll_;
    +  ::google::protobuf::RepeatedPtrField< ::std::string> blacklisted_dll_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState > module_state_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData_Process* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport_EnvironmentData : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport_EnvironmentData();
    +  virtual ~ClientIncidentReport_EnvironmentData();
    +
    +  ClientIncidentReport_EnvironmentData(const ClientIncidentReport_EnvironmentData& from);
    +
    +  inline ClientIncidentReport_EnvironmentData& operator=(const ClientIncidentReport_EnvironmentData& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport_EnvironmentData& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport_EnvironmentData* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport_EnvironmentData* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport_EnvironmentData* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport_EnvironmentData& from);
    +  void MergeFrom(const ClientIncidentReport_EnvironmentData& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentReport_EnvironmentData_OS OS;
    +  typedef ClientIncidentReport_EnvironmentData_Machine Machine;
    +  typedef ClientIncidentReport_EnvironmentData_Process Process;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.OS os = 1;
    +  inline bool has_os() const;
    +  inline void clear_os();
    +  static const int kOsFieldNumber = 1;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_OS& os() const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_OS* mutable_os();
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_OS* release_os();
    +  inline void set_allocated_os(::safe_browsing::ClientIncidentReport_EnvironmentData_OS* os);
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Machine machine = 2;
    +  inline bool has_machine() const;
    +  inline void clear_machine();
    +  static const int kMachineFieldNumber = 2;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine& machine() const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* mutable_machine();
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* release_machine();
    +  inline void set_allocated_machine(::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* machine);
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process process = 3;
    +  inline bool has_process() const;
    +  inline void clear_process();
    +  static const int kProcessFieldNumber = 3;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process& process() const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process* mutable_process();
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process* release_process();
    +  inline void set_allocated_process(::safe_browsing::ClientIncidentReport_EnvironmentData_Process* process);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport.EnvironmentData)
    + private:
    +  inline void set_has_os();
    +  inline void clear_has_os();
    +  inline void set_has_machine();
    +  inline void clear_has_machine();
    +  inline void set_has_process();
    +  inline void clear_has_process();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData_OS* os_;
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* machine_;
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData_Process* process_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport_EnvironmentData* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentReport : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentReport();
    +  virtual ~ClientIncidentReport();
    +
    +  ClientIncidentReport(const ClientIncidentReport& from);
    +
    +  inline ClientIncidentReport& operator=(const ClientIncidentReport& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentReport& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentReport* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentReport* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentReport* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentReport& from);
    +  void MergeFrom(const ClientIncidentReport& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentReport_IncidentData IncidentData;
    +  typedef ClientIncidentReport_DownloadDetails DownloadDetails;
    +  typedef ClientIncidentReport_EnvironmentData EnvironmentData;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // repeated .safe_browsing.ClientIncidentReport.IncidentData incident = 1;
    +  inline int incident_size() const;
    +  inline void clear_incident();
    +  static const int kIncidentFieldNumber = 1;
    +  inline const ::safe_browsing::ClientIncidentReport_IncidentData& incident(int index) const;
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData* mutable_incident(int index);
    +  inline ::safe_browsing::ClientIncidentReport_IncidentData* add_incident();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_IncidentData >&
    +      incident() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_IncidentData >*
    +      mutable_incident();
    +
    +  // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +  inline bool has_download() const;
    +  inline void clear_download();
    +  static const int kDownloadFieldNumber = 2;
    +  inline const ::safe_browsing::ClientIncidentReport_DownloadDetails& download() const;
    +  inline ::safe_browsing::ClientIncidentReport_DownloadDetails* mutable_download();
    +  inline ::safe_browsing::ClientIncidentReport_DownloadDetails* release_download();
    +  inline void set_allocated_download(::safe_browsing::ClientIncidentReport_DownloadDetails* download);
    +
    +  // optional .safe_browsing.ClientIncidentReport.EnvironmentData environment = 3;
    +  inline bool has_environment() const;
    +  inline void clear_environment();
    +  static const int kEnvironmentFieldNumber = 3;
    +  inline const ::safe_browsing::ClientIncidentReport_EnvironmentData& environment() const;
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData* mutable_environment();
    +  inline ::safe_browsing::ClientIncidentReport_EnvironmentData* release_environment();
    +  inline void set_allocated_environment(::safe_browsing::ClientIncidentReport_EnvironmentData* environment);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentReport)
    + private:
    +  inline void set_has_download();
    +  inline void clear_has_download();
    +  inline void set_has_environment();
    +  inline void clear_has_environment();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_IncidentData > incident_;
    +  ::safe_browsing::ClientIncidentReport_DownloadDetails* download_;
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData* environment_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentReport* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentResponse_EnvironmentRequest : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentResponse_EnvironmentRequest();
    +  virtual ~ClientIncidentResponse_EnvironmentRequest();
    +
    +  ClientIncidentResponse_EnvironmentRequest(const ClientIncidentResponse_EnvironmentRequest& from);
    +
    +  inline ClientIncidentResponse_EnvironmentRequest& operator=(const ClientIncidentResponse_EnvironmentRequest& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentResponse_EnvironmentRequest& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentResponse_EnvironmentRequest* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentResponse_EnvironmentRequest* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentResponse_EnvironmentRequest* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentResponse_EnvironmentRequest& from);
    +  void MergeFrom(const ClientIncidentResponse_EnvironmentRequest& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional int32 dll_index = 1;
    +  inline bool has_dll_index() const;
    +  inline void clear_dll_index();
    +  static const int kDllIndexFieldNumber = 1;
    +  inline ::google::protobuf::int32 dll_index() const;
    +  inline void set_dll_index(::google::protobuf::int32 value);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentResponse.EnvironmentRequest)
    + private:
    +  inline void set_has_dll_index();
    +  inline void clear_has_dll_index();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::int32 dll_index_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentResponse_EnvironmentRequest* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class ClientIncidentResponse : public ::google::protobuf::MessageLite {
    + public:
    +  ClientIncidentResponse();
    +  virtual ~ClientIncidentResponse();
    +
    +  ClientIncidentResponse(const ClientIncidentResponse& from);
    +
    +  inline ClientIncidentResponse& operator=(const ClientIncidentResponse& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ClientIncidentResponse& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const ClientIncidentResponse* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(ClientIncidentResponse* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ClientIncidentResponse* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const ClientIncidentResponse& from);
    +  void MergeFrom(const ClientIncidentResponse& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef ClientIncidentResponse_EnvironmentRequest EnvironmentRequest;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bytes token = 1;
    +  inline bool has_token() const;
    +  inline void clear_token();
    +  static const int kTokenFieldNumber = 1;
    +  inline const ::std::string& token() const;
    +  inline void set_token(const ::std::string& value);
    +  inline void set_token(const char* value);
    +  inline void set_token(const void* value, size_t size);
    +  inline ::std::string* mutable_token();
    +  inline ::std::string* release_token();
    +  inline void set_allocated_token(::std::string* token);
    +
    +  // optional bool download_requested = 2;
    +  inline bool has_download_requested() const;
    +  inline void clear_download_requested();
    +  static const int kDownloadRequestedFieldNumber = 2;
    +  inline bool download_requested() const;
    +  inline void set_download_requested(bool value);
    +
    +  // repeated .safe_browsing.ClientIncidentResponse.EnvironmentRequest environment_requests = 3;
    +  inline int environment_requests_size() const;
    +  inline void clear_environment_requests();
    +  static const int kEnvironmentRequestsFieldNumber = 3;
    +  inline const ::safe_browsing::ClientIncidentResponse_EnvironmentRequest& environment_requests(int index) const;
    +  inline ::safe_browsing::ClientIncidentResponse_EnvironmentRequest* mutable_environment_requests(int index);
    +  inline ::safe_browsing::ClientIncidentResponse_EnvironmentRequest* add_environment_requests();
    +  inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentResponse_EnvironmentRequest >&
    +      environment_requests() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentResponse_EnvironmentRequest >*
    +      mutable_environment_requests();
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.ClientIncidentResponse)
    + private:
    +  inline void set_has_token();
    +  inline void clear_has_token();
    +  inline void set_has_download_requested();
    +  inline void clear_has_download_requested();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* token_;
    +  ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentResponse_EnvironmentRequest > environment_requests_;
    +  bool download_requested_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ClientIncidentResponse* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class DownloadMetadata : public ::google::protobuf::MessageLite {
    + public:
    +  DownloadMetadata();
    +  virtual ~DownloadMetadata();
    +
    +  DownloadMetadata(const DownloadMetadata& from);
    +
    +  inline DownloadMetadata& operator=(const DownloadMetadata& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::std::string& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::std::string* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const DownloadMetadata& default_instance();
    +
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  // Returns the internal default instance pointer. This function can
    +  // return NULL thus should not be used by the user. This is intended
    +  // for Protobuf internal code. Please use default_instance() declared
    +  // above instead.
    +  static inline const DownloadMetadata* internal_default_instance() {
    +    return default_instance_;
    +  }
    +  #endif
    +
    +  void Swap(DownloadMetadata* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  DownloadMetadata* New() const;
    +  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
    +  void CopyFrom(const DownloadMetadata& from);
    +  void MergeFrom(const DownloadMetadata& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  void DiscardUnknownFields();
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::std::string GetTypeName() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional uint32 download_id = 1;
    +  inline bool has_download_id() const;
    +  inline void clear_download_id();
    +  static const int kDownloadIdFieldNumber = 1;
    +  inline ::google::protobuf::uint32 download_id() const;
    +  inline void set_download_id(::google::protobuf::uint32 value);
    +
    +  // optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +  inline bool has_download() const;
    +  inline void clear_download();
    +  static const int kDownloadFieldNumber = 2;
    +  inline const ::safe_browsing::ClientIncidentReport_DownloadDetails& download() const;
    +  inline ::safe_browsing::ClientIncidentReport_DownloadDetails* mutable_download();
    +  inline ::safe_browsing::ClientIncidentReport_DownloadDetails* release_download();
    +  inline void set_allocated_download(::safe_browsing::ClientIncidentReport_DownloadDetails* download);
    +
    +  // @@protoc_insertion_point(class_scope:safe_browsing.DownloadMetadata)
    + private:
    +  inline void set_has_download_id();
    +  inline void clear_has_download_id();
    +  inline void set_has_download();
    +  inline void clear_has_download();
    +
    +  ::std::string _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::safe_browsing::ClientIncidentReport_DownloadDetails* download_;
    +  ::google::protobuf::uint32 download_id_;
    +  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  friend void  protobuf_AddDesc_csd_2eproto_impl();
    +  #else
    +  friend void  protobuf_AddDesc_csd_2eproto();
    +  #endif
    +  friend void protobuf_AssignDesc_csd_2eproto();
    +  friend void protobuf_ShutdownFile_csd_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static DownloadMetadata* default_instance_;
    +};
     // ===================================================================
     
     
     // ===================================================================
     
    +// ClientPhishingRequest_Feature
    +
    +// required string name = 1;
    +inline bool ClientPhishingRequest_Feature::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientPhishingRequest_Feature::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientPhishingRequest_Feature::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientPhishingRequest_Feature::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& ClientPhishingRequest_Feature::name() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.Feature.name)
    +  return *name_;
    +}
    +inline void ClientPhishingRequest_Feature::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.Feature.name)
    +}
    +inline void ClientPhishingRequest_Feature::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientPhishingRequest.Feature.name)
    +}
    +inline void ClientPhishingRequest_Feature::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientPhishingRequest.Feature.name)
    +}
    +inline ::std::string* ClientPhishingRequest_Feature::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientPhishingRequest.Feature.name)
    +  return name_;
    +}
    +inline ::std::string* ClientPhishingRequest_Feature::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientPhishingRequest_Feature::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientPhishingRequest.Feature.name)
    +}
    +
    +// required double value = 2;
    +inline bool ClientPhishingRequest_Feature::has_value() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientPhishingRequest_Feature::set_has_value() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientPhishingRequest_Feature::clear_has_value() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientPhishingRequest_Feature::clear_value() {
    +  value_ = 0;
    +  clear_has_value();
    +}
    +inline double ClientPhishingRequest_Feature::value() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.Feature.value)
    +  return value_;
    +}
    +inline void ClientPhishingRequest_Feature::set_value(double value) {
    +  set_has_value();
    +  value_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.Feature.value)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientPhishingRequest
    +
    +// optional string url = 1;
    +inline bool ClientPhishingRequest::has_url() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientPhishingRequest::set_has_url() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientPhishingRequest::clear_has_url() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientPhishingRequest::clear_url() {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_->clear();
    +  }
    +  clear_has_url();
    +}
    +inline const ::std::string& ClientPhishingRequest::url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.url)
    +  return *url_;
    +}
    +inline void ClientPhishingRequest::set_url(const ::std::string& value) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.url)
    +}
    +inline void ClientPhishingRequest::set_url(const char* value) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientPhishingRequest.url)
    +}
    +inline void ClientPhishingRequest::set_url(const char* value, size_t size) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientPhishingRequest.url)
    +}
    +inline ::std::string* ClientPhishingRequest::mutable_url() {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientPhishingRequest.url)
    +  return url_;
    +}
    +inline ::std::string* ClientPhishingRequest::release_url() {
    +  clear_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = url_;
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientPhishingRequest::set_allocated_url(::std::string* url) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (url) {
    +    set_has_url();
    +    url_ = url;
    +  } else {
    +    clear_has_url();
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientPhishingRequest.url)
    +}
    +
    +// optional bytes OBSOLETE_hash_prefix = 10;
    +inline bool ClientPhishingRequest::has_obsolete_hash_prefix() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientPhishingRequest::set_has_obsolete_hash_prefix() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientPhishingRequest::clear_has_obsolete_hash_prefix() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientPhishingRequest::clear_obsolete_hash_prefix() {
    +  if (obsolete_hash_prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_hash_prefix_->clear();
    +  }
    +  clear_has_obsolete_hash_prefix();
    +}
    +inline const ::std::string& ClientPhishingRequest::obsolete_hash_prefix() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.OBSOLETE_hash_prefix)
    +  return *obsolete_hash_prefix_;
    +}
    +inline void ClientPhishingRequest::set_obsolete_hash_prefix(const ::std::string& value) {
    +  set_has_obsolete_hash_prefix();
    +  if (obsolete_hash_prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_hash_prefix_ = new ::std::string;
    +  }
    +  obsolete_hash_prefix_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.OBSOLETE_hash_prefix)
    +}
    +inline void ClientPhishingRequest::set_obsolete_hash_prefix(const char* value) {
    +  set_has_obsolete_hash_prefix();
    +  if (obsolete_hash_prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_hash_prefix_ = new ::std::string;
    +  }
    +  obsolete_hash_prefix_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientPhishingRequest.OBSOLETE_hash_prefix)
    +}
    +inline void ClientPhishingRequest::set_obsolete_hash_prefix(const void* value, size_t size) {
    +  set_has_obsolete_hash_prefix();
    +  if (obsolete_hash_prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_hash_prefix_ = new ::std::string;
    +  }
    +  obsolete_hash_prefix_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientPhishingRequest.OBSOLETE_hash_prefix)
    +}
    +inline ::std::string* ClientPhishingRequest::mutable_obsolete_hash_prefix() {
    +  set_has_obsolete_hash_prefix();
    +  if (obsolete_hash_prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_hash_prefix_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientPhishingRequest.OBSOLETE_hash_prefix)
    +  return obsolete_hash_prefix_;
    +}
    +inline ::std::string* ClientPhishingRequest::release_obsolete_hash_prefix() {
    +  clear_has_obsolete_hash_prefix();
    +  if (obsolete_hash_prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = obsolete_hash_prefix_;
    +    obsolete_hash_prefix_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientPhishingRequest::set_allocated_obsolete_hash_prefix(::std::string* obsolete_hash_prefix) {
    +  if (obsolete_hash_prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete obsolete_hash_prefix_;
    +  }
    +  if (obsolete_hash_prefix) {
    +    set_has_obsolete_hash_prefix();
    +    obsolete_hash_prefix_ = obsolete_hash_prefix;
    +  } else {
    +    clear_has_obsolete_hash_prefix();
    +    obsolete_hash_prefix_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientPhishingRequest.OBSOLETE_hash_prefix)
    +}
    +
    +// required float client_score = 2;
    +inline bool ClientPhishingRequest::has_client_score() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientPhishingRequest::set_has_client_score() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientPhishingRequest::clear_has_client_score() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientPhishingRequest::clear_client_score() {
    +  client_score_ = 0;
    +  clear_has_client_score();
    +}
    +inline float ClientPhishingRequest::client_score() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.client_score)
    +  return client_score_;
    +}
    +inline void ClientPhishingRequest::set_client_score(float value) {
    +  set_has_client_score();
    +  client_score_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.client_score)
    +}
    +
    +// optional bool is_phishing = 4;
    +inline bool ClientPhishingRequest::has_is_phishing() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientPhishingRequest::set_has_is_phishing() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientPhishingRequest::clear_has_is_phishing() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientPhishingRequest::clear_is_phishing() {
    +  is_phishing_ = false;
    +  clear_has_is_phishing();
    +}
    +inline bool ClientPhishingRequest::is_phishing() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.is_phishing)
    +  return is_phishing_;
    +}
    +inline void ClientPhishingRequest::set_is_phishing(bool value) {
    +  set_has_is_phishing();
    +  is_phishing_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.is_phishing)
    +}
    +
    +// repeated .safe_browsing.ClientPhishingRequest.Feature feature_map = 5;
    +inline int ClientPhishingRequest::feature_map_size() const {
    +  return feature_map_.size();
    +}
    +inline void ClientPhishingRequest::clear_feature_map() {
    +  feature_map_.Clear();
    +}
    +inline const ::safe_browsing::ClientPhishingRequest_Feature& ClientPhishingRequest::feature_map(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.feature_map)
    +  return feature_map_.Get(index);
    +}
    +inline ::safe_browsing::ClientPhishingRequest_Feature* ClientPhishingRequest::mutable_feature_map(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientPhishingRequest.feature_map)
    +  return feature_map_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientPhishingRequest_Feature* ClientPhishingRequest::add_feature_map() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientPhishingRequest.feature_map)
    +  return feature_map_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >&
    +ClientPhishingRequest::feature_map() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientPhishingRequest.feature_map)
    +  return feature_map_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >*
    +ClientPhishingRequest::mutable_feature_map() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientPhishingRequest.feature_map)
    +  return &feature_map_;
    +}
    +
    +// optional int32 model_version = 6;
    +inline bool ClientPhishingRequest::has_model_version() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void ClientPhishingRequest::set_has_model_version() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void ClientPhishingRequest::clear_has_model_version() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void ClientPhishingRequest::clear_model_version() {
    +  model_version_ = 0;
    +  clear_has_model_version();
    +}
    +inline ::google::protobuf::int32 ClientPhishingRequest::model_version() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.model_version)
    +  return model_version_;
    +}
    +inline void ClientPhishingRequest::set_model_version(::google::protobuf::int32 value) {
    +  set_has_model_version();
    +  model_version_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.model_version)
    +}
    +
    +// repeated .safe_browsing.ClientPhishingRequest.Feature non_model_feature_map = 8;
    +inline int ClientPhishingRequest::non_model_feature_map_size() const {
    +  return non_model_feature_map_.size();
    +}
    +inline void ClientPhishingRequest::clear_non_model_feature_map() {
    +  non_model_feature_map_.Clear();
    +}
    +inline const ::safe_browsing::ClientPhishingRequest_Feature& ClientPhishingRequest::non_model_feature_map(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.non_model_feature_map)
    +  return non_model_feature_map_.Get(index);
    +}
    +inline ::safe_browsing::ClientPhishingRequest_Feature* ClientPhishingRequest::mutable_non_model_feature_map(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientPhishingRequest.non_model_feature_map)
    +  return non_model_feature_map_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientPhishingRequest_Feature* ClientPhishingRequest::add_non_model_feature_map() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientPhishingRequest.non_model_feature_map)
    +  return non_model_feature_map_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >&
    +ClientPhishingRequest::non_model_feature_map() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientPhishingRequest.non_model_feature_map)
    +  return non_model_feature_map_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientPhishingRequest_Feature >*
    +ClientPhishingRequest::mutable_non_model_feature_map() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientPhishingRequest.non_model_feature_map)
    +  return &non_model_feature_map_;
    +}
    +
    +// optional string OBSOLETE_referrer_url = 9;
    +inline bool ClientPhishingRequest::has_obsolete_referrer_url() const {
    +  return (_has_bits_[0] & 0x00000080u) != 0;
    +}
    +inline void ClientPhishingRequest::set_has_obsolete_referrer_url() {
    +  _has_bits_[0] |= 0x00000080u;
    +}
    +inline void ClientPhishingRequest::clear_has_obsolete_referrer_url() {
    +  _has_bits_[0] &= ~0x00000080u;
    +}
    +inline void ClientPhishingRequest::clear_obsolete_referrer_url() {
    +  if (obsolete_referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_referrer_url_->clear();
    +  }
    +  clear_has_obsolete_referrer_url();
    +}
    +inline const ::std::string& ClientPhishingRequest::obsolete_referrer_url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.OBSOLETE_referrer_url)
    +  return *obsolete_referrer_url_;
    +}
    +inline void ClientPhishingRequest::set_obsolete_referrer_url(const ::std::string& value) {
    +  set_has_obsolete_referrer_url();
    +  if (obsolete_referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_referrer_url_ = new ::std::string;
    +  }
    +  obsolete_referrer_url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.OBSOLETE_referrer_url)
    +}
    +inline void ClientPhishingRequest::set_obsolete_referrer_url(const char* value) {
    +  set_has_obsolete_referrer_url();
    +  if (obsolete_referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_referrer_url_ = new ::std::string;
    +  }
    +  obsolete_referrer_url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientPhishingRequest.OBSOLETE_referrer_url)
    +}
    +inline void ClientPhishingRequest::set_obsolete_referrer_url(const char* value, size_t size) {
    +  set_has_obsolete_referrer_url();
    +  if (obsolete_referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_referrer_url_ = new ::std::string;
    +  }
    +  obsolete_referrer_url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientPhishingRequest.OBSOLETE_referrer_url)
    +}
    +inline ::std::string* ClientPhishingRequest::mutable_obsolete_referrer_url() {
    +  set_has_obsolete_referrer_url();
    +  if (obsolete_referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    obsolete_referrer_url_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientPhishingRequest.OBSOLETE_referrer_url)
    +  return obsolete_referrer_url_;
    +}
    +inline ::std::string* ClientPhishingRequest::release_obsolete_referrer_url() {
    +  clear_has_obsolete_referrer_url();
    +  if (obsolete_referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = obsolete_referrer_url_;
    +    obsolete_referrer_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientPhishingRequest::set_allocated_obsolete_referrer_url(::std::string* obsolete_referrer_url) {
    +  if (obsolete_referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete obsolete_referrer_url_;
    +  }
    +  if (obsolete_referrer_url) {
    +    set_has_obsolete_referrer_url();
    +    obsolete_referrer_url_ = obsolete_referrer_url;
    +  } else {
    +    clear_has_obsolete_referrer_url();
    +    obsolete_referrer_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientPhishingRequest.OBSOLETE_referrer_url)
    +}
    +
    +// repeated uint32 shingle_hashes = 12 [packed = true];
    +inline int ClientPhishingRequest::shingle_hashes_size() const {
    +  return shingle_hashes_.size();
    +}
    +inline void ClientPhishingRequest::clear_shingle_hashes() {
    +  shingle_hashes_.Clear();
    +}
    +inline ::google::protobuf::uint32 ClientPhishingRequest::shingle_hashes(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingRequest.shingle_hashes)
    +  return shingle_hashes_.Get(index);
    +}
    +inline void ClientPhishingRequest::set_shingle_hashes(int index, ::google::protobuf::uint32 value) {
    +  shingle_hashes_.Set(index, value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingRequest.shingle_hashes)
    +}
    +inline void ClientPhishingRequest::add_shingle_hashes(::google::protobuf::uint32 value) {
    +  shingle_hashes_.Add(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientPhishingRequest.shingle_hashes)
    +}
    +inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
    +ClientPhishingRequest::shingle_hashes() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientPhishingRequest.shingle_hashes)
    +  return shingle_hashes_;
    +}
    +inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
    +ClientPhishingRequest::mutable_shingle_hashes() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientPhishingRequest.shingle_hashes)
    +  return &shingle_hashes_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientPhishingResponse
    +
    +// required bool phishy = 1;
    +inline bool ClientPhishingResponse::has_phishy() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientPhishingResponse::set_has_phishy() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientPhishingResponse::clear_has_phishy() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientPhishingResponse::clear_phishy() {
    +  phishy_ = false;
    +  clear_has_phishy();
    +}
    +inline bool ClientPhishingResponse::phishy() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingResponse.phishy)
    +  return phishy_;
    +}
    +inline void ClientPhishingResponse::set_phishy(bool value) {
    +  set_has_phishy();
    +  phishy_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingResponse.phishy)
    +}
    +
    +// repeated string OBSOLETE_whitelist_expression = 2;
    +inline int ClientPhishingResponse::obsolete_whitelist_expression_size() const {
    +  return obsolete_whitelist_expression_.size();
    +}
    +inline void ClientPhishingResponse::clear_obsolete_whitelist_expression() {
    +  obsolete_whitelist_expression_.Clear();
    +}
    +inline const ::std::string& ClientPhishingResponse::obsolete_whitelist_expression(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +  return obsolete_whitelist_expression_.Get(index);
    +}
    +inline ::std::string* ClientPhishingResponse::mutable_obsolete_whitelist_expression(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +  return obsolete_whitelist_expression_.Mutable(index);
    +}
    +inline void ClientPhishingResponse::set_obsolete_whitelist_expression(int index, const ::std::string& value) {
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +  obsolete_whitelist_expression_.Mutable(index)->assign(value);
    +}
    +inline void ClientPhishingResponse::set_obsolete_whitelist_expression(int index, const char* value) {
    +  obsolete_whitelist_expression_.Mutable(index)->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +}
    +inline void ClientPhishingResponse::set_obsolete_whitelist_expression(int index, const char* value, size_t size) {
    +  obsolete_whitelist_expression_.Mutable(index)->assign(
    +    reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +}
    +inline ::std::string* ClientPhishingResponse::add_obsolete_whitelist_expression() {
    +  return obsolete_whitelist_expression_.Add();
    +}
    +inline void ClientPhishingResponse::add_obsolete_whitelist_expression(const ::std::string& value) {
    +  obsolete_whitelist_expression_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +}
    +inline void ClientPhishingResponse::add_obsolete_whitelist_expression(const char* value) {
    +  obsolete_whitelist_expression_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add_char:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +}
    +inline void ClientPhishingResponse::add_obsolete_whitelist_expression(const char* value, size_t size) {
    +  obsolete_whitelist_expression_.Add()->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_add_pointer:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
    +ClientPhishingResponse::obsolete_whitelist_expression() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +  return obsolete_whitelist_expression_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::std::string>*
    +ClientPhishingResponse::mutable_obsolete_whitelist_expression() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientPhishingResponse.OBSOLETE_whitelist_expression)
    +  return &obsolete_whitelist_expression_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientMalwareRequest_UrlInfo
    +
    +// required string ip = 1;
    +inline bool ClientMalwareRequest_UrlInfo::has_ip() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_has_ip() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_has_ip() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_ip() {
    +  if (ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    ip_->clear();
    +  }
    +  clear_has_ip();
    +}
    +inline const ::std::string& ClientMalwareRequest_UrlInfo::ip() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.UrlInfo.ip)
    +  return *ip_;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_ip(const ::std::string& value) {
    +  set_has_ip();
    +  if (ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    ip_ = new ::std::string;
    +  }
    +  ip_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareRequest.UrlInfo.ip)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_ip(const char* value) {
    +  set_has_ip();
    +  if (ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    ip_ = new ::std::string;
    +  }
    +  ip_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareRequest.UrlInfo.ip)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_ip(const char* value, size_t size) {
    +  set_has_ip();
    +  if (ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    ip_ = new ::std::string;
    +  }
    +  ip_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareRequest.UrlInfo.ip)
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::mutable_ip() {
    +  set_has_ip();
    +  if (ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    ip_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareRequest.UrlInfo.ip)
    +  return ip_;
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::release_ip() {
    +  clear_has_ip();
    +  if (ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = ip_;
    +    ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_allocated_ip(::std::string* ip) {
    +  if (ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete ip_;
    +  }
    +  if (ip) {
    +    set_has_ip();
    +    ip_ = ip;
    +  } else {
    +    clear_has_ip();
    +    ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareRequest.UrlInfo.ip)
    +}
    +
    +// required string url = 2;
    +inline bool ClientMalwareRequest_UrlInfo::has_url() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_has_url() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_has_url() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_url() {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_->clear();
    +  }
    +  clear_has_url();
    +}
    +inline const ::std::string& ClientMalwareRequest_UrlInfo::url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.UrlInfo.url)
    +  return *url_;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_url(const ::std::string& value) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareRequest.UrlInfo.url)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_url(const char* value) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareRequest.UrlInfo.url)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_url(const char* value, size_t size) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareRequest.UrlInfo.url)
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::mutable_url() {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareRequest.UrlInfo.url)
    +  return url_;
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::release_url() {
    +  clear_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = url_;
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_allocated_url(::std::string* url) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (url) {
    +    set_has_url();
    +    url_ = url;
    +  } else {
    +    clear_has_url();
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareRequest.UrlInfo.url)
    +}
    +
    +// optional string method = 3;
    +inline bool ClientMalwareRequest_UrlInfo::has_method() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_has_method() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_has_method() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_method() {
    +  if (method_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    method_->clear();
    +  }
    +  clear_has_method();
    +}
    +inline const ::std::string& ClientMalwareRequest_UrlInfo::method() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.UrlInfo.method)
    +  return *method_;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_method(const ::std::string& value) {
    +  set_has_method();
    +  if (method_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    method_ = new ::std::string;
    +  }
    +  method_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareRequest.UrlInfo.method)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_method(const char* value) {
    +  set_has_method();
    +  if (method_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    method_ = new ::std::string;
    +  }
    +  method_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareRequest.UrlInfo.method)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_method(const char* value, size_t size) {
    +  set_has_method();
    +  if (method_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    method_ = new ::std::string;
    +  }
    +  method_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareRequest.UrlInfo.method)
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::mutable_method() {
    +  set_has_method();
    +  if (method_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    method_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareRequest.UrlInfo.method)
    +  return method_;
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::release_method() {
    +  clear_has_method();
    +  if (method_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = method_;
    +    method_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_allocated_method(::std::string* method) {
    +  if (method_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete method_;
    +  }
    +  if (method) {
    +    set_has_method();
    +    method_ = method;
    +  } else {
    +    clear_has_method();
    +    method_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareRequest.UrlInfo.method)
    +}
    +
    +// optional string referrer = 4;
    +inline bool ClientMalwareRequest_UrlInfo::has_referrer() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_has_referrer() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_has_referrer() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_referrer() {
    +  if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_->clear();
    +  }
    +  clear_has_referrer();
    +}
    +inline const ::std::string& ClientMalwareRequest_UrlInfo::referrer() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.UrlInfo.referrer)
    +  return *referrer_;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_referrer(const ::std::string& value) {
    +  set_has_referrer();
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_ = new ::std::string;
    +  }
    +  referrer_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareRequest.UrlInfo.referrer)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_referrer(const char* value) {
    +  set_has_referrer();
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_ = new ::std::string;
    +  }
    +  referrer_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareRequest.UrlInfo.referrer)
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_referrer(const char* value, size_t size) {
    +  set_has_referrer();
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_ = new ::std::string;
    +  }
    +  referrer_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareRequest.UrlInfo.referrer)
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::mutable_referrer() {
    +  set_has_referrer();
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareRequest.UrlInfo.referrer)
    +  return referrer_;
    +}
    +inline ::std::string* ClientMalwareRequest_UrlInfo::release_referrer() {
    +  clear_has_referrer();
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = referrer_;
    +    referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_allocated_referrer(::std::string* referrer) {
    +  if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete referrer_;
    +  }
    +  if (referrer) {
    +    set_has_referrer();
    +    referrer_ = referrer;
    +  } else {
    +    clear_has_referrer();
    +    referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareRequest.UrlInfo.referrer)
    +}
    +
    +// optional int32 resource_type = 5;
    +inline bool ClientMalwareRequest_UrlInfo::has_resource_type() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_has_resource_type() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_has_resource_type() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void ClientMalwareRequest_UrlInfo::clear_resource_type() {
    +  resource_type_ = 0;
    +  clear_has_resource_type();
    +}
    +inline ::google::protobuf::int32 ClientMalwareRequest_UrlInfo::resource_type() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.UrlInfo.resource_type)
    +  return resource_type_;
    +}
    +inline void ClientMalwareRequest_UrlInfo::set_resource_type(::google::protobuf::int32 value) {
    +  set_has_resource_type();
    +  resource_type_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareRequest.UrlInfo.resource_type)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientMalwareRequest
    +
    +// required string url = 1;
    +inline bool ClientMalwareRequest::has_url() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientMalwareRequest::set_has_url() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientMalwareRequest::clear_has_url() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientMalwareRequest::clear_url() {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_->clear();
    +  }
    +  clear_has_url();
    +}
    +inline const ::std::string& ClientMalwareRequest::url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.url)
    +  return *url_;
    +}
    +inline void ClientMalwareRequest::set_url(const ::std::string& value) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareRequest.url)
    +}
    +inline void ClientMalwareRequest::set_url(const char* value) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareRequest.url)
    +}
    +inline void ClientMalwareRequest::set_url(const char* value, size_t size) {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareRequest.url)
    +}
    +inline ::std::string* ClientMalwareRequest::mutable_url() {
    +  set_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    url_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareRequest.url)
    +  return url_;
    +}
    +inline ::std::string* ClientMalwareRequest::release_url() {
    +  clear_has_url();
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = url_;
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareRequest::set_allocated_url(::std::string* url) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (url) {
    +    set_has_url();
    +    url_ = url;
    +  } else {
    +    clear_has_url();
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareRequest.url)
    +}
    +
    +// optional string referrer_url = 4;
    +inline bool ClientMalwareRequest::has_referrer_url() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientMalwareRequest::set_has_referrer_url() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientMalwareRequest::clear_has_referrer_url() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientMalwareRequest::clear_referrer_url() {
    +  if (referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_url_->clear();
    +  }
    +  clear_has_referrer_url();
    +}
    +inline const ::std::string& ClientMalwareRequest::referrer_url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.referrer_url)
    +  return *referrer_url_;
    +}
    +inline void ClientMalwareRequest::set_referrer_url(const ::std::string& value) {
    +  set_has_referrer_url();
    +  if (referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_url_ = new ::std::string;
    +  }
    +  referrer_url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareRequest.referrer_url)
    +}
    +inline void ClientMalwareRequest::set_referrer_url(const char* value) {
    +  set_has_referrer_url();
    +  if (referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_url_ = new ::std::string;
    +  }
    +  referrer_url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareRequest.referrer_url)
    +}
    +inline void ClientMalwareRequest::set_referrer_url(const char* value, size_t size) {
    +  set_has_referrer_url();
    +  if (referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_url_ = new ::std::string;
    +  }
    +  referrer_url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareRequest.referrer_url)
    +}
    +inline ::std::string* ClientMalwareRequest::mutable_referrer_url() {
    +  set_has_referrer_url();
    +  if (referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    referrer_url_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareRequest.referrer_url)
    +  return referrer_url_;
    +}
    +inline ::std::string* ClientMalwareRequest::release_referrer_url() {
    +  clear_has_referrer_url();
    +  if (referrer_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = referrer_url_;
    +    referrer_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareRequest::set_allocated_referrer_url(::std::string* referrer_url) {
    +  if (referrer_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete referrer_url_;
    +  }
    +  if (referrer_url) {
    +    set_has_referrer_url();
    +    referrer_url_ = referrer_url;
    +  } else {
    +    clear_has_referrer_url();
    +    referrer_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareRequest.referrer_url)
    +}
    +
    +// repeated .safe_browsing.ClientMalwareRequest.UrlInfo bad_ip_url_info = 7;
    +inline int ClientMalwareRequest::bad_ip_url_info_size() const {
    +  return bad_ip_url_info_.size();
    +}
    +inline void ClientMalwareRequest::clear_bad_ip_url_info() {
    +  bad_ip_url_info_.Clear();
    +}
    +inline const ::safe_browsing::ClientMalwareRequest_UrlInfo& ClientMalwareRequest::bad_ip_url_info(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareRequest.bad_ip_url_info)
    +  return bad_ip_url_info_.Get(index);
    +}
    +inline ::safe_browsing::ClientMalwareRequest_UrlInfo* ClientMalwareRequest::mutable_bad_ip_url_info(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareRequest.bad_ip_url_info)
    +  return bad_ip_url_info_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientMalwareRequest_UrlInfo* ClientMalwareRequest::add_bad_ip_url_info() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientMalwareRequest.bad_ip_url_info)
    +  return bad_ip_url_info_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientMalwareRequest_UrlInfo >&
    +ClientMalwareRequest::bad_ip_url_info() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientMalwareRequest.bad_ip_url_info)
    +  return bad_ip_url_info_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientMalwareRequest_UrlInfo >*
    +ClientMalwareRequest::mutable_bad_ip_url_info() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientMalwareRequest.bad_ip_url_info)
    +  return &bad_ip_url_info_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientMalwareResponse
    +
    +// required bool blacklist = 1;
    +inline bool ClientMalwareResponse::has_blacklist() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientMalwareResponse::set_has_blacklist() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientMalwareResponse::clear_has_blacklist() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientMalwareResponse::clear_blacklist() {
    +  blacklist_ = false;
    +  clear_has_blacklist();
    +}
    +inline bool ClientMalwareResponse::blacklist() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareResponse.blacklist)
    +  return blacklist_;
    +}
    +inline void ClientMalwareResponse::set_blacklist(bool value) {
    +  set_has_blacklist();
    +  blacklist_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareResponse.blacklist)
    +}
    +
    +// optional string bad_ip = 2;
    +inline bool ClientMalwareResponse::has_bad_ip() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientMalwareResponse::set_has_bad_ip() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientMalwareResponse::clear_has_bad_ip() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientMalwareResponse::clear_bad_ip() {
    +  if (bad_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_ip_->clear();
    +  }
    +  clear_has_bad_ip();
    +}
    +inline const ::std::string& ClientMalwareResponse::bad_ip() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareResponse.bad_ip)
    +  return *bad_ip_;
    +}
    +inline void ClientMalwareResponse::set_bad_ip(const ::std::string& value) {
    +  set_has_bad_ip();
    +  if (bad_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_ip_ = new ::std::string;
    +  }
    +  bad_ip_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareResponse.bad_ip)
    +}
    +inline void ClientMalwareResponse::set_bad_ip(const char* value) {
    +  set_has_bad_ip();
    +  if (bad_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_ip_ = new ::std::string;
    +  }
    +  bad_ip_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareResponse.bad_ip)
    +}
    +inline void ClientMalwareResponse::set_bad_ip(const char* value, size_t size) {
    +  set_has_bad_ip();
    +  if (bad_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_ip_ = new ::std::string;
    +  }
    +  bad_ip_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareResponse.bad_ip)
    +}
    +inline ::std::string* ClientMalwareResponse::mutable_bad_ip() {
    +  set_has_bad_ip();
    +  if (bad_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_ip_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareResponse.bad_ip)
    +  return bad_ip_;
    +}
    +inline ::std::string* ClientMalwareResponse::release_bad_ip() {
    +  clear_has_bad_ip();
    +  if (bad_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = bad_ip_;
    +    bad_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareResponse::set_allocated_bad_ip(::std::string* bad_ip) {
    +  if (bad_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete bad_ip_;
    +  }
    +  if (bad_ip) {
    +    set_has_bad_ip();
    +    bad_ip_ = bad_ip;
    +  } else {
    +    clear_has_bad_ip();
    +    bad_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareResponse.bad_ip)
    +}
    +
    +// optional string bad_url = 3;
    +inline bool ClientMalwareResponse::has_bad_url() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientMalwareResponse::set_has_bad_url() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientMalwareResponse::clear_has_bad_url() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientMalwareResponse::clear_bad_url() {
    +  if (bad_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_url_->clear();
    +  }
    +  clear_has_bad_url();
    +}
    +inline const ::std::string& ClientMalwareResponse::bad_url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientMalwareResponse.bad_url)
    +  return *bad_url_;
    +}
    +inline void ClientMalwareResponse::set_bad_url(const ::std::string& value) {
    +  set_has_bad_url();
    +  if (bad_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_url_ = new ::std::string;
    +  }
    +  bad_url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientMalwareResponse.bad_url)
    +}
    +inline void ClientMalwareResponse::set_bad_url(const char* value) {
    +  set_has_bad_url();
    +  if (bad_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_url_ = new ::std::string;
    +  }
    +  bad_url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientMalwareResponse.bad_url)
    +}
    +inline void ClientMalwareResponse::set_bad_url(const char* value, size_t size) {
    +  set_has_bad_url();
    +  if (bad_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_url_ = new ::std::string;
    +  }
    +  bad_url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientMalwareResponse.bad_url)
    +}
    +inline ::std::string* ClientMalwareResponse::mutable_bad_url() {
    +  set_has_bad_url();
    +  if (bad_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    bad_url_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientMalwareResponse.bad_url)
    +  return bad_url_;
    +}
    +inline ::std::string* ClientMalwareResponse::release_bad_url() {
    +  clear_has_bad_url();
    +  if (bad_url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = bad_url_;
    +    bad_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientMalwareResponse::set_allocated_bad_url(::std::string* bad_url) {
    +  if (bad_url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete bad_url_;
    +  }
    +  if (bad_url) {
    +    set_has_bad_url();
    +    bad_url_ = bad_url;
    +  } else {
    +    clear_has_bad_url();
    +    bad_url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientMalwareResponse.bad_url)
    +}
    +
    +// -------------------------------------------------------------------
    +
     // ClientDownloadRequest_Digests
     
     // optional bytes sha256 = 1;
    @@ -1269,52 +6682,70 @@ inline void ClientDownloadRequest_Digests::clear_has_sha256() {
       _has_bits_[0] &= ~0x00000001u;
     }
     inline void ClientDownloadRequest_Digests::clear_sha256() {
    -  if (sha256_ != &::google::protobuf::internal::kEmptyString) {
    +  if (sha256_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha256_->clear();
       }
       clear_has_sha256();
     }
     inline const ::std::string& ClientDownloadRequest_Digests::sha256() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.Digests.sha256)
       return *sha256_;
     }
     inline void ClientDownloadRequest_Digests::set_sha256(const ::std::string& value) {
       set_has_sha256();
    -  if (sha256_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha256_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha256_ = new ::std::string;
       }
       sha256_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.Digests.sha256)
     }
     inline void ClientDownloadRequest_Digests::set_sha256(const char* value) {
       set_has_sha256();
    -  if (sha256_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha256_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha256_ = new ::std::string;
       }
       sha256_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.Digests.sha256)
     }
     inline void ClientDownloadRequest_Digests::set_sha256(const void* value, size_t size) {
       set_has_sha256();
    -  if (sha256_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha256_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha256_ = new ::std::string;
       }
       sha256_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.Digests.sha256)
     }
     inline ::std::string* ClientDownloadRequest_Digests::mutable_sha256() {
       set_has_sha256();
    -  if (sha256_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha256_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha256_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.Digests.sha256)
       return sha256_;
     }
     inline ::std::string* ClientDownloadRequest_Digests::release_sha256() {
       clear_has_sha256();
    -  if (sha256_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha256_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = sha256_;
    -    sha256_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    sha256_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_Digests::set_allocated_sha256(::std::string* sha256) {
    +  if (sha256_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete sha256_;
    +  }
    +  if (sha256) {
    +    set_has_sha256();
    +    sha256_ = sha256;
    +  } else {
    +    clear_has_sha256();
    +    sha256_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.Digests.sha256)
    +}
     
     // optional bytes sha1 = 2;
     inline bool ClientDownloadRequest_Digests::has_sha1() const {
    @@ -1327,52 +6758,70 @@ inline void ClientDownloadRequest_Digests::clear_has_sha1() {
       _has_bits_[0] &= ~0x00000002u;
     }
     inline void ClientDownloadRequest_Digests::clear_sha1() {
    -  if (sha1_ != &::google::protobuf::internal::kEmptyString) {
    +  if (sha1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha1_->clear();
       }
       clear_has_sha1();
     }
     inline const ::std::string& ClientDownloadRequest_Digests::sha1() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.Digests.sha1)
       return *sha1_;
     }
     inline void ClientDownloadRequest_Digests::set_sha1(const ::std::string& value) {
       set_has_sha1();
    -  if (sha1_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha1_ = new ::std::string;
       }
       sha1_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.Digests.sha1)
     }
     inline void ClientDownloadRequest_Digests::set_sha1(const char* value) {
       set_has_sha1();
    -  if (sha1_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha1_ = new ::std::string;
       }
       sha1_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.Digests.sha1)
     }
     inline void ClientDownloadRequest_Digests::set_sha1(const void* value, size_t size) {
       set_has_sha1();
    -  if (sha1_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha1_ = new ::std::string;
       }
       sha1_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.Digests.sha1)
     }
     inline ::std::string* ClientDownloadRequest_Digests::mutable_sha1() {
       set_has_sha1();
    -  if (sha1_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         sha1_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.Digests.sha1)
       return sha1_;
     }
     inline ::std::string* ClientDownloadRequest_Digests::release_sha1() {
       clear_has_sha1();
    -  if (sha1_ == &::google::protobuf::internal::kEmptyString) {
    +  if (sha1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = sha1_;
    -    sha1_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    sha1_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_Digests::set_allocated_sha1(::std::string* sha1) {
    +  if (sha1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete sha1_;
    +  }
    +  if (sha1) {
    +    set_has_sha1();
    +    sha1_ = sha1;
    +  } else {
    +    clear_has_sha1();
    +    sha1_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.Digests.sha1)
    +}
     
     // optional bytes md5 = 3;
     inline bool ClientDownloadRequest_Digests::has_md5() const {
    @@ -1385,52 +6834,70 @@ inline void ClientDownloadRequest_Digests::clear_has_md5() {
       _has_bits_[0] &= ~0x00000004u;
     }
     inline void ClientDownloadRequest_Digests::clear_md5() {
    -  if (md5_ != &::google::protobuf::internal::kEmptyString) {
    +  if (md5_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         md5_->clear();
       }
       clear_has_md5();
     }
     inline const ::std::string& ClientDownloadRequest_Digests::md5() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.Digests.md5)
       return *md5_;
     }
     inline void ClientDownloadRequest_Digests::set_md5(const ::std::string& value) {
       set_has_md5();
    -  if (md5_ == &::google::protobuf::internal::kEmptyString) {
    +  if (md5_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         md5_ = new ::std::string;
       }
       md5_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.Digests.md5)
     }
     inline void ClientDownloadRequest_Digests::set_md5(const char* value) {
       set_has_md5();
    -  if (md5_ == &::google::protobuf::internal::kEmptyString) {
    +  if (md5_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         md5_ = new ::std::string;
       }
       md5_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.Digests.md5)
     }
     inline void ClientDownloadRequest_Digests::set_md5(const void* value, size_t size) {
       set_has_md5();
    -  if (md5_ == &::google::protobuf::internal::kEmptyString) {
    +  if (md5_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         md5_ = new ::std::string;
       }
       md5_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.Digests.md5)
     }
     inline ::std::string* ClientDownloadRequest_Digests::mutable_md5() {
       set_has_md5();
    -  if (md5_ == &::google::protobuf::internal::kEmptyString) {
    +  if (md5_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         md5_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.Digests.md5)
       return md5_;
     }
     inline ::std::string* ClientDownloadRequest_Digests::release_md5() {
       clear_has_md5();
    -  if (md5_ == &::google::protobuf::internal::kEmptyString) {
    +  if (md5_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = md5_;
    -    md5_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    md5_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_Digests::set_allocated_md5(::std::string* md5) {
    +  if (md5_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete md5_;
    +  }
    +  if (md5) {
    +    set_has_md5();
    +    md5_ = md5;
    +  } else {
    +    clear_has_md5();
    +    md5_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.Digests.md5)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -1447,52 +6914,70 @@ inline void ClientDownloadRequest_Resource::clear_has_url() {
       _has_bits_[0] &= ~0x00000001u;
     }
     inline void ClientDownloadRequest_Resource::clear_url() {
    -  if (url_ != &::google::protobuf::internal::kEmptyString) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_->clear();
       }
       clear_has_url();
     }
     inline const ::std::string& ClientDownloadRequest_Resource::url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.Resource.url)
       return *url_;
     }
     inline void ClientDownloadRequest_Resource::set_url(const ::std::string& value) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.Resource.url)
     }
     inline void ClientDownloadRequest_Resource::set_url(const char* value) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.Resource.url)
     }
     inline void ClientDownloadRequest_Resource::set_url(const char* value, size_t size) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.Resource.url)
     }
     inline ::std::string* ClientDownloadRequest_Resource::mutable_url() {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.Resource.url)
       return url_;
     }
     inline ::std::string* ClientDownloadRequest_Resource::release_url() {
       clear_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = url_;
    -    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_Resource::set_allocated_url(::std::string* url) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (url) {
    +    set_has_url();
    +    url_ = url;
    +  } else {
    +    clear_has_url();
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.Resource.url)
    +}
     
     // required .safe_browsing.ClientDownloadRequest.ResourceType type = 2;
     inline bool ClientDownloadRequest_Resource::has_type() const {
    @@ -1509,12 +6994,14 @@ inline void ClientDownloadRequest_Resource::clear_type() {
       clear_has_type();
     }
     inline ::safe_browsing::ClientDownloadRequest_ResourceType ClientDownloadRequest_Resource::type() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.Resource.type)
       return static_cast< ::safe_browsing::ClientDownloadRequest_ResourceType >(type_);
     }
     inline void ClientDownloadRequest_Resource::set_type(::safe_browsing::ClientDownloadRequest_ResourceType value) {
    -  GOOGLE_DCHECK(::safe_browsing::ClientDownloadRequest_ResourceType_IsValid(value));
    +  assert(::safe_browsing::ClientDownloadRequest_ResourceType_IsValid(value));
       set_has_type();
       type_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.Resource.type)
     }
     
     // optional bytes remote_ip = 3;
    @@ -1528,52 +7015,70 @@ inline void ClientDownloadRequest_Resource::clear_has_remote_ip() {
       _has_bits_[0] &= ~0x00000004u;
     }
     inline void ClientDownloadRequest_Resource::clear_remote_ip() {
    -  if (remote_ip_ != &::google::protobuf::internal::kEmptyString) {
    +  if (remote_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         remote_ip_->clear();
       }
       clear_has_remote_ip();
     }
     inline const ::std::string& ClientDownloadRequest_Resource::remote_ip() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.Resource.remote_ip)
       return *remote_ip_;
     }
     inline void ClientDownloadRequest_Resource::set_remote_ip(const ::std::string& value) {
       set_has_remote_ip();
    -  if (remote_ip_ == &::google::protobuf::internal::kEmptyString) {
    +  if (remote_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         remote_ip_ = new ::std::string;
       }
       remote_ip_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.Resource.remote_ip)
     }
     inline void ClientDownloadRequest_Resource::set_remote_ip(const char* value) {
       set_has_remote_ip();
    -  if (remote_ip_ == &::google::protobuf::internal::kEmptyString) {
    +  if (remote_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         remote_ip_ = new ::std::string;
       }
       remote_ip_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.Resource.remote_ip)
     }
     inline void ClientDownloadRequest_Resource::set_remote_ip(const void* value, size_t size) {
       set_has_remote_ip();
    -  if (remote_ip_ == &::google::protobuf::internal::kEmptyString) {
    +  if (remote_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         remote_ip_ = new ::std::string;
       }
       remote_ip_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.Resource.remote_ip)
     }
     inline ::std::string* ClientDownloadRequest_Resource::mutable_remote_ip() {
       set_has_remote_ip();
    -  if (remote_ip_ == &::google::protobuf::internal::kEmptyString) {
    +  if (remote_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         remote_ip_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.Resource.remote_ip)
       return remote_ip_;
     }
     inline ::std::string* ClientDownloadRequest_Resource::release_remote_ip() {
       clear_has_remote_ip();
    -  if (remote_ip_ == &::google::protobuf::internal::kEmptyString) {
    +  if (remote_ip_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = remote_ip_;
    -    remote_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    remote_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_Resource::set_allocated_remote_ip(::std::string* remote_ip) {
    +  if (remote_ip_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete remote_ip_;
    +  }
    +  if (remote_ip) {
    +    set_has_remote_ip();
    +    remote_ip_ = remote_ip;
    +  } else {
    +    clear_has_remote_ip();
    +    remote_ip_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.Resource.remote_ip)
    +}
     
     // optional string referrer = 4;
     inline bool ClientDownloadRequest_Resource::has_referrer() const {
    @@ -1586,52 +7091,70 @@ inline void ClientDownloadRequest_Resource::clear_has_referrer() {
       _has_bits_[0] &= ~0x00000008u;
     }
     inline void ClientDownloadRequest_Resource::clear_referrer() {
    -  if (referrer_ != &::google::protobuf::internal::kEmptyString) {
    +  if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         referrer_->clear();
       }
       clear_has_referrer();
     }
     inline const ::std::string& ClientDownloadRequest_Resource::referrer() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.Resource.referrer)
       return *referrer_;
     }
     inline void ClientDownloadRequest_Resource::set_referrer(const ::std::string& value) {
       set_has_referrer();
    -  if (referrer_ == &::google::protobuf::internal::kEmptyString) {
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         referrer_ = new ::std::string;
       }
       referrer_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.Resource.referrer)
     }
     inline void ClientDownloadRequest_Resource::set_referrer(const char* value) {
       set_has_referrer();
    -  if (referrer_ == &::google::protobuf::internal::kEmptyString) {
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         referrer_ = new ::std::string;
       }
       referrer_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.Resource.referrer)
     }
     inline void ClientDownloadRequest_Resource::set_referrer(const char* value, size_t size) {
       set_has_referrer();
    -  if (referrer_ == &::google::protobuf::internal::kEmptyString) {
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         referrer_ = new ::std::string;
       }
       referrer_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.Resource.referrer)
     }
     inline ::std::string* ClientDownloadRequest_Resource::mutable_referrer() {
       set_has_referrer();
    -  if (referrer_ == &::google::protobuf::internal::kEmptyString) {
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         referrer_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.Resource.referrer)
       return referrer_;
     }
     inline ::std::string* ClientDownloadRequest_Resource::release_referrer() {
       clear_has_referrer();
    -  if (referrer_ == &::google::protobuf::internal::kEmptyString) {
    +  if (referrer_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = referrer_;
    -    referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_Resource::set_allocated_referrer(::std::string* referrer) {
    +  if (referrer_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete referrer_;
    +  }
    +  if (referrer) {
    +    set_has_referrer();
    +    referrer_ = referrer;
    +  } else {
    +    clear_has_referrer();
    +    referrer_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.Resource.referrer)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -1648,52 +7171,70 @@ inline void ClientDownloadRequest_CertificateChain_Element::clear_has_certificat
       _has_bits_[0] &= ~0x00000001u;
     }
     inline void ClientDownloadRequest_CertificateChain_Element::clear_certificate() {
    -  if (certificate_ != &::google::protobuf::internal::kEmptyString) {
    +  if (certificate_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         certificate_->clear();
       }
       clear_has_certificate();
     }
     inline const ::std::string& ClientDownloadRequest_CertificateChain_Element::certificate() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.CertificateChain.Element.certificate)
       return *certificate_;
     }
     inline void ClientDownloadRequest_CertificateChain_Element::set_certificate(const ::std::string& value) {
       set_has_certificate();
    -  if (certificate_ == &::google::protobuf::internal::kEmptyString) {
    +  if (certificate_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         certificate_ = new ::std::string;
       }
       certificate_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.CertificateChain.Element.certificate)
     }
     inline void ClientDownloadRequest_CertificateChain_Element::set_certificate(const char* value) {
       set_has_certificate();
    -  if (certificate_ == &::google::protobuf::internal::kEmptyString) {
    +  if (certificate_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         certificate_ = new ::std::string;
       }
       certificate_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.CertificateChain.Element.certificate)
     }
     inline void ClientDownloadRequest_CertificateChain_Element::set_certificate(const void* value, size_t size) {
       set_has_certificate();
    -  if (certificate_ == &::google::protobuf::internal::kEmptyString) {
    +  if (certificate_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         certificate_ = new ::std::string;
       }
       certificate_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.CertificateChain.Element.certificate)
     }
     inline ::std::string* ClientDownloadRequest_CertificateChain_Element::mutable_certificate() {
       set_has_certificate();
    -  if (certificate_ == &::google::protobuf::internal::kEmptyString) {
    +  if (certificate_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         certificate_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.CertificateChain.Element.certificate)
       return certificate_;
     }
     inline ::std::string* ClientDownloadRequest_CertificateChain_Element::release_certificate() {
       clear_has_certificate();
    -  if (certificate_ == &::google::protobuf::internal::kEmptyString) {
    +  if (certificate_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = certificate_;
    -    certificate_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    certificate_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_CertificateChain_Element::set_allocated_certificate(::std::string* certificate) {
    +  if (certificate_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete certificate_;
    +  }
    +  if (certificate) {
    +    set_has_certificate();
    +    certificate_ = certificate;
    +  } else {
    +    clear_has_certificate();
    +    certificate_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.CertificateChain.Element.certificate)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -1707,20 +7248,25 @@ inline void ClientDownloadRequest_CertificateChain::clear_element() {
       element_.Clear();
     }
     inline const ::safe_browsing::ClientDownloadRequest_CertificateChain_Element& ClientDownloadRequest_CertificateChain::element(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.CertificateChain.element)
       return element_.Get(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_CertificateChain_Element* ClientDownloadRequest_CertificateChain::mutable_element(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.CertificateChain.element)
       return element_.Mutable(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_CertificateChain_Element* ClientDownloadRequest_CertificateChain::add_element() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientDownloadRequest.CertificateChain.element)
       return element_.Add();
     }
     inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain_Element >&
     ClientDownloadRequest_CertificateChain::element() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientDownloadRequest.CertificateChain.element)
       return element_;
     }
     inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain_Element >*
     ClientDownloadRequest_CertificateChain::mutable_element() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientDownloadRequest.CertificateChain.element)
       return &element_;
     }
     
    @@ -1736,20 +7282,25 @@ inline void ClientDownloadRequest_SignatureInfo::clear_certificate_chain() {
       certificate_chain_.Clear();
     }
     inline const ::safe_browsing::ClientDownloadRequest_CertificateChain& ClientDownloadRequest_SignatureInfo::certificate_chain(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.SignatureInfo.certificate_chain)
       return certificate_chain_.Get(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_CertificateChain* ClientDownloadRequest_SignatureInfo::mutable_certificate_chain(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.SignatureInfo.certificate_chain)
       return certificate_chain_.Mutable(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_CertificateChain* ClientDownloadRequest_SignatureInfo::add_certificate_chain() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientDownloadRequest.SignatureInfo.certificate_chain)
       return certificate_chain_.Add();
     }
     inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain >&
     ClientDownloadRequest_SignatureInfo::certificate_chain() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientDownloadRequest.SignatureInfo.certificate_chain)
       return certificate_chain_;
     }
     inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_CertificateChain >*
     ClientDownloadRequest_SignatureInfo::mutable_certificate_chain() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientDownloadRequest.SignatureInfo.certificate_chain)
       return &certificate_chain_;
     }
     
    @@ -1768,11 +7319,13 @@ inline void ClientDownloadRequest_SignatureInfo::clear_trusted() {
       clear_has_trusted();
     }
     inline bool ClientDownloadRequest_SignatureInfo::trusted() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.SignatureInfo.trusted)
       return trusted_;
     }
     inline void ClientDownloadRequest_SignatureInfo::set_trusted(bool value) {
       set_has_trusted();
       trusted_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.SignatureInfo.trusted)
     }
     
     // -------------------------------------------------------------------
    @@ -1790,52 +7343,70 @@ inline void ClientDownloadRequest_PEImageHeaders_DebugData::clear_has_directory_
       _has_bits_[0] &= ~0x00000001u;
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::clear_directory_entry() {
    -  if (directory_entry_ != &::google::protobuf::internal::kEmptyString) {
    +  if (directory_entry_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         directory_entry_->clear();
       }
       clear_has_directory_entry();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders_DebugData::directory_entry() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.directory_entry)
       return *directory_entry_;
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_directory_entry(const ::std::string& value) {
       set_has_directory_entry();
    -  if (directory_entry_ == &::google::protobuf::internal::kEmptyString) {
    +  if (directory_entry_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         directory_entry_ = new ::std::string;
       }
       directory_entry_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.directory_entry)
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_directory_entry(const char* value) {
       set_has_directory_entry();
    -  if (directory_entry_ == &::google::protobuf::internal::kEmptyString) {
    +  if (directory_entry_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         directory_entry_ = new ::std::string;
       }
       directory_entry_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.directory_entry)
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_directory_entry(const void* value, size_t size) {
       set_has_directory_entry();
    -  if (directory_entry_ == &::google::protobuf::internal::kEmptyString) {
    +  if (directory_entry_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         directory_entry_ = new ::std::string;
       }
       directory_entry_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.directory_entry)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders_DebugData::mutable_directory_entry() {
       set_has_directory_entry();
    -  if (directory_entry_ == &::google::protobuf::internal::kEmptyString) {
    +  if (directory_entry_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         directory_entry_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.directory_entry)
       return directory_entry_;
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders_DebugData::release_directory_entry() {
       clear_has_directory_entry();
    -  if (directory_entry_ == &::google::protobuf::internal::kEmptyString) {
    +  if (directory_entry_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = directory_entry_;
    -    directory_entry_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    directory_entry_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_allocated_directory_entry(::std::string* directory_entry) {
    +  if (directory_entry_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete directory_entry_;
    +  }
    +  if (directory_entry) {
    +    set_has_directory_entry();
    +    directory_entry_ = directory_entry;
    +  } else {
    +    clear_has_directory_entry();
    +    directory_entry_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.directory_entry)
    +}
     
     // optional bytes raw_data = 2;
     inline bool ClientDownloadRequest_PEImageHeaders_DebugData::has_raw_data() const {
    @@ -1848,52 +7419,70 @@ inline void ClientDownloadRequest_PEImageHeaders_DebugData::clear_has_raw_data()
       _has_bits_[0] &= ~0x00000002u;
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::clear_raw_data() {
    -  if (raw_data_ != &::google::protobuf::internal::kEmptyString) {
    +  if (raw_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         raw_data_->clear();
       }
       clear_has_raw_data();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders_DebugData::raw_data() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.raw_data)
       return *raw_data_;
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_raw_data(const ::std::string& value) {
       set_has_raw_data();
    -  if (raw_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (raw_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         raw_data_ = new ::std::string;
       }
       raw_data_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.raw_data)
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_raw_data(const char* value) {
       set_has_raw_data();
    -  if (raw_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (raw_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         raw_data_ = new ::std::string;
       }
       raw_data_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.raw_data)
     }
     inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_raw_data(const void* value, size_t size) {
       set_has_raw_data();
    -  if (raw_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (raw_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         raw_data_ = new ::std::string;
       }
       raw_data_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.raw_data)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders_DebugData::mutable_raw_data() {
       set_has_raw_data();
    -  if (raw_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (raw_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         raw_data_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.raw_data)
       return raw_data_;
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders_DebugData::release_raw_data() {
       clear_has_raw_data();
    -  if (raw_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (raw_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = raw_data_;
    -    raw_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    raw_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_PEImageHeaders_DebugData::set_allocated_raw_data(::std::string* raw_data) {
    +  if (raw_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete raw_data_;
    +  }
    +  if (raw_data) {
    +    set_has_raw_data();
    +    raw_data_ = raw_data;
    +  } else {
    +    clear_has_raw_data();
    +    raw_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData.raw_data)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -1910,52 +7499,70 @@ inline void ClientDownloadRequest_PEImageHeaders::clear_has_dos_header() {
       _has_bits_[0] &= ~0x00000001u;
     }
     inline void ClientDownloadRequest_PEImageHeaders::clear_dos_header() {
    -  if (dos_header_ != &::google::protobuf::internal::kEmptyString) {
    +  if (dos_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         dos_header_->clear();
       }
       clear_has_dos_header();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders::dos_header() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.dos_header)
       return *dos_header_;
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_dos_header(const ::std::string& value) {
       set_has_dos_header();
    -  if (dos_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (dos_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         dos_header_ = new ::std::string;
       }
       dos_header_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.dos_header)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_dos_header(const char* value) {
       set_has_dos_header();
    -  if (dos_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (dos_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         dos_header_ = new ::std::string;
       }
       dos_header_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.dos_header)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_dos_header(const void* value, size_t size) {
       set_has_dos_header();
    -  if (dos_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (dos_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         dos_header_ = new ::std::string;
       }
       dos_header_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.dos_header)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::mutable_dos_header() {
       set_has_dos_header();
    -  if (dos_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (dos_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         dos_header_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.dos_header)
       return dos_header_;
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::release_dos_header() {
       clear_has_dos_header();
    -  if (dos_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (dos_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = dos_header_;
    -    dos_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    dos_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_PEImageHeaders::set_allocated_dos_header(::std::string* dos_header) {
    +  if (dos_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete dos_header_;
    +  }
    +  if (dos_header) {
    +    set_has_dos_header();
    +    dos_header_ = dos_header;
    +  } else {
    +    clear_has_dos_header();
    +    dos_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.PEImageHeaders.dos_header)
    +}
     
     // optional bytes file_header = 2;
     inline bool ClientDownloadRequest_PEImageHeaders::has_file_header() const {
    @@ -1968,52 +7575,70 @@ inline void ClientDownloadRequest_PEImageHeaders::clear_has_file_header() {
       _has_bits_[0] &= ~0x00000002u;
     }
     inline void ClientDownloadRequest_PEImageHeaders::clear_file_header() {
    -  if (file_header_ != &::google::protobuf::internal::kEmptyString) {
    +  if (file_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_header_->clear();
       }
       clear_has_file_header();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders::file_header() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.file_header)
       return *file_header_;
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_file_header(const ::std::string& value) {
       set_has_file_header();
    -  if (file_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_header_ = new ::std::string;
       }
       file_header_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.file_header)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_file_header(const char* value) {
       set_has_file_header();
    -  if (file_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_header_ = new ::std::string;
       }
       file_header_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.file_header)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_file_header(const void* value, size_t size) {
       set_has_file_header();
    -  if (file_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_header_ = new ::std::string;
       }
       file_header_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.file_header)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::mutable_file_header() {
       set_has_file_header();
    -  if (file_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_header_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.file_header)
       return file_header_;
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::release_file_header() {
       clear_has_file_header();
    -  if (file_header_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_header_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = file_header_;
    -    file_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    file_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_PEImageHeaders::set_allocated_file_header(::std::string* file_header) {
    +  if (file_header_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete file_header_;
    +  }
    +  if (file_header) {
    +    set_has_file_header();
    +    file_header_ = file_header;
    +  } else {
    +    clear_has_file_header();
    +    file_header_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.PEImageHeaders.file_header)
    +}
     
     // optional bytes optional_headers32 = 3;
     inline bool ClientDownloadRequest_PEImageHeaders::has_optional_headers32() const {
    @@ -2026,52 +7651,70 @@ inline void ClientDownloadRequest_PEImageHeaders::clear_has_optional_headers32()
       _has_bits_[0] &= ~0x00000004u;
     }
     inline void ClientDownloadRequest_PEImageHeaders::clear_optional_headers32() {
    -  if (optional_headers32_ != &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers32_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers32_->clear();
       }
       clear_has_optional_headers32();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders::optional_headers32() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers32)
       return *optional_headers32_;
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_optional_headers32(const ::std::string& value) {
       set_has_optional_headers32();
    -  if (optional_headers32_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers32_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers32_ = new ::std::string;
       }
       optional_headers32_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers32)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_optional_headers32(const char* value) {
       set_has_optional_headers32();
    -  if (optional_headers32_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers32_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers32_ = new ::std::string;
       }
       optional_headers32_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers32)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_optional_headers32(const void* value, size_t size) {
       set_has_optional_headers32();
    -  if (optional_headers32_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers32_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers32_ = new ::std::string;
       }
       optional_headers32_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers32)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::mutable_optional_headers32() {
       set_has_optional_headers32();
    -  if (optional_headers32_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers32_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers32_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers32)
       return optional_headers32_;
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::release_optional_headers32() {
       clear_has_optional_headers32();
    -  if (optional_headers32_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers32_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = optional_headers32_;
    -    optional_headers32_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    optional_headers32_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_PEImageHeaders::set_allocated_optional_headers32(::std::string* optional_headers32) {
    +  if (optional_headers32_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete optional_headers32_;
    +  }
    +  if (optional_headers32) {
    +    set_has_optional_headers32();
    +    optional_headers32_ = optional_headers32;
    +  } else {
    +    clear_has_optional_headers32();
    +    optional_headers32_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers32)
    +}
     
     // optional bytes optional_headers64 = 4;
     inline bool ClientDownloadRequest_PEImageHeaders::has_optional_headers64() const {
    @@ -2084,52 +7727,70 @@ inline void ClientDownloadRequest_PEImageHeaders::clear_has_optional_headers64()
       _has_bits_[0] &= ~0x00000008u;
     }
     inline void ClientDownloadRequest_PEImageHeaders::clear_optional_headers64() {
    -  if (optional_headers64_ != &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers64_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers64_->clear();
       }
       clear_has_optional_headers64();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders::optional_headers64() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers64)
       return *optional_headers64_;
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_optional_headers64(const ::std::string& value) {
       set_has_optional_headers64();
    -  if (optional_headers64_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers64_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers64_ = new ::std::string;
       }
       optional_headers64_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers64)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_optional_headers64(const char* value) {
       set_has_optional_headers64();
    -  if (optional_headers64_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers64_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers64_ = new ::std::string;
       }
       optional_headers64_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers64)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_optional_headers64(const void* value, size_t size) {
       set_has_optional_headers64();
    -  if (optional_headers64_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers64_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers64_ = new ::std::string;
       }
       optional_headers64_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers64)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::mutable_optional_headers64() {
       set_has_optional_headers64();
    -  if (optional_headers64_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers64_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         optional_headers64_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers64)
       return optional_headers64_;
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::release_optional_headers64() {
       clear_has_optional_headers64();
    -  if (optional_headers64_ == &::google::protobuf::internal::kEmptyString) {
    +  if (optional_headers64_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = optional_headers64_;
    -    optional_headers64_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    optional_headers64_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_PEImageHeaders::set_allocated_optional_headers64(::std::string* optional_headers64) {
    +  if (optional_headers64_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete optional_headers64_;
    +  }
    +  if (optional_headers64) {
    +    set_has_optional_headers64();
    +    optional_headers64_ = optional_headers64;
    +  } else {
    +    clear_has_optional_headers64();
    +    optional_headers64_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.PEImageHeaders.optional_headers64)
    +}
     
     // repeated bytes section_header = 5;
     inline int ClientDownloadRequest_PEImageHeaders::section_header_size() const {
    @@ -2139,39 +7800,49 @@ inline void ClientDownloadRequest_PEImageHeaders::clear_section_header() {
       section_header_.Clear();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders::section_header(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
       return section_header_.Get(index);
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::mutable_section_header(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
       return section_header_.Mutable(index);
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_section_header(int index, const ::std::string& value) {
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
       section_header_.Mutable(index)->assign(value);
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_section_header(int index, const char* value) {
       section_header_.Mutable(index)->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_section_header(int index, const void* value, size_t size) {
       section_header_.Mutable(index)->assign(
         reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::add_section_header() {
       return section_header_.Add();
     }
     inline void ClientDownloadRequest_PEImageHeaders::add_section_header(const ::std::string& value) {
       section_header_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
     }
     inline void ClientDownloadRequest_PEImageHeaders::add_section_header(const char* value) {
       section_header_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
     }
     inline void ClientDownloadRequest_PEImageHeaders::add_section_header(const void* value, size_t size) {
       section_header_.Add()->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_add_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
     }
     inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
     ClientDownloadRequest_PEImageHeaders::section_header() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
       return section_header_;
     }
     inline ::google::protobuf::RepeatedPtrField< ::std::string>*
     ClientDownloadRequest_PEImageHeaders::mutable_section_header() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientDownloadRequest.PEImageHeaders.section_header)
       return §ion_header_;
     }
     
    @@ -2186,52 +7857,70 @@ inline void ClientDownloadRequest_PEImageHeaders::clear_has_export_section_data(
       _has_bits_[0] &= ~0x00000020u;
     }
     inline void ClientDownloadRequest_PEImageHeaders::clear_export_section_data() {
    -  if (export_section_data_ != &::google::protobuf::internal::kEmptyString) {
    +  if (export_section_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         export_section_data_->clear();
       }
       clear_has_export_section_data();
     }
     inline const ::std::string& ClientDownloadRequest_PEImageHeaders::export_section_data() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.export_section_data)
       return *export_section_data_;
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_export_section_data(const ::std::string& value) {
       set_has_export_section_data();
    -  if (export_section_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (export_section_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         export_section_data_ = new ::std::string;
       }
       export_section_data_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.PEImageHeaders.export_section_data)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_export_section_data(const char* value) {
       set_has_export_section_data();
    -  if (export_section_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (export_section_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         export_section_data_ = new ::std::string;
       }
       export_section_data_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.PEImageHeaders.export_section_data)
     }
     inline void ClientDownloadRequest_PEImageHeaders::set_export_section_data(const void* value, size_t size) {
       set_has_export_section_data();
    -  if (export_section_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (export_section_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         export_section_data_ = new ::std::string;
       }
       export_section_data_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.PEImageHeaders.export_section_data)
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::mutable_export_section_data() {
       set_has_export_section_data();
    -  if (export_section_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (export_section_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         export_section_data_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.export_section_data)
       return export_section_data_;
     }
     inline ::std::string* ClientDownloadRequest_PEImageHeaders::release_export_section_data() {
       clear_has_export_section_data();
    -  if (export_section_data_ == &::google::protobuf::internal::kEmptyString) {
    +  if (export_section_data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = export_section_data_;
    -    export_section_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    export_section_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest_PEImageHeaders::set_allocated_export_section_data(::std::string* export_section_data) {
    +  if (export_section_data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete export_section_data_;
    +  }
    +  if (export_section_data) {
    +    set_has_export_section_data();
    +    export_section_data_ = export_section_data;
    +  } else {
    +    clear_has_export_section_data();
    +    export_section_data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.PEImageHeaders.export_section_data)
    +}
     
     // repeated .safe_browsing.ClientDownloadRequest.PEImageHeaders.DebugData debug_data = 7;
     inline int ClientDownloadRequest_PEImageHeaders::debug_data_size() const {
    @@ -2241,20 +7930,25 @@ inline void ClientDownloadRequest_PEImageHeaders::clear_debug_data() {
       debug_data_.Clear();
     }
     inline const ::safe_browsing::ClientDownloadRequest_PEImageHeaders_DebugData& ClientDownloadRequest_PEImageHeaders::debug_data(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.PEImageHeaders.debug_data)
       return debug_data_.Get(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_PEImageHeaders_DebugData* ClientDownloadRequest_PEImageHeaders::mutable_debug_data(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.PEImageHeaders.debug_data)
       return debug_data_.Mutable(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_PEImageHeaders_DebugData* ClientDownloadRequest_PEImageHeaders::add_debug_data() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientDownloadRequest.PEImageHeaders.debug_data)
       return debug_data_.Add();
     }
     inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_PEImageHeaders_DebugData >&
     ClientDownloadRequest_PEImageHeaders::debug_data() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientDownloadRequest.PEImageHeaders.debug_data)
       return debug_data_;
     }
     inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_PEImageHeaders_DebugData >*
     ClientDownloadRequest_PEImageHeaders::mutable_debug_data() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientDownloadRequest.PEImageHeaders.debug_data)
       return &debug_data_;
     }
     
    @@ -2277,11 +7971,17 @@ inline void ClientDownloadRequest_ImageHeaders::clear_pe_headers() {
       clear_has_pe_headers();
     }
     inline const ::safe_browsing::ClientDownloadRequest_PEImageHeaders& ClientDownloadRequest_ImageHeaders::pe_headers() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.ImageHeaders.pe_headers)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return pe_headers_ != NULL ? *pe_headers_ : *default_instance().pe_headers_;
    +#else
       return pe_headers_ != NULL ? *pe_headers_ : *default_instance_->pe_headers_;
    +#endif
     }
     inline ::safe_browsing::ClientDownloadRequest_PEImageHeaders* ClientDownloadRequest_ImageHeaders::mutable_pe_headers() {
       set_has_pe_headers();
       if (pe_headers_ == NULL) pe_headers_ = new ::safe_browsing::ClientDownloadRequest_PEImageHeaders;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.ImageHeaders.pe_headers)
       return pe_headers_;
     }
     inline ::safe_browsing::ClientDownloadRequest_PEImageHeaders* ClientDownloadRequest_ImageHeaders::release_pe_headers() {
    @@ -2290,6 +7990,280 @@ inline ::safe_browsing::ClientDownloadRequest_PEImageHeaders* ClientDownloadRequ
       pe_headers_ = NULL;
       return temp;
     }
    +inline void ClientDownloadRequest_ImageHeaders::set_allocated_pe_headers(::safe_browsing::ClientDownloadRequest_PEImageHeaders* pe_headers) {
    +  delete pe_headers_;
    +  pe_headers_ = pe_headers;
    +  if (pe_headers) {
    +    set_has_pe_headers();
    +  } else {
    +    clear_has_pe_headers();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.ImageHeaders.pe_headers)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientDownloadRequest_ArchivedBinary
    +
    +// optional string file_basename = 1;
    +inline bool ClientDownloadRequest_ArchivedBinary::has_file_basename() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_has_file_basename() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_has_file_basename() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_file_basename() {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_->clear();
    +  }
    +  clear_has_file_basename();
    +}
    +inline const ::std::string& ClientDownloadRequest_ArchivedBinary::file_basename() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.ArchivedBinary.file_basename)
    +  return *file_basename_;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_file_basename(const ::std::string& value) {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  file_basename_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.ArchivedBinary.file_basename)
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_file_basename(const char* value) {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  file_basename_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.ArchivedBinary.file_basename)
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_file_basename(const char* value, size_t size) {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  file_basename_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.ArchivedBinary.file_basename)
    +}
    +inline ::std::string* ClientDownloadRequest_ArchivedBinary::mutable_file_basename() {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.ArchivedBinary.file_basename)
    +  return file_basename_;
    +}
    +inline ::std::string* ClientDownloadRequest_ArchivedBinary::release_file_basename() {
    +  clear_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = file_basename_;
    +    file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_allocated_file_basename(::std::string* file_basename) {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete file_basename_;
    +  }
    +  if (file_basename) {
    +    set_has_file_basename();
    +    file_basename_ = file_basename;
    +  } else {
    +    clear_has_file_basename();
    +    file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.ArchivedBinary.file_basename)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 2;
    +inline bool ClientDownloadRequest_ArchivedBinary::has_download_type() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_has_download_type() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_has_download_type() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_download_type() {
    +  download_type_ = 0;
    +  clear_has_download_type();
    +}
    +inline ::safe_browsing::ClientDownloadRequest_DownloadType ClientDownloadRequest_ArchivedBinary::download_type() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.ArchivedBinary.download_type)
    +  return static_cast< ::safe_browsing::ClientDownloadRequest_DownloadType >(download_type_);
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_download_type(::safe_browsing::ClientDownloadRequest_DownloadType value) {
    +  assert(::safe_browsing::ClientDownloadRequest_DownloadType_IsValid(value));
    +  set_has_download_type();
    +  download_type_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.ArchivedBinary.download_type)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.Digests digests = 3;
    +inline bool ClientDownloadRequest_ArchivedBinary::has_digests() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_has_digests() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_has_digests() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_digests() {
    +  if (digests_ != NULL) digests_->::safe_browsing::ClientDownloadRequest_Digests::Clear();
    +  clear_has_digests();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_Digests& ClientDownloadRequest_ArchivedBinary::digests() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.ArchivedBinary.digests)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return digests_ != NULL ? *digests_ : *default_instance().digests_;
    +#else
    +  return digests_ != NULL ? *digests_ : *default_instance_->digests_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_Digests* ClientDownloadRequest_ArchivedBinary::mutable_digests() {
    +  set_has_digests();
    +  if (digests_ == NULL) digests_ = new ::safe_browsing::ClientDownloadRequest_Digests;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.ArchivedBinary.digests)
    +  return digests_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_Digests* ClientDownloadRequest_ArchivedBinary::release_digests() {
    +  clear_has_digests();
    +  ::safe_browsing::ClientDownloadRequest_Digests* temp = digests_;
    +  digests_ = NULL;
    +  return temp;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_allocated_digests(::safe_browsing::ClientDownloadRequest_Digests* digests) {
    +  delete digests_;
    +  digests_ = digests;
    +  if (digests) {
    +    set_has_digests();
    +  } else {
    +    clear_has_digests();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.ArchivedBinary.digests)
    +}
    +
    +// optional int64 length = 4;
    +inline bool ClientDownloadRequest_ArchivedBinary::has_length() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_has_length() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_has_length() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_length() {
    +  length_ = GOOGLE_LONGLONG(0);
    +  clear_has_length();
    +}
    +inline ::google::protobuf::int64 ClientDownloadRequest_ArchivedBinary::length() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.ArchivedBinary.length)
    +  return length_;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_length(::google::protobuf::int64 value) {
    +  set_has_length();
    +  length_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.ArchivedBinary.length)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +inline bool ClientDownloadRequest_ArchivedBinary::has_signature() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_has_signature() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_has_signature() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_signature() {
    +  if (signature_ != NULL) signature_->::safe_browsing::ClientDownloadRequest_SignatureInfo::Clear();
    +  clear_has_signature();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& ClientDownloadRequest_ArchivedBinary::signature() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.ArchivedBinary.signature)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return signature_ != NULL ? *signature_ : *default_instance().signature_;
    +#else
    +  return signature_ != NULL ? *signature_ : *default_instance_->signature_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientDownloadRequest_ArchivedBinary::mutable_signature() {
    +  set_has_signature();
    +  if (signature_ == NULL) signature_ = new ::safe_browsing::ClientDownloadRequest_SignatureInfo;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.ArchivedBinary.signature)
    +  return signature_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientDownloadRequest_ArchivedBinary::release_signature() {
    +  clear_has_signature();
    +  ::safe_browsing::ClientDownloadRequest_SignatureInfo* temp = signature_;
    +  signature_ = NULL;
    +  return temp;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature) {
    +  delete signature_;
    +  signature_ = signature;
    +  if (signature) {
    +    set_has_signature();
    +  } else {
    +    clear_has_signature();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.ArchivedBinary.signature)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +inline bool ClientDownloadRequest_ArchivedBinary::has_image_headers() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_has_image_headers() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_has_image_headers() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::clear_image_headers() {
    +  if (image_headers_ != NULL) image_headers_->::safe_browsing::ClientDownloadRequest_ImageHeaders::Clear();
    +  clear_has_image_headers();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& ClientDownloadRequest_ArchivedBinary::image_headers() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.ArchivedBinary.image_headers)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return image_headers_ != NULL ? *image_headers_ : *default_instance().image_headers_;
    +#else
    +  return image_headers_ != NULL ? *image_headers_ : *default_instance_->image_headers_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientDownloadRequest_ArchivedBinary::mutable_image_headers() {
    +  set_has_image_headers();
    +  if (image_headers_ == NULL) image_headers_ = new ::safe_browsing::ClientDownloadRequest_ImageHeaders;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.ArchivedBinary.image_headers)
    +  return image_headers_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientDownloadRequest_ArchivedBinary::release_image_headers() {
    +  clear_has_image_headers();
    +  ::safe_browsing::ClientDownloadRequest_ImageHeaders* temp = image_headers_;
    +  image_headers_ = NULL;
    +  return temp;
    +}
    +inline void ClientDownloadRequest_ArchivedBinary::set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers) {
    +  delete image_headers_;
    +  image_headers_ = image_headers;
    +  if (image_headers) {
    +    set_has_image_headers();
    +  } else {
    +    clear_has_image_headers();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.ArchivedBinary.image_headers)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -2306,52 +8280,70 @@ inline void ClientDownloadRequest::clear_has_url() {
       _has_bits_[0] &= ~0x00000001u;
     }
     inline void ClientDownloadRequest::clear_url() {
    -  if (url_ != &::google::protobuf::internal::kEmptyString) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_->clear();
       }
       clear_has_url();
     }
     inline const ::std::string& ClientDownloadRequest::url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.url)
       return *url_;
     }
     inline void ClientDownloadRequest::set_url(const ::std::string& value) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.url)
     }
     inline void ClientDownloadRequest::set_url(const char* value) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.url)
     }
     inline void ClientDownloadRequest::set_url(const char* value, size_t size) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.url)
     }
     inline ::std::string* ClientDownloadRequest::mutable_url() {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.url)
       return url_;
     }
     inline ::std::string* ClientDownloadRequest::release_url() {
       clear_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = url_;
    -    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest::set_allocated_url(::std::string* url) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (url) {
    +    set_has_url();
    +    url_ = url;
    +  } else {
    +    clear_has_url();
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.url)
    +}
     
     // required .safe_browsing.ClientDownloadRequest.Digests digests = 2;
     inline bool ClientDownloadRequest::has_digests() const {
    @@ -2368,11 +8360,17 @@ inline void ClientDownloadRequest::clear_digests() {
       clear_has_digests();
     }
     inline const ::safe_browsing::ClientDownloadRequest_Digests& ClientDownloadRequest::digests() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.digests)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return digests_ != NULL ? *digests_ : *default_instance().digests_;
    +#else
       return digests_ != NULL ? *digests_ : *default_instance_->digests_;
    +#endif
     }
     inline ::safe_browsing::ClientDownloadRequest_Digests* ClientDownloadRequest::mutable_digests() {
       set_has_digests();
       if (digests_ == NULL) digests_ = new ::safe_browsing::ClientDownloadRequest_Digests;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.digests)
       return digests_;
     }
     inline ::safe_browsing::ClientDownloadRequest_Digests* ClientDownloadRequest::release_digests() {
    @@ -2381,6 +8379,16 @@ inline ::safe_browsing::ClientDownloadRequest_Digests* ClientDownloadRequest::re
       digests_ = NULL;
       return temp;
     }
    +inline void ClientDownloadRequest::set_allocated_digests(::safe_browsing::ClientDownloadRequest_Digests* digests) {
    +  delete digests_;
    +  digests_ = digests;
    +  if (digests) {
    +    set_has_digests();
    +  } else {
    +    clear_has_digests();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.digests)
    +}
     
     // required int64 length = 3;
     inline bool ClientDownloadRequest::has_length() const {
    @@ -2397,11 +8405,13 @@ inline void ClientDownloadRequest::clear_length() {
       clear_has_length();
     }
     inline ::google::protobuf::int64 ClientDownloadRequest::length() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.length)
       return length_;
     }
     inline void ClientDownloadRequest::set_length(::google::protobuf::int64 value) {
       set_has_length();
       length_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.length)
     }
     
     // repeated .safe_browsing.ClientDownloadRequest.Resource resources = 4;
    @@ -2412,20 +8422,25 @@ inline void ClientDownloadRequest::clear_resources() {
       resources_.Clear();
     }
     inline const ::safe_browsing::ClientDownloadRequest_Resource& ClientDownloadRequest::resources(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.resources)
       return resources_.Get(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_Resource* ClientDownloadRequest::mutable_resources(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.resources)
       return resources_.Mutable(index);
     }
     inline ::safe_browsing::ClientDownloadRequest_Resource* ClientDownloadRequest::add_resources() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientDownloadRequest.resources)
       return resources_.Add();
     }
     inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_Resource >&
     ClientDownloadRequest::resources() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientDownloadRequest.resources)
       return resources_;
     }
     inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_Resource >*
     ClientDownloadRequest::mutable_resources() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientDownloadRequest.resources)
       return &resources_;
     }
     
    @@ -2444,11 +8459,17 @@ inline void ClientDownloadRequest::clear_signature() {
       clear_has_signature();
     }
     inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& ClientDownloadRequest::signature() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.signature)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return signature_ != NULL ? *signature_ : *default_instance().signature_;
    +#else
       return signature_ != NULL ? *signature_ : *default_instance_->signature_;
    +#endif
     }
     inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientDownloadRequest::mutable_signature() {
       set_has_signature();
       if (signature_ == NULL) signature_ = new ::safe_browsing::ClientDownloadRequest_SignatureInfo;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.signature)
       return signature_;
     }
     inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientDownloadRequest::release_signature() {
    @@ -2457,6 +8478,16 @@ inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientDownloadReque
       signature_ = NULL;
       return temp;
     }
    +inline void ClientDownloadRequest::set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature) {
    +  delete signature_;
    +  signature_ = signature;
    +  if (signature) {
    +    set_has_signature();
    +  } else {
    +    clear_has_signature();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.signature)
    +}
     
     // optional bool user_initiated = 6;
     inline bool ClientDownloadRequest::has_user_initiated() const {
    @@ -2473,11 +8504,13 @@ inline void ClientDownloadRequest::clear_user_initiated() {
       clear_has_user_initiated();
     }
     inline bool ClientDownloadRequest::user_initiated() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.user_initiated)
       return user_initiated_;
     }
     inline void ClientDownloadRequest::set_user_initiated(bool value) {
       set_has_user_initiated();
       user_initiated_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.user_initiated)
     }
     
     // optional string file_basename = 9;
    @@ -2491,52 +8524,70 @@ inline void ClientDownloadRequest::clear_has_file_basename() {
       _has_bits_[0] &= ~0x00000040u;
     }
     inline void ClientDownloadRequest::clear_file_basename() {
    -  if (file_basename_ != &::google::protobuf::internal::kEmptyString) {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_basename_->clear();
       }
       clear_has_file_basename();
     }
     inline const ::std::string& ClientDownloadRequest::file_basename() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.file_basename)
       return *file_basename_;
     }
     inline void ClientDownloadRequest::set_file_basename(const ::std::string& value) {
       set_has_file_basename();
    -  if (file_basename_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_basename_ = new ::std::string;
       }
       file_basename_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.file_basename)
     }
     inline void ClientDownloadRequest::set_file_basename(const char* value) {
       set_has_file_basename();
    -  if (file_basename_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_basename_ = new ::std::string;
       }
       file_basename_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.file_basename)
     }
     inline void ClientDownloadRequest::set_file_basename(const char* value, size_t size) {
       set_has_file_basename();
    -  if (file_basename_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_basename_ = new ::std::string;
       }
       file_basename_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.file_basename)
     }
     inline ::std::string* ClientDownloadRequest::mutable_file_basename() {
       set_has_file_basename();
    -  if (file_basename_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         file_basename_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.file_basename)
       return file_basename_;
     }
     inline ::std::string* ClientDownloadRequest::release_file_basename() {
       clear_has_file_basename();
    -  if (file_basename_ == &::google::protobuf::internal::kEmptyString) {
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = file_basename_;
    -    file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest::set_allocated_file_basename(::std::string* file_basename) {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete file_basename_;
    +  }
    +  if (file_basename) {
    +    set_has_file_basename();
    +    file_basename_ = file_basename;
    +  } else {
    +    clear_has_file_basename();
    +    file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.file_basename)
    +}
     
     // optional .safe_browsing.ClientDownloadRequest.DownloadType download_type = 10 [default = WIN_EXECUTABLE];
     inline bool ClientDownloadRequest::has_download_type() const {
    @@ -2553,12 +8604,14 @@ inline void ClientDownloadRequest::clear_download_type() {
       clear_has_download_type();
     }
     inline ::safe_browsing::ClientDownloadRequest_DownloadType ClientDownloadRequest::download_type() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.download_type)
       return static_cast< ::safe_browsing::ClientDownloadRequest_DownloadType >(download_type_);
     }
     inline void ClientDownloadRequest::set_download_type(::safe_browsing::ClientDownloadRequest_DownloadType value) {
    -  GOOGLE_DCHECK(::safe_browsing::ClientDownloadRequest_DownloadType_IsValid(value));
    +  assert(::safe_browsing::ClientDownloadRequest_DownloadType_IsValid(value));
       set_has_download_type();
       download_type_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.download_type)
     }
     
     // optional string locale = 11;
    @@ -2572,52 +8625,70 @@ inline void ClientDownloadRequest::clear_has_locale() {
       _has_bits_[0] &= ~0x00000100u;
     }
     inline void ClientDownloadRequest::clear_locale() {
    -  if (locale_ != &::google::protobuf::internal::kEmptyString) {
    +  if (locale_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         locale_->clear();
       }
       clear_has_locale();
     }
     inline const ::std::string& ClientDownloadRequest::locale() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.locale)
       return *locale_;
     }
     inline void ClientDownloadRequest::set_locale(const ::std::string& value) {
       set_has_locale();
    -  if (locale_ == &::google::protobuf::internal::kEmptyString) {
    +  if (locale_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         locale_ = new ::std::string;
       }
       locale_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadRequest.locale)
     }
     inline void ClientDownloadRequest::set_locale(const char* value) {
       set_has_locale();
    -  if (locale_ == &::google::protobuf::internal::kEmptyString) {
    +  if (locale_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         locale_ = new ::std::string;
       }
       locale_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadRequest.locale)
     }
     inline void ClientDownloadRequest::set_locale(const char* value, size_t size) {
       set_has_locale();
    -  if (locale_ == &::google::protobuf::internal::kEmptyString) {
    +  if (locale_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         locale_ = new ::std::string;
       }
       locale_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadRequest.locale)
     }
     inline ::std::string* ClientDownloadRequest::mutable_locale() {
       set_has_locale();
    -  if (locale_ == &::google::protobuf::internal::kEmptyString) {
    +  if (locale_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         locale_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.locale)
       return locale_;
     }
     inline ::std::string* ClientDownloadRequest::release_locale() {
       clear_has_locale();
    -  if (locale_ == &::google::protobuf::internal::kEmptyString) {
    +  if (locale_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = locale_;
    -    locale_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    locale_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadRequest::set_allocated_locale(::std::string* locale) {
    +  if (locale_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete locale_;
    +  }
    +  if (locale) {
    +    set_has_locale();
    +    locale_ = locale;
    +  } else {
    +    clear_has_locale();
    +    locale_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.locale)
    +}
     
     // optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 18;
     inline bool ClientDownloadRequest::has_image_headers() const {
    @@ -2634,11 +8705,17 @@ inline void ClientDownloadRequest::clear_image_headers() {
       clear_has_image_headers();
     }
     inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& ClientDownloadRequest::image_headers() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.image_headers)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return image_headers_ != NULL ? *image_headers_ : *default_instance().image_headers_;
    +#else
       return image_headers_ != NULL ? *image_headers_ : *default_instance_->image_headers_;
    +#endif
     }
     inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientDownloadRequest::mutable_image_headers() {
       set_has_image_headers();
       if (image_headers_ == NULL) image_headers_ = new ::safe_browsing::ClientDownloadRequest_ImageHeaders;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.image_headers)
       return image_headers_;
     }
     inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientDownloadRequest::release_image_headers() {
    @@ -2647,6 +8724,46 @@ inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientDownloadReques
       image_headers_ = NULL;
       return temp;
     }
    +inline void ClientDownloadRequest::set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers) {
    +  delete image_headers_;
    +  image_headers_ = image_headers;
    +  if (image_headers) {
    +    set_has_image_headers();
    +  } else {
    +    clear_has_image_headers();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadRequest.image_headers)
    +}
    +
    +// repeated .safe_browsing.ClientDownloadRequest.ArchivedBinary archived_binary = 22;
    +inline int ClientDownloadRequest::archived_binary_size() const {
    +  return archived_binary_.size();
    +}
    +inline void ClientDownloadRequest::clear_archived_binary() {
    +  archived_binary_.Clear();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_ArchivedBinary& ClientDownloadRequest::archived_binary(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadRequest.archived_binary)
    +  return archived_binary_.Get(index);
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ArchivedBinary* ClientDownloadRequest::mutable_archived_binary(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadRequest.archived_binary)
    +  return archived_binary_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ArchivedBinary* ClientDownloadRequest::add_archived_binary() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientDownloadRequest.archived_binary)
    +  return archived_binary_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_ArchivedBinary >&
    +ClientDownloadRequest::archived_binary() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientDownloadRequest.archived_binary)
    +  return archived_binary_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientDownloadRequest_ArchivedBinary >*
    +ClientDownloadRequest::mutable_archived_binary() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientDownloadRequest.archived_binary)
    +  return &archived_binary_;
    +}
     
     // -------------------------------------------------------------------
     
    @@ -2663,52 +8780,70 @@ inline void ClientDownloadResponse_MoreInfo::clear_has_description() {
       _has_bits_[0] &= ~0x00000001u;
     }
     inline void ClientDownloadResponse_MoreInfo::clear_description() {
    -  if (description_ != &::google::protobuf::internal::kEmptyString) {
    +  if (description_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         description_->clear();
       }
       clear_has_description();
     }
     inline const ::std::string& ClientDownloadResponse_MoreInfo::description() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadResponse.MoreInfo.description)
       return *description_;
     }
     inline void ClientDownloadResponse_MoreInfo::set_description(const ::std::string& value) {
       set_has_description();
    -  if (description_ == &::google::protobuf::internal::kEmptyString) {
    +  if (description_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         description_ = new ::std::string;
       }
       description_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadResponse.MoreInfo.description)
     }
     inline void ClientDownloadResponse_MoreInfo::set_description(const char* value) {
       set_has_description();
    -  if (description_ == &::google::protobuf::internal::kEmptyString) {
    +  if (description_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         description_ = new ::std::string;
       }
       description_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadResponse.MoreInfo.description)
     }
     inline void ClientDownloadResponse_MoreInfo::set_description(const char* value, size_t size) {
       set_has_description();
    -  if (description_ == &::google::protobuf::internal::kEmptyString) {
    +  if (description_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         description_ = new ::std::string;
       }
       description_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadResponse.MoreInfo.description)
     }
     inline ::std::string* ClientDownloadResponse_MoreInfo::mutable_description() {
       set_has_description();
    -  if (description_ == &::google::protobuf::internal::kEmptyString) {
    +  if (description_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         description_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadResponse.MoreInfo.description)
       return description_;
     }
     inline ::std::string* ClientDownloadResponse_MoreInfo::release_description() {
       clear_has_description();
    -  if (description_ == &::google::protobuf::internal::kEmptyString) {
    +  if (description_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = description_;
    -    description_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    description_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadResponse_MoreInfo::set_allocated_description(::std::string* description) {
    +  if (description_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete description_;
    +  }
    +  if (description) {
    +    set_has_description();
    +    description_ = description;
    +  } else {
    +    clear_has_description();
    +    description_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadResponse.MoreInfo.description)
    +}
     
     // optional string url = 2;
     inline bool ClientDownloadResponse_MoreInfo::has_url() const {
    @@ -2721,52 +8856,70 @@ inline void ClientDownloadResponse_MoreInfo::clear_has_url() {
       _has_bits_[0] &= ~0x00000002u;
     }
     inline void ClientDownloadResponse_MoreInfo::clear_url() {
    -  if (url_ != &::google::protobuf::internal::kEmptyString) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_->clear();
       }
       clear_has_url();
     }
     inline const ::std::string& ClientDownloadResponse_MoreInfo::url() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadResponse.MoreInfo.url)
       return *url_;
     }
     inline void ClientDownloadResponse_MoreInfo::set_url(const ::std::string& value) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadResponse.MoreInfo.url)
     }
     inline void ClientDownloadResponse_MoreInfo::set_url(const char* value) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadResponse.MoreInfo.url)
     }
     inline void ClientDownloadResponse_MoreInfo::set_url(const char* value, size_t size) {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
       url_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadResponse.MoreInfo.url)
     }
     inline ::std::string* ClientDownloadResponse_MoreInfo::mutable_url() {
       set_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         url_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadResponse.MoreInfo.url)
       return url_;
     }
     inline ::std::string* ClientDownloadResponse_MoreInfo::release_url() {
       clear_has_url();
    -  if (url_ == &::google::protobuf::internal::kEmptyString) {
    +  if (url_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = url_;
    -    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadResponse_MoreInfo::set_allocated_url(::std::string* url) {
    +  if (url_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete url_;
    +  }
    +  if (url) {
    +    set_has_url();
    +    url_ = url;
    +  } else {
    +    clear_has_url();
    +    url_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadResponse.MoreInfo.url)
    +}
     
     // -------------------------------------------------------------------
     
    @@ -2787,12 +8940,14 @@ inline void ClientDownloadResponse::clear_verdict() {
       clear_has_verdict();
     }
     inline ::safe_browsing::ClientDownloadResponse_Verdict ClientDownloadResponse::verdict() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadResponse.verdict)
       return static_cast< ::safe_browsing::ClientDownloadResponse_Verdict >(verdict_);
     }
     inline void ClientDownloadResponse::set_verdict(::safe_browsing::ClientDownloadResponse_Verdict value) {
    -  GOOGLE_DCHECK(::safe_browsing::ClientDownloadResponse_Verdict_IsValid(value));
    +  assert(::safe_browsing::ClientDownloadResponse_Verdict_IsValid(value));
       set_has_verdict();
       verdict_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadResponse.verdict)
     }
     
     // optional .safe_browsing.ClientDownloadResponse.MoreInfo more_info = 2;
    @@ -2810,11 +8965,17 @@ inline void ClientDownloadResponse::clear_more_info() {
       clear_has_more_info();
     }
     inline const ::safe_browsing::ClientDownloadResponse_MoreInfo& ClientDownloadResponse::more_info() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadResponse.more_info)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return more_info_ != NULL ? *more_info_ : *default_instance().more_info_;
    +#else
       return more_info_ != NULL ? *more_info_ : *default_instance_->more_info_;
    +#endif
     }
     inline ::safe_browsing::ClientDownloadResponse_MoreInfo* ClientDownloadResponse::mutable_more_info() {
       set_has_more_info();
       if (more_info_ == NULL) more_info_ = new ::safe_browsing::ClientDownloadResponse_MoreInfo;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadResponse.more_info)
       return more_info_;
     }
     inline ::safe_browsing::ClientDownloadResponse_MoreInfo* ClientDownloadResponse::release_more_info() {
    @@ -2823,6 +8984,16 @@ inline ::safe_browsing::ClientDownloadResponse_MoreInfo* ClientDownloadResponse:
       more_info_ = NULL;
       return temp;
     }
    +inline void ClientDownloadResponse::set_allocated_more_info(::safe_browsing::ClientDownloadResponse_MoreInfo* more_info) {
    +  delete more_info_;
    +  more_info_ = more_info;
    +  if (more_info) {
    +    set_has_more_info();
    +  } else {
    +    clear_has_more_info();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadResponse.more_info)
    +}
     
     // optional bytes token = 3;
     inline bool ClientDownloadResponse::has_token() const {
    @@ -2835,52 +9006,3595 @@ inline void ClientDownloadResponse::clear_has_token() {
       _has_bits_[0] &= ~0x00000004u;
     }
     inline void ClientDownloadResponse::clear_token() {
    -  if (token_ != &::google::protobuf::internal::kEmptyString) {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         token_->clear();
       }
       clear_has_token();
     }
     inline const ::std::string& ClientDownloadResponse::token() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadResponse.token)
       return *token_;
     }
     inline void ClientDownloadResponse::set_token(const ::std::string& value) {
       set_has_token();
    -  if (token_ == &::google::protobuf::internal::kEmptyString) {
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         token_ = new ::std::string;
       }
       token_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadResponse.token)
     }
     inline void ClientDownloadResponse::set_token(const char* value) {
       set_has_token();
    -  if (token_ == &::google::protobuf::internal::kEmptyString) {
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         token_ = new ::std::string;
       }
       token_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadResponse.token)
     }
     inline void ClientDownloadResponse::set_token(const void* value, size_t size) {
       set_has_token();
    -  if (token_ == &::google::protobuf::internal::kEmptyString) {
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         token_ = new ::std::string;
       }
       token_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadResponse.token)
     }
     inline ::std::string* ClientDownloadResponse::mutable_token() {
       set_has_token();
    -  if (token_ == &::google::protobuf::internal::kEmptyString) {
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         token_ = new ::std::string;
       }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadResponse.token)
       return token_;
     }
     inline ::std::string* ClientDownloadResponse::release_token() {
       clear_has_token();
    -  if (token_ == &::google::protobuf::internal::kEmptyString) {
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
         return NULL;
       } else {
         ::std::string* temp = token_;
    -    token_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    +    token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
         return temp;
       }
     }
    +inline void ClientDownloadResponse::set_allocated_token(::std::string* token) {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete token_;
    +  }
    +  if (token) {
    +    set_has_token();
    +    token_ = token;
    +  } else {
    +    clear_has_token();
    +    token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadResponse.token)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientDownloadReport_UserInformation
    +
    +// optional string email = 1;
    +inline bool ClientDownloadReport_UserInformation::has_email() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientDownloadReport_UserInformation::set_has_email() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientDownloadReport_UserInformation::clear_has_email() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientDownloadReport_UserInformation::clear_email() {
    +  if (email_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    email_->clear();
    +  }
    +  clear_has_email();
    +}
    +inline const ::std::string& ClientDownloadReport_UserInformation::email() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadReport.UserInformation.email)
    +  return *email_;
    +}
    +inline void ClientDownloadReport_UserInformation::set_email(const ::std::string& value) {
    +  set_has_email();
    +  if (email_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    email_ = new ::std::string;
    +  }
    +  email_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadReport.UserInformation.email)
    +}
    +inline void ClientDownloadReport_UserInformation::set_email(const char* value) {
    +  set_has_email();
    +  if (email_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    email_ = new ::std::string;
    +  }
    +  email_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadReport.UserInformation.email)
    +}
    +inline void ClientDownloadReport_UserInformation::set_email(const char* value, size_t size) {
    +  set_has_email();
    +  if (email_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    email_ = new ::std::string;
    +  }
    +  email_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadReport.UserInformation.email)
    +}
    +inline ::std::string* ClientDownloadReport_UserInformation::mutable_email() {
    +  set_has_email();
    +  if (email_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    email_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadReport.UserInformation.email)
    +  return email_;
    +}
    +inline ::std::string* ClientDownloadReport_UserInformation::release_email() {
    +  clear_has_email();
    +  if (email_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = email_;
    +    email_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientDownloadReport_UserInformation::set_allocated_email(::std::string* email) {
    +  if (email_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete email_;
    +  }
    +  if (email) {
    +    set_has_email();
    +    email_ = email;
    +  } else {
    +    clear_has_email();
    +    email_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadReport.UserInformation.email)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientDownloadReport
    +
    +// optional .safe_browsing.ClientDownloadReport.Reason reason = 1;
    +inline bool ClientDownloadReport::has_reason() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientDownloadReport::set_has_reason() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientDownloadReport::clear_has_reason() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientDownloadReport::clear_reason() {
    +  reason_ = 0;
    +  clear_has_reason();
    +}
    +inline ::safe_browsing::ClientDownloadReport_Reason ClientDownloadReport::reason() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadReport.reason)
    +  return static_cast< ::safe_browsing::ClientDownloadReport_Reason >(reason_);
    +}
    +inline void ClientDownloadReport::set_reason(::safe_browsing::ClientDownloadReport_Reason value) {
    +  assert(::safe_browsing::ClientDownloadReport_Reason_IsValid(value));
    +  set_has_reason();
    +  reason_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadReport.reason)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest download_request = 2;
    +inline bool ClientDownloadReport::has_download_request() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientDownloadReport::set_has_download_request() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientDownloadReport::clear_has_download_request() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientDownloadReport::clear_download_request() {
    +  if (download_request_ != NULL) download_request_->::safe_browsing::ClientDownloadRequest::Clear();
    +  clear_has_download_request();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest& ClientDownloadReport::download_request() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadReport.download_request)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return download_request_ != NULL ? *download_request_ : *default_instance().download_request_;
    +#else
    +  return download_request_ != NULL ? *download_request_ : *default_instance_->download_request_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest* ClientDownloadReport::mutable_download_request() {
    +  set_has_download_request();
    +  if (download_request_ == NULL) download_request_ = new ::safe_browsing::ClientDownloadRequest;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadReport.download_request)
    +  return download_request_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest* ClientDownloadReport::release_download_request() {
    +  clear_has_download_request();
    +  ::safe_browsing::ClientDownloadRequest* temp = download_request_;
    +  download_request_ = NULL;
    +  return temp;
    +}
    +inline void ClientDownloadReport::set_allocated_download_request(::safe_browsing::ClientDownloadRequest* download_request) {
    +  delete download_request_;
    +  download_request_ = download_request;
    +  if (download_request) {
    +    set_has_download_request();
    +  } else {
    +    clear_has_download_request();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadReport.download_request)
    +}
    +
    +// optional .safe_browsing.ClientDownloadReport.UserInformation user_information = 3;
    +inline bool ClientDownloadReport::has_user_information() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientDownloadReport::set_has_user_information() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientDownloadReport::clear_has_user_information() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientDownloadReport::clear_user_information() {
    +  if (user_information_ != NULL) user_information_->::safe_browsing::ClientDownloadReport_UserInformation::Clear();
    +  clear_has_user_information();
    +}
    +inline const ::safe_browsing::ClientDownloadReport_UserInformation& ClientDownloadReport::user_information() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadReport.user_information)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return user_information_ != NULL ? *user_information_ : *default_instance().user_information_;
    +#else
    +  return user_information_ != NULL ? *user_information_ : *default_instance_->user_information_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadReport_UserInformation* ClientDownloadReport::mutable_user_information() {
    +  set_has_user_information();
    +  if (user_information_ == NULL) user_information_ = new ::safe_browsing::ClientDownloadReport_UserInformation;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadReport.user_information)
    +  return user_information_;
    +}
    +inline ::safe_browsing::ClientDownloadReport_UserInformation* ClientDownloadReport::release_user_information() {
    +  clear_has_user_information();
    +  ::safe_browsing::ClientDownloadReport_UserInformation* temp = user_information_;
    +  user_information_ = NULL;
    +  return temp;
    +}
    +inline void ClientDownloadReport::set_allocated_user_information(::safe_browsing::ClientDownloadReport_UserInformation* user_information) {
    +  delete user_information_;
    +  user_information_ = user_information;
    +  if (user_information) {
    +    set_has_user_information();
    +  } else {
    +    clear_has_user_information();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadReport.user_information)
    +}
    +
    +// optional bytes comment = 4;
    +inline bool ClientDownloadReport::has_comment() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientDownloadReport::set_has_comment() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientDownloadReport::clear_has_comment() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientDownloadReport::clear_comment() {
    +  if (comment_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    comment_->clear();
    +  }
    +  clear_has_comment();
    +}
    +inline const ::std::string& ClientDownloadReport::comment() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadReport.comment)
    +  return *comment_;
    +}
    +inline void ClientDownloadReport::set_comment(const ::std::string& value) {
    +  set_has_comment();
    +  if (comment_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    comment_ = new ::std::string;
    +  }
    +  comment_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientDownloadReport.comment)
    +}
    +inline void ClientDownloadReport::set_comment(const char* value) {
    +  set_has_comment();
    +  if (comment_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    comment_ = new ::std::string;
    +  }
    +  comment_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientDownloadReport.comment)
    +}
    +inline void ClientDownloadReport::set_comment(const void* value, size_t size) {
    +  set_has_comment();
    +  if (comment_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    comment_ = new ::std::string;
    +  }
    +  comment_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientDownloadReport.comment)
    +}
    +inline ::std::string* ClientDownloadReport::mutable_comment() {
    +  set_has_comment();
    +  if (comment_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    comment_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadReport.comment)
    +  return comment_;
    +}
    +inline ::std::string* ClientDownloadReport::release_comment() {
    +  clear_has_comment();
    +  if (comment_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = comment_;
    +    comment_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientDownloadReport::set_allocated_comment(::std::string* comment) {
    +  if (comment_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete comment_;
    +  }
    +  if (comment) {
    +    set_has_comment();
    +    comment_ = comment;
    +  } else {
    +    clear_has_comment();
    +    comment_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadReport.comment)
    +}
    +
    +// optional .safe_browsing.ClientDownloadResponse download_response = 5;
    +inline bool ClientDownloadReport::has_download_response() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void ClientDownloadReport::set_has_download_response() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void ClientDownloadReport::clear_has_download_response() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void ClientDownloadReport::clear_download_response() {
    +  if (download_response_ != NULL) download_response_->::safe_browsing::ClientDownloadResponse::Clear();
    +  clear_has_download_response();
    +}
    +inline const ::safe_browsing::ClientDownloadResponse& ClientDownloadReport::download_response() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientDownloadReport.download_response)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return download_response_ != NULL ? *download_response_ : *default_instance().download_response_;
    +#else
    +  return download_response_ != NULL ? *download_response_ : *default_instance_->download_response_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadResponse* ClientDownloadReport::mutable_download_response() {
    +  set_has_download_response();
    +  if (download_response_ == NULL) download_response_ = new ::safe_browsing::ClientDownloadResponse;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientDownloadReport.download_response)
    +  return download_response_;
    +}
    +inline ::safe_browsing::ClientDownloadResponse* ClientDownloadReport::release_download_response() {
    +  clear_has_download_response();
    +  ::safe_browsing::ClientDownloadResponse* temp = download_response_;
    +  download_response_ = NULL;
    +  return temp;
    +}
    +inline void ClientDownloadReport::set_allocated_download_response(::safe_browsing::ClientDownloadResponse* download_response) {
    +  delete download_response_;
    +  download_response_ = download_response;
    +  if (download_response) {
    +    set_has_download_response();
    +  } else {
    +    clear_has_download_response();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientDownloadReport.download_response)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientUploadResponse
    +
    +// optional .safe_browsing.ClientUploadResponse.UploadStatus status = 1;
    +inline bool ClientUploadResponse::has_status() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientUploadResponse::set_has_status() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientUploadResponse::clear_has_status() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientUploadResponse::clear_status() {
    +  status_ = 0;
    +  clear_has_status();
    +}
    +inline ::safe_browsing::ClientUploadResponse_UploadStatus ClientUploadResponse::status() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientUploadResponse.status)
    +  return static_cast< ::safe_browsing::ClientUploadResponse_UploadStatus >(status_);
    +}
    +inline void ClientUploadResponse::set_status(::safe_browsing::ClientUploadResponse_UploadStatus value) {
    +  assert(::safe_browsing::ClientUploadResponse_UploadStatus_IsValid(value));
    +  set_has_status();
    +  status_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientUploadResponse.status)
    +}
    +
    +// optional string permalink = 2;
    +inline bool ClientUploadResponse::has_permalink() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientUploadResponse::set_has_permalink() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientUploadResponse::clear_has_permalink() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientUploadResponse::clear_permalink() {
    +  if (permalink_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    permalink_->clear();
    +  }
    +  clear_has_permalink();
    +}
    +inline const ::std::string& ClientUploadResponse::permalink() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientUploadResponse.permalink)
    +  return *permalink_;
    +}
    +inline void ClientUploadResponse::set_permalink(const ::std::string& value) {
    +  set_has_permalink();
    +  if (permalink_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    permalink_ = new ::std::string;
    +  }
    +  permalink_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientUploadResponse.permalink)
    +}
    +inline void ClientUploadResponse::set_permalink(const char* value) {
    +  set_has_permalink();
    +  if (permalink_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    permalink_ = new ::std::string;
    +  }
    +  permalink_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientUploadResponse.permalink)
    +}
    +inline void ClientUploadResponse::set_permalink(const char* value, size_t size) {
    +  set_has_permalink();
    +  if (permalink_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    permalink_ = new ::std::string;
    +  }
    +  permalink_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientUploadResponse.permalink)
    +}
    +inline ::std::string* ClientUploadResponse::mutable_permalink() {
    +  set_has_permalink();
    +  if (permalink_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    permalink_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientUploadResponse.permalink)
    +  return permalink_;
    +}
    +inline ::std::string* ClientUploadResponse::release_permalink() {
    +  clear_has_permalink();
    +  if (permalink_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = permalink_;
    +    permalink_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientUploadResponse::set_allocated_permalink(::std::string* permalink) {
    +  if (permalink_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete permalink_;
    +  }
    +  if (permalink) {
    +    set_has_permalink();
    +    permalink_ = permalink;
    +  } else {
    +    clear_has_permalink();
    +    permalink_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientUploadResponse.permalink)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_IncidentData_TrackedPreferenceIncident
    +
    +// optional string path = 1;
    +inline bool ClientIncidentReport_IncidentData_TrackedPreferenceIncident::has_path() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_has_path() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::clear_has_path() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::clear_path() {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_->clear();
    +  }
    +  clear_has_path();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_TrackedPreferenceIncident::path() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.path)
    +  return *path_;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_path(const ::std::string& value) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.path)
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_path(const char* value) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.path)
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_path(const char* value, size_t size) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.path)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::mutable_path() {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.path)
    +  return path_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::release_path() {
    +  clear_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = path_;
    +    path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_allocated_path(::std::string* path) {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete path_;
    +  }
    +  if (path) {
    +    set_has_path();
    +    path_ = path;
    +  } else {
    +    clear_has_path();
    +    path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.path)
    +}
    +
    +// optional string atomic_value = 2;
    +inline bool ClientIncidentReport_IncidentData_TrackedPreferenceIncident::has_atomic_value() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_has_atomic_value() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::clear_has_atomic_value() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::clear_atomic_value() {
    +  if (atomic_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    atomic_value_->clear();
    +  }
    +  clear_has_atomic_value();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_TrackedPreferenceIncident::atomic_value() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.atomic_value)
    +  return *atomic_value_;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_atomic_value(const ::std::string& value) {
    +  set_has_atomic_value();
    +  if (atomic_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    atomic_value_ = new ::std::string;
    +  }
    +  atomic_value_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.atomic_value)
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_atomic_value(const char* value) {
    +  set_has_atomic_value();
    +  if (atomic_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    atomic_value_ = new ::std::string;
    +  }
    +  atomic_value_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.atomic_value)
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_atomic_value(const char* value, size_t size) {
    +  set_has_atomic_value();
    +  if (atomic_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    atomic_value_ = new ::std::string;
    +  }
    +  atomic_value_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.atomic_value)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::mutable_atomic_value() {
    +  set_has_atomic_value();
    +  if (atomic_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    atomic_value_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.atomic_value)
    +  return atomic_value_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::release_atomic_value() {
    +  clear_has_atomic_value();
    +  if (atomic_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = atomic_value_;
    +    atomic_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_allocated_atomic_value(::std::string* atomic_value) {
    +  if (atomic_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete atomic_value_;
    +  }
    +  if (atomic_value) {
    +    set_has_atomic_value();
    +    atomic_value_ = atomic_value;
    +  } else {
    +    clear_has_atomic_value();
    +    atomic_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.atomic_value)
    +}
    +
    +// repeated string split_key = 3;
    +inline int ClientIncidentReport_IncidentData_TrackedPreferenceIncident::split_key_size() const {
    +  return split_key_.size();
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::clear_split_key() {
    +  split_key_.Clear();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_TrackedPreferenceIncident::split_key(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +  return split_key_.Get(index);
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::mutable_split_key(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +  return split_key_.Mutable(index);
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_split_key(int index, const ::std::string& value) {
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +  split_key_.Mutable(index)->assign(value);
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_split_key(int index, const char* value) {
    +  split_key_.Mutable(index)->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_split_key(int index, const char* value, size_t size) {
    +  split_key_.Mutable(index)->assign(
    +    reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_TrackedPreferenceIncident::add_split_key() {
    +  return split_key_.Add();
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::add_split_key(const ::std::string& value) {
    +  split_key_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::add_split_key(const char* value) {
    +  split_key_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add_char:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::add_split_key(const char* value, size_t size) {
    +  split_key_.Add()->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_add_pointer:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
    +ClientIncidentReport_IncidentData_TrackedPreferenceIncident::split_key() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +  return split_key_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::std::string>*
    +ClientIncidentReport_IncidentData_TrackedPreferenceIncident::mutable_split_key() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.split_key)
    +  return &split_key_;
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.ValueState value_state = 4;
    +inline bool ClientIncidentReport_IncidentData_TrackedPreferenceIncident::has_value_state() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_has_value_state() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::clear_has_value_state() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::clear_value_state() {
    +  value_state_ = 0;
    +  clear_has_value_state();
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState ClientIncidentReport_IncidentData_TrackedPreferenceIncident::value_state() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.value_state)
    +  return static_cast< ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState >(value_state_);
    +}
    +inline void ClientIncidentReport_IncidentData_TrackedPreferenceIncident::set_value_state(::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState value) {
    +  assert(::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState_IsValid(value));
    +  set_has_value_state();
    +  value_state_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident.value_state)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_IncidentData_BinaryIntegrityIncident
    +
    +// optional string file_basename = 1;
    +inline bool ClientIncidentReport_IncidentData_BinaryIntegrityIncident::has_file_basename() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::set_has_file_basename() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::clear_has_file_basename() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::clear_file_basename() {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_->clear();
    +  }
    +  clear_has_file_basename();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_BinaryIntegrityIncident::file_basename() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.file_basename)
    +  return *file_basename_;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::set_file_basename(const ::std::string& value) {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  file_basename_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.file_basename)
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::set_file_basename(const char* value) {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  file_basename_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.file_basename)
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::set_file_basename(const char* value, size_t size) {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  file_basename_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.file_basename)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_BinaryIntegrityIncident::mutable_file_basename() {
    +  set_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    file_basename_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.file_basename)
    +  return file_basename_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_BinaryIntegrityIncident::release_file_basename() {
    +  clear_has_file_basename();
    +  if (file_basename_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = file_basename_;
    +    file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::set_allocated_file_basename(::std::string* file_basename) {
    +  if (file_basename_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete file_basename_;
    +  }
    +  if (file_basename) {
    +    set_has_file_basename();
    +    file_basename_ = file_basename;
    +  } else {
    +    clear_has_file_basename();
    +    file_basename_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.file_basename)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 2;
    +inline bool ClientIncidentReport_IncidentData_BinaryIntegrityIncident::has_signature() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::set_has_signature() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::clear_has_signature() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::clear_signature() {
    +  if (signature_ != NULL) signature_->::safe_browsing::ClientDownloadRequest_SignatureInfo::Clear();
    +  clear_has_signature();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& ClientIncidentReport_IncidentData_BinaryIntegrityIncident::signature() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.signature)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return signature_ != NULL ? *signature_ : *default_instance().signature_;
    +#else
    +  return signature_ != NULL ? *signature_ : *default_instance_->signature_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientIncidentReport_IncidentData_BinaryIntegrityIncident::mutable_signature() {
    +  set_has_signature();
    +  if (signature_ == NULL) signature_ = new ::safe_browsing::ClientDownloadRequest_SignatureInfo;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.signature)
    +  return signature_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientIncidentReport_IncidentData_BinaryIntegrityIncident::release_signature() {
    +  clear_has_signature();
    +  ::safe_browsing::ClientDownloadRequest_SignatureInfo* temp = signature_;
    +  signature_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData_BinaryIntegrityIncident::set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature) {
    +  delete signature_;
    +  signature_ = signature;
    +  if (signature) {
    +    set_has_signature();
    +  } else {
    +    clear_has_signature();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident.signature)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_IncidentData_BlacklistLoadIncident
    +
    +// optional string path = 1;
    +inline bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::has_path() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_has_path() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_has_path() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_path() {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_->clear();
    +  }
    +  clear_has_path();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_BlacklistLoadIncident::path() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.path)
    +  return *path_;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_path(const ::std::string& value) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.path)
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_path(const char* value) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.path)
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_path(const char* value, size_t size) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.path)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_BlacklistLoadIncident::mutable_path() {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.path)
    +  return path_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_BlacklistLoadIncident::release_path() {
    +  clear_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = path_;
    +    path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_allocated_path(::std::string* path) {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete path_;
    +  }
    +  if (path) {
    +    set_has_path();
    +    path_ = path;
    +  } else {
    +    clear_has_path();
    +    path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.path)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.Digests digest = 2;
    +inline bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::has_digest() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_has_digest() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_has_digest() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_digest() {
    +  if (digest_ != NULL) digest_->::safe_browsing::ClientDownloadRequest_Digests::Clear();
    +  clear_has_digest();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_Digests& ClientIncidentReport_IncidentData_BlacklistLoadIncident::digest() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.digest)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return digest_ != NULL ? *digest_ : *default_instance().digest_;
    +#else
    +  return digest_ != NULL ? *digest_ : *default_instance_->digest_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_Digests* ClientIncidentReport_IncidentData_BlacklistLoadIncident::mutable_digest() {
    +  set_has_digest();
    +  if (digest_ == NULL) digest_ = new ::safe_browsing::ClientDownloadRequest_Digests;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.digest)
    +  return digest_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_Digests* ClientIncidentReport_IncidentData_BlacklistLoadIncident::release_digest() {
    +  clear_has_digest();
    +  ::safe_browsing::ClientDownloadRequest_Digests* temp = digest_;
    +  digest_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_allocated_digest(::safe_browsing::ClientDownloadRequest_Digests* digest) {
    +  delete digest_;
    +  digest_ = digest;
    +  if (digest) {
    +    set_has_digest();
    +  } else {
    +    clear_has_digest();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.digest)
    +}
    +
    +// optional string version = 3;
    +inline bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::has_version() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_has_version() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_has_version() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_version() {
    +  if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_->clear();
    +  }
    +  clear_has_version();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_BlacklistLoadIncident::version() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.version)
    +  return *version_;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_version(const ::std::string& value) {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  version_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.version)
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_version(const char* value) {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  version_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.version)
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_version(const char* value, size_t size) {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  version_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.version)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_BlacklistLoadIncident::mutable_version() {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.version)
    +  return version_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_BlacklistLoadIncident::release_version() {
    +  clear_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = version_;
    +    version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_allocated_version(::std::string* version) {
    +  if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete version_;
    +  }
    +  if (version) {
    +    set_has_version();
    +    version_ = version;
    +  } else {
    +    clear_has_version();
    +    version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.version)
    +}
    +
    +// optional bool blacklist_initialized = 4;
    +inline bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::has_blacklist_initialized() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_has_blacklist_initialized() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_has_blacklist_initialized() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_blacklist_initialized() {
    +  blacklist_initialized_ = false;
    +  clear_has_blacklist_initialized();
    +}
    +inline bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::blacklist_initialized() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.blacklist_initialized)
    +  return blacklist_initialized_;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_blacklist_initialized(bool value) {
    +  set_has_blacklist_initialized();
    +  blacklist_initialized_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.blacklist_initialized)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.SignatureInfo signature = 5;
    +inline bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::has_signature() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_has_signature() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_has_signature() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_signature() {
    +  if (signature_ != NULL) signature_->::safe_browsing::ClientDownloadRequest_SignatureInfo::Clear();
    +  clear_has_signature();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_SignatureInfo& ClientIncidentReport_IncidentData_BlacklistLoadIncident::signature() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.signature)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return signature_ != NULL ? *signature_ : *default_instance().signature_;
    +#else
    +  return signature_ != NULL ? *signature_ : *default_instance_->signature_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientIncidentReport_IncidentData_BlacklistLoadIncident::mutable_signature() {
    +  set_has_signature();
    +  if (signature_ == NULL) signature_ = new ::safe_browsing::ClientDownloadRequest_SignatureInfo;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.signature)
    +  return signature_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_SignatureInfo* ClientIncidentReport_IncidentData_BlacklistLoadIncident::release_signature() {
    +  clear_has_signature();
    +  ::safe_browsing::ClientDownloadRequest_SignatureInfo* temp = signature_;
    +  signature_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_allocated_signature(::safe_browsing::ClientDownloadRequest_SignatureInfo* signature) {
    +  delete signature_;
    +  signature_ = signature;
    +  if (signature) {
    +    set_has_signature();
    +  } else {
    +    clear_has_signature();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.signature)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 6;
    +inline bool ClientIncidentReport_IncidentData_BlacklistLoadIncident::has_image_headers() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_has_image_headers() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_has_image_headers() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::clear_image_headers() {
    +  if (image_headers_ != NULL) image_headers_->::safe_browsing::ClientDownloadRequest_ImageHeaders::Clear();
    +  clear_has_image_headers();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& ClientIncidentReport_IncidentData_BlacklistLoadIncident::image_headers() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.image_headers)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return image_headers_ != NULL ? *image_headers_ : *default_instance().image_headers_;
    +#else
    +  return image_headers_ != NULL ? *image_headers_ : *default_instance_->image_headers_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientIncidentReport_IncidentData_BlacklistLoadIncident::mutable_image_headers() {
    +  set_has_image_headers();
    +  if (image_headers_ == NULL) image_headers_ = new ::safe_browsing::ClientDownloadRequest_ImageHeaders;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.image_headers)
    +  return image_headers_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientIncidentReport_IncidentData_BlacklistLoadIncident::release_image_headers() {
    +  clear_has_image_headers();
    +  ::safe_browsing::ClientDownloadRequest_ImageHeaders* temp = image_headers_;
    +  image_headers_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData_BlacklistLoadIncident::set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers) {
    +  delete image_headers_;
    +  image_headers_ = image_headers;
    +  if (image_headers) {
    +    set_has_image_headers();
    +  } else {
    +    clear_has_image_headers();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident.image_headers)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident
    +
    +// optional string variations_seed_signature = 1;
    +inline bool ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::has_variations_seed_signature() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::set_has_variations_seed_signature() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::clear_has_variations_seed_signature() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::clear_variations_seed_signature() {
    +  if (variations_seed_signature_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    variations_seed_signature_->clear();
    +  }
    +  clear_has_variations_seed_signature();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::variations_seed_signature() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident.variations_seed_signature)
    +  return *variations_seed_signature_;
    +}
    +inline void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::set_variations_seed_signature(const ::std::string& value) {
    +  set_has_variations_seed_signature();
    +  if (variations_seed_signature_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    variations_seed_signature_ = new ::std::string;
    +  }
    +  variations_seed_signature_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident.variations_seed_signature)
    +}
    +inline void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::set_variations_seed_signature(const char* value) {
    +  set_has_variations_seed_signature();
    +  if (variations_seed_signature_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    variations_seed_signature_ = new ::std::string;
    +  }
    +  variations_seed_signature_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident.variations_seed_signature)
    +}
    +inline void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::set_variations_seed_signature(const char* value, size_t size) {
    +  set_has_variations_seed_signature();
    +  if (variations_seed_signature_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    variations_seed_signature_ = new ::std::string;
    +  }
    +  variations_seed_signature_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident.variations_seed_signature)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::mutable_variations_seed_signature() {
    +  set_has_variations_seed_signature();
    +  if (variations_seed_signature_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    variations_seed_signature_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident.variations_seed_signature)
    +  return variations_seed_signature_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::release_variations_seed_signature() {
    +  clear_has_variations_seed_signature();
    +  if (variations_seed_signature_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = variations_seed_signature_;
    +    variations_seed_signature_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::set_allocated_variations_seed_signature(::std::string* variations_seed_signature) {
    +  if (variations_seed_signature_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete variations_seed_signature_;
    +  }
    +  if (variations_seed_signature) {
    +    set_has_variations_seed_signature();
    +    variations_seed_signature_ = variations_seed_signature;
    +  } else {
    +    clear_has_variations_seed_signature();
    +    variations_seed_signature_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident.variations_seed_signature)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_IncidentData_ScriptRequestIncident
    +
    +// optional string script_digest = 1;
    +inline bool ClientIncidentReport_IncidentData_ScriptRequestIncident::has_script_digest() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_has_script_digest() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::clear_has_script_digest() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::clear_script_digest() {
    +  if (script_digest_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    script_digest_->clear();
    +  }
    +  clear_has_script_digest();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_ScriptRequestIncident::script_digest() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.script_digest)
    +  return *script_digest_;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_script_digest(const ::std::string& value) {
    +  set_has_script_digest();
    +  if (script_digest_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    script_digest_ = new ::std::string;
    +  }
    +  script_digest_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.script_digest)
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_script_digest(const char* value) {
    +  set_has_script_digest();
    +  if (script_digest_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    script_digest_ = new ::std::string;
    +  }
    +  script_digest_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.script_digest)
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_script_digest(const char* value, size_t size) {
    +  set_has_script_digest();
    +  if (script_digest_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    script_digest_ = new ::std::string;
    +  }
    +  script_digest_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.script_digest)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_ScriptRequestIncident::mutable_script_digest() {
    +  set_has_script_digest();
    +  if (script_digest_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    script_digest_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.script_digest)
    +  return script_digest_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_ScriptRequestIncident::release_script_digest() {
    +  clear_has_script_digest();
    +  if (script_digest_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = script_digest_;
    +    script_digest_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_allocated_script_digest(::std::string* script_digest) {
    +  if (script_digest_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete script_digest_;
    +  }
    +  if (script_digest) {
    +    set_has_script_digest();
    +    script_digest_ = script_digest;
    +  } else {
    +    clear_has_script_digest();
    +    script_digest_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.script_digest)
    +}
    +
    +// optional string inclusion_origin = 2;
    +inline bool ClientIncidentReport_IncidentData_ScriptRequestIncident::has_inclusion_origin() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_has_inclusion_origin() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::clear_has_inclusion_origin() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::clear_inclusion_origin() {
    +  if (inclusion_origin_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    inclusion_origin_->clear();
    +  }
    +  clear_has_inclusion_origin();
    +}
    +inline const ::std::string& ClientIncidentReport_IncidentData_ScriptRequestIncident::inclusion_origin() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.inclusion_origin)
    +  return *inclusion_origin_;
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_inclusion_origin(const ::std::string& value) {
    +  set_has_inclusion_origin();
    +  if (inclusion_origin_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    inclusion_origin_ = new ::std::string;
    +  }
    +  inclusion_origin_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.inclusion_origin)
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_inclusion_origin(const char* value) {
    +  set_has_inclusion_origin();
    +  if (inclusion_origin_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    inclusion_origin_ = new ::std::string;
    +  }
    +  inclusion_origin_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.inclusion_origin)
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_inclusion_origin(const char* value, size_t size) {
    +  set_has_inclusion_origin();
    +  if (inclusion_origin_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    inclusion_origin_ = new ::std::string;
    +  }
    +  inclusion_origin_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.inclusion_origin)
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_ScriptRequestIncident::mutable_inclusion_origin() {
    +  set_has_inclusion_origin();
    +  if (inclusion_origin_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    inclusion_origin_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.inclusion_origin)
    +  return inclusion_origin_;
    +}
    +inline ::std::string* ClientIncidentReport_IncidentData_ScriptRequestIncident::release_inclusion_origin() {
    +  clear_has_inclusion_origin();
    +  if (inclusion_origin_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = inclusion_origin_;
    +    inclusion_origin_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_IncidentData_ScriptRequestIncident::set_allocated_inclusion_origin(::std::string* inclusion_origin) {
    +  if (inclusion_origin_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete inclusion_origin_;
    +  }
    +  if (inclusion_origin) {
    +    set_has_inclusion_origin();
    +    inclusion_origin_ = inclusion_origin;
    +  } else {
    +    clear_has_inclusion_origin();
    +    inclusion_origin_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident.inclusion_origin)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_IncidentData
    +
    +// optional int64 incident_time_msec = 1;
    +inline bool ClientIncidentReport_IncidentData::has_incident_time_msec() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData::set_has_incident_time_msec() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_has_incident_time_msec() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_incident_time_msec() {
    +  incident_time_msec_ = GOOGLE_LONGLONG(0);
    +  clear_has_incident_time_msec();
    +}
    +inline ::google::protobuf::int64 ClientIncidentReport_IncidentData::incident_time_msec() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.incident_time_msec)
    +  return incident_time_msec_;
    +}
    +inline void ClientIncidentReport_IncidentData::set_incident_time_msec(::google::protobuf::int64 value) {
    +  set_has_incident_time_msec();
    +  incident_time_msec_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.IncidentData.incident_time_msec)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.IncidentData.TrackedPreferenceIncident tracked_preference = 2;
    +inline bool ClientIncidentReport_IncidentData::has_tracked_preference() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData::set_has_tracked_preference() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_has_tracked_preference() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_tracked_preference() {
    +  if (tracked_preference_ != NULL) tracked_preference_->::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident::Clear();
    +  clear_has_tracked_preference();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident& ClientIncidentReport_IncidentData::tracked_preference() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.tracked_preference)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return tracked_preference_ != NULL ? *tracked_preference_ : *default_instance().tracked_preference_;
    +#else
    +  return tracked_preference_ != NULL ? *tracked_preference_ : *default_instance_->tracked_preference_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* ClientIncidentReport_IncidentData::mutable_tracked_preference() {
    +  set_has_tracked_preference();
    +  if (tracked_preference_ == NULL) tracked_preference_ = new ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.tracked_preference)
    +  return tracked_preference_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* ClientIncidentReport_IncidentData::release_tracked_preference() {
    +  clear_has_tracked_preference();
    +  ::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* temp = tracked_preference_;
    +  tracked_preference_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData::set_allocated_tracked_preference(::safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* tracked_preference) {
    +  delete tracked_preference_;
    +  tracked_preference_ = tracked_preference;
    +  if (tracked_preference) {
    +    set_has_tracked_preference();
    +  } else {
    +    clear_has_tracked_preference();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.tracked_preference)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.IncidentData.BinaryIntegrityIncident binary_integrity = 3;
    +inline bool ClientIncidentReport_IncidentData::has_binary_integrity() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData::set_has_binary_integrity() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_has_binary_integrity() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_binary_integrity() {
    +  if (binary_integrity_ != NULL) binary_integrity_->::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident::Clear();
    +  clear_has_binary_integrity();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident& ClientIncidentReport_IncidentData::binary_integrity() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.binary_integrity)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return binary_integrity_ != NULL ? *binary_integrity_ : *default_instance().binary_integrity_;
    +#else
    +  return binary_integrity_ != NULL ? *binary_integrity_ : *default_instance_->binary_integrity_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* ClientIncidentReport_IncidentData::mutable_binary_integrity() {
    +  set_has_binary_integrity();
    +  if (binary_integrity_ == NULL) binary_integrity_ = new ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.binary_integrity)
    +  return binary_integrity_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* ClientIncidentReport_IncidentData::release_binary_integrity() {
    +  clear_has_binary_integrity();
    +  ::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* temp = binary_integrity_;
    +  binary_integrity_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData::set_allocated_binary_integrity(::safe_browsing::ClientIncidentReport_IncidentData_BinaryIntegrityIncident* binary_integrity) {
    +  delete binary_integrity_;
    +  binary_integrity_ = binary_integrity;
    +  if (binary_integrity) {
    +    set_has_binary_integrity();
    +  } else {
    +    clear_has_binary_integrity();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.binary_integrity)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.IncidentData.BlacklistLoadIncident blacklist_load = 4;
    +inline bool ClientIncidentReport_IncidentData::has_blacklist_load() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData::set_has_blacklist_load() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_has_blacklist_load() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_blacklist_load() {
    +  if (blacklist_load_ != NULL) blacklist_load_->::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident::Clear();
    +  clear_has_blacklist_load();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident& ClientIncidentReport_IncidentData::blacklist_load() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.blacklist_load)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return blacklist_load_ != NULL ? *blacklist_load_ : *default_instance().blacklist_load_;
    +#else
    +  return blacklist_load_ != NULL ? *blacklist_load_ : *default_instance_->blacklist_load_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* ClientIncidentReport_IncidentData::mutable_blacklist_load() {
    +  set_has_blacklist_load();
    +  if (blacklist_load_ == NULL) blacklist_load_ = new ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.blacklist_load)
    +  return blacklist_load_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* ClientIncidentReport_IncidentData::release_blacklist_load() {
    +  clear_has_blacklist_load();
    +  ::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* temp = blacklist_load_;
    +  blacklist_load_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData::set_allocated_blacklist_load(::safe_browsing::ClientIncidentReport_IncidentData_BlacklistLoadIncident* blacklist_load) {
    +  delete blacklist_load_;
    +  blacklist_load_ = blacklist_load;
    +  if (blacklist_load) {
    +    set_has_blacklist_load();
    +  } else {
    +    clear_has_blacklist_load();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.blacklist_load)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.IncidentData.VariationsSeedSignatureIncident variations_seed_signature = 6;
    +inline bool ClientIncidentReport_IncidentData::has_variations_seed_signature() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData::set_has_variations_seed_signature() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_has_variations_seed_signature() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_variations_seed_signature() {
    +  if (variations_seed_signature_ != NULL) variations_seed_signature_->::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident::Clear();
    +  clear_has_variations_seed_signature();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident& ClientIncidentReport_IncidentData::variations_seed_signature() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.variations_seed_signature)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return variations_seed_signature_ != NULL ? *variations_seed_signature_ : *default_instance().variations_seed_signature_;
    +#else
    +  return variations_seed_signature_ != NULL ? *variations_seed_signature_ : *default_instance_->variations_seed_signature_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* ClientIncidentReport_IncidentData::mutable_variations_seed_signature() {
    +  set_has_variations_seed_signature();
    +  if (variations_seed_signature_ == NULL) variations_seed_signature_ = new ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.variations_seed_signature)
    +  return variations_seed_signature_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* ClientIncidentReport_IncidentData::release_variations_seed_signature() {
    +  clear_has_variations_seed_signature();
    +  ::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* temp = variations_seed_signature_;
    +  variations_seed_signature_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData::set_allocated_variations_seed_signature(::safe_browsing::ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident* variations_seed_signature) {
    +  delete variations_seed_signature_;
    +  variations_seed_signature_ = variations_seed_signature;
    +  if (variations_seed_signature) {
    +    set_has_variations_seed_signature();
    +  } else {
    +    clear_has_variations_seed_signature();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.variations_seed_signature)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.IncidentData.ScriptRequestIncident script_request = 7;
    +inline bool ClientIncidentReport_IncidentData::has_script_request() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void ClientIncidentReport_IncidentData::set_has_script_request() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_has_script_request() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void ClientIncidentReport_IncidentData::clear_script_request() {
    +  if (script_request_ != NULL) script_request_->::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident::Clear();
    +  clear_has_script_request();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident& ClientIncidentReport_IncidentData::script_request() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.IncidentData.script_request)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return script_request_ != NULL ? *script_request_ : *default_instance().script_request_;
    +#else
    +  return script_request_ != NULL ? *script_request_ : *default_instance_->script_request_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* ClientIncidentReport_IncidentData::mutable_script_request() {
    +  set_has_script_request();
    +  if (script_request_ == NULL) script_request_ = new ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.IncidentData.script_request)
    +  return script_request_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* ClientIncidentReport_IncidentData::release_script_request() {
    +  clear_has_script_request();
    +  ::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* temp = script_request_;
    +  script_request_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_IncidentData::set_allocated_script_request(::safe_browsing::ClientIncidentReport_IncidentData_ScriptRequestIncident* script_request) {
    +  delete script_request_;
    +  script_request_ = script_request;
    +  if (script_request) {
    +    set_has_script_request();
    +  } else {
    +    clear_has_script_request();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.IncidentData.script_request)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_DownloadDetails
    +
    +// optional bytes token = 1;
    +inline bool ClientIncidentReport_DownloadDetails::has_token() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_has_token() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_has_token() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_token() {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_->clear();
    +  }
    +  clear_has_token();
    +}
    +inline const ::std::string& ClientIncidentReport_DownloadDetails::token() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.DownloadDetails.token)
    +  return *token_;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_token(const ::std::string& value) {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  token_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.DownloadDetails.token)
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_token(const char* value) {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  token_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.DownloadDetails.token)
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_token(const void* value, size_t size) {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  token_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.DownloadDetails.token)
    +}
    +inline ::std::string* ClientIncidentReport_DownloadDetails::mutable_token() {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.DownloadDetails.token)
    +  return token_;
    +}
    +inline ::std::string* ClientIncidentReport_DownloadDetails::release_token() {
    +  clear_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = token_;
    +    token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_allocated_token(::std::string* token) {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete token_;
    +  }
    +  if (token) {
    +    set_has_token();
    +    token_ = token;
    +  } else {
    +    clear_has_token();
    +    token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.DownloadDetails.token)
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest download = 2;
    +inline bool ClientIncidentReport_DownloadDetails::has_download() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_has_download() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_has_download() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_download() {
    +  if (download_ != NULL) download_->::safe_browsing::ClientDownloadRequest::Clear();
    +  clear_has_download();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest& ClientIncidentReport_DownloadDetails::download() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.DownloadDetails.download)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return download_ != NULL ? *download_ : *default_instance().download_;
    +#else
    +  return download_ != NULL ? *download_ : *default_instance_->download_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest* ClientIncidentReport_DownloadDetails::mutable_download() {
    +  set_has_download();
    +  if (download_ == NULL) download_ = new ::safe_browsing::ClientDownloadRequest;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.DownloadDetails.download)
    +  return download_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest* ClientIncidentReport_DownloadDetails::release_download() {
    +  clear_has_download();
    +  ::safe_browsing::ClientDownloadRequest* temp = download_;
    +  download_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_allocated_download(::safe_browsing::ClientDownloadRequest* download) {
    +  delete download_;
    +  download_ = download;
    +  if (download) {
    +    set_has_download();
    +  } else {
    +    clear_has_download();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.DownloadDetails.download)
    +}
    +
    +// optional int64 download_time_msec = 3;
    +inline bool ClientIncidentReport_DownloadDetails::has_download_time_msec() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_has_download_time_msec() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_has_download_time_msec() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_download_time_msec() {
    +  download_time_msec_ = GOOGLE_LONGLONG(0);
    +  clear_has_download_time_msec();
    +}
    +inline ::google::protobuf::int64 ClientIncidentReport_DownloadDetails::download_time_msec() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.DownloadDetails.download_time_msec)
    +  return download_time_msec_;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_download_time_msec(::google::protobuf::int64 value) {
    +  set_has_download_time_msec();
    +  download_time_msec_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.DownloadDetails.download_time_msec)
    +}
    +
    +// optional int64 open_time_msec = 4;
    +inline bool ClientIncidentReport_DownloadDetails::has_open_time_msec() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_has_open_time_msec() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_has_open_time_msec() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void ClientIncidentReport_DownloadDetails::clear_open_time_msec() {
    +  open_time_msec_ = GOOGLE_LONGLONG(0);
    +  clear_has_open_time_msec();
    +}
    +inline ::google::protobuf::int64 ClientIncidentReport_DownloadDetails::open_time_msec() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.DownloadDetails.open_time_msec)
    +  return open_time_msec_;
    +}
    +inline void ClientIncidentReport_DownloadDetails::set_open_time_msec(::google::protobuf::int64 value) {
    +  set_has_open_time_msec();
    +  open_time_msec_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.DownloadDetails.open_time_msec)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData_OS
    +
    +// optional string os_name = 1;
    +inline bool ClientIncidentReport_EnvironmentData_OS::has_os_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_has_os_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::clear_has_os_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::clear_os_name() {
    +  if (os_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_name_->clear();
    +  }
    +  clear_has_os_name();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_OS::os_name() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_name)
    +  return *os_name_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_os_name(const ::std::string& value) {
    +  set_has_os_name();
    +  if (os_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_name_ = new ::std::string;
    +  }
    +  os_name_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_name)
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_os_name(const char* value) {
    +  set_has_os_name();
    +  if (os_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_name_ = new ::std::string;
    +  }
    +  os_name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_name)
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_os_name(const char* value, size_t size) {
    +  set_has_os_name();
    +  if (os_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_name_ = new ::std::string;
    +  }
    +  os_name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_name)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_OS::mutable_os_name() {
    +  set_has_os_name();
    +  if (os_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_name)
    +  return os_name_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_OS::release_os_name() {
    +  clear_has_os_name();
    +  if (os_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = os_name_;
    +    os_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_allocated_os_name(::std::string* os_name) {
    +  if (os_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete os_name_;
    +  }
    +  if (os_name) {
    +    set_has_os_name();
    +    os_name_ = os_name;
    +  } else {
    +    clear_has_os_name();
    +    os_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_name)
    +}
    +
    +// optional string os_version = 2;
    +inline bool ClientIncidentReport_EnvironmentData_OS::has_os_version() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_has_os_version() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::clear_has_os_version() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::clear_os_version() {
    +  if (os_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_version_->clear();
    +  }
    +  clear_has_os_version();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_OS::os_version() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_version)
    +  return *os_version_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_os_version(const ::std::string& value) {
    +  set_has_os_version();
    +  if (os_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_version_ = new ::std::string;
    +  }
    +  os_version_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_version)
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_os_version(const char* value) {
    +  set_has_os_version();
    +  if (os_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_version_ = new ::std::string;
    +  }
    +  os_version_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_version)
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_os_version(const char* value, size_t size) {
    +  set_has_os_version();
    +  if (os_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_version_ = new ::std::string;
    +  }
    +  os_version_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_version)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_OS::mutable_os_version() {
    +  set_has_os_version();
    +  if (os_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    os_version_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_version)
    +  return os_version_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_OS::release_os_version() {
    +  clear_has_os_version();
    +  if (os_version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = os_version_;
    +    os_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_OS::set_allocated_os_version(::std::string* os_version) {
    +  if (os_version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete os_version_;
    +  }
    +  if (os_version) {
    +    set_has_os_version();
    +    os_version_ = os_version;
    +  } else {
    +    clear_has_os_version();
    +    os_version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.OS.os_version)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData_Machine
    +
    +// optional string cpu_architecture = 1;
    +inline bool ClientIncidentReport_EnvironmentData_Machine::has_cpu_architecture() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_has_cpu_architecture() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::clear_has_cpu_architecture() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::clear_cpu_architecture() {
    +  if (cpu_architecture_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_architecture_->clear();
    +  }
    +  clear_has_cpu_architecture();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Machine::cpu_architecture() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_architecture)
    +  return *cpu_architecture_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_cpu_architecture(const ::std::string& value) {
    +  set_has_cpu_architecture();
    +  if (cpu_architecture_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_architecture_ = new ::std::string;
    +  }
    +  cpu_architecture_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_architecture)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_cpu_architecture(const char* value) {
    +  set_has_cpu_architecture();
    +  if (cpu_architecture_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_architecture_ = new ::std::string;
    +  }
    +  cpu_architecture_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_architecture)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_cpu_architecture(const char* value, size_t size) {
    +  set_has_cpu_architecture();
    +  if (cpu_architecture_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_architecture_ = new ::std::string;
    +  }
    +  cpu_architecture_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_architecture)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Machine::mutable_cpu_architecture() {
    +  set_has_cpu_architecture();
    +  if (cpu_architecture_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_architecture_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_architecture)
    +  return cpu_architecture_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Machine::release_cpu_architecture() {
    +  clear_has_cpu_architecture();
    +  if (cpu_architecture_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = cpu_architecture_;
    +    cpu_architecture_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_allocated_cpu_architecture(::std::string* cpu_architecture) {
    +  if (cpu_architecture_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete cpu_architecture_;
    +  }
    +  if (cpu_architecture) {
    +    set_has_cpu_architecture();
    +    cpu_architecture_ = cpu_architecture;
    +  } else {
    +    clear_has_cpu_architecture();
    +    cpu_architecture_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_architecture)
    +}
    +
    +// optional string cpu_vendor = 2;
    +inline bool ClientIncidentReport_EnvironmentData_Machine::has_cpu_vendor() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_has_cpu_vendor() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::clear_has_cpu_vendor() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::clear_cpu_vendor() {
    +  if (cpu_vendor_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_vendor_->clear();
    +  }
    +  clear_has_cpu_vendor();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Machine::cpu_vendor() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_vendor)
    +  return *cpu_vendor_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_cpu_vendor(const ::std::string& value) {
    +  set_has_cpu_vendor();
    +  if (cpu_vendor_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_vendor_ = new ::std::string;
    +  }
    +  cpu_vendor_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_vendor)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_cpu_vendor(const char* value) {
    +  set_has_cpu_vendor();
    +  if (cpu_vendor_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_vendor_ = new ::std::string;
    +  }
    +  cpu_vendor_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_vendor)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_cpu_vendor(const char* value, size_t size) {
    +  set_has_cpu_vendor();
    +  if (cpu_vendor_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_vendor_ = new ::std::string;
    +  }
    +  cpu_vendor_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_vendor)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Machine::mutable_cpu_vendor() {
    +  set_has_cpu_vendor();
    +  if (cpu_vendor_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    cpu_vendor_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_vendor)
    +  return cpu_vendor_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Machine::release_cpu_vendor() {
    +  clear_has_cpu_vendor();
    +  if (cpu_vendor_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = cpu_vendor_;
    +    cpu_vendor_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_allocated_cpu_vendor(::std::string* cpu_vendor) {
    +  if (cpu_vendor_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete cpu_vendor_;
    +  }
    +  if (cpu_vendor) {
    +    set_has_cpu_vendor();
    +    cpu_vendor_ = cpu_vendor;
    +  } else {
    +    clear_has_cpu_vendor();
    +    cpu_vendor_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpu_vendor)
    +}
    +
    +// optional uint32 cpuid = 3;
    +inline bool ClientIncidentReport_EnvironmentData_Machine::has_cpuid() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_has_cpuid() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::clear_has_cpuid() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::clear_cpuid() {
    +  cpuid_ = 0u;
    +  clear_has_cpuid();
    +}
    +inline ::google::protobuf::uint32 ClientIncidentReport_EnvironmentData_Machine::cpuid() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpuid)
    +  return cpuid_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Machine::set_cpuid(::google::protobuf::uint32 value) {
    +  set_has_cpuid();
    +  cpuid_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Machine.cpuid)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData_Process_Patch
    +
    +// optional string function = 1;
    +inline bool ClientIncidentReport_EnvironmentData_Process_Patch::has_function() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_has_function() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::clear_has_function() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::clear_function() {
    +  if (function_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    function_->clear();
    +  }
    +  clear_has_function();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process_Patch::function() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.function)
    +  return *function_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_function(const ::std::string& value) {
    +  set_has_function();
    +  if (function_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    function_ = new ::std::string;
    +  }
    +  function_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.function)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_function(const char* value) {
    +  set_has_function();
    +  if (function_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    function_ = new ::std::string;
    +  }
    +  function_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.function)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_function(const char* value, size_t size) {
    +  set_has_function();
    +  if (function_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    function_ = new ::std::string;
    +  }
    +  function_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.function)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_Patch::mutable_function() {
    +  set_has_function();
    +  if (function_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    function_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.function)
    +  return function_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_Patch::release_function() {
    +  clear_has_function();
    +  if (function_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = function_;
    +    function_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_allocated_function(::std::string* function) {
    +  if (function_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete function_;
    +  }
    +  if (function) {
    +    set_has_function();
    +    function_ = function;
    +  } else {
    +    clear_has_function();
    +    function_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.function)
    +}
    +
    +// optional string target_dll = 2;
    +inline bool ClientIncidentReport_EnvironmentData_Process_Patch::has_target_dll() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_has_target_dll() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::clear_has_target_dll() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::clear_target_dll() {
    +  if (target_dll_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    target_dll_->clear();
    +  }
    +  clear_has_target_dll();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process_Patch::target_dll() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.target_dll)
    +  return *target_dll_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_target_dll(const ::std::string& value) {
    +  set_has_target_dll();
    +  if (target_dll_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    target_dll_ = new ::std::string;
    +  }
    +  target_dll_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.target_dll)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_target_dll(const char* value) {
    +  set_has_target_dll();
    +  if (target_dll_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    target_dll_ = new ::std::string;
    +  }
    +  target_dll_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.target_dll)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_target_dll(const char* value, size_t size) {
    +  set_has_target_dll();
    +  if (target_dll_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    target_dll_ = new ::std::string;
    +  }
    +  target_dll_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.target_dll)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_Patch::mutable_target_dll() {
    +  set_has_target_dll();
    +  if (target_dll_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    target_dll_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.target_dll)
    +  return target_dll_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_Patch::release_target_dll() {
    +  clear_has_target_dll();
    +  if (target_dll_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = target_dll_;
    +    target_dll_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Patch::set_allocated_target_dll(::std::string* target_dll) {
    +  if (target_dll_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete target_dll_;
    +  }
    +  if (target_dll) {
    +    set_has_target_dll();
    +    target_dll_ = target_dll;
    +  } else {
    +    clear_has_target_dll();
    +    target_dll_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch.target_dll)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData_Process_NetworkProvider
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData_Process_Dll
    +
    +// optional string path = 1;
    +inline bool ClientIncidentReport_EnvironmentData_Process_Dll::has_path() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_has_path() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_has_path() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_path() {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_->clear();
    +  }
    +  clear_has_path();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process_Dll::path() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.path)
    +  return *path_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_path(const ::std::string& value) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.path)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_path(const char* value) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.path)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_path(const char* value, size_t size) {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  path_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.path)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_Dll::mutable_path() {
    +  set_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    path_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.path)
    +  return path_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_Dll::release_path() {
    +  clear_has_path();
    +  if (path_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = path_;
    +    path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_allocated_path(::std::string* path) {
    +  if (path_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete path_;
    +  }
    +  if (path) {
    +    set_has_path();
    +    path_ = path;
    +  } else {
    +    clear_has_path();
    +    path_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.path)
    +}
    +
    +// optional uint64 base_address = 2;
    +inline bool ClientIncidentReport_EnvironmentData_Process_Dll::has_base_address() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_has_base_address() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_has_base_address() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_base_address() {
    +  base_address_ = GOOGLE_ULONGLONG(0);
    +  clear_has_base_address();
    +}
    +inline ::google::protobuf::uint64 ClientIncidentReport_EnvironmentData_Process_Dll::base_address() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.base_address)
    +  return base_address_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_base_address(::google::protobuf::uint64 value) {
    +  set_has_base_address();
    +  base_address_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.base_address)
    +}
    +
    +// optional uint32 length = 3;
    +inline bool ClientIncidentReport_EnvironmentData_Process_Dll::has_length() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_has_length() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_has_length() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_length() {
    +  length_ = 0u;
    +  clear_has_length();
    +}
    +inline ::google::protobuf::uint32 ClientIncidentReport_EnvironmentData_Process_Dll::length() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.length)
    +  return length_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_length(::google::protobuf::uint32 value) {
    +  set_has_length();
    +  length_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.length)
    +}
    +
    +// repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.Feature feature = 4;
    +inline int ClientIncidentReport_EnvironmentData_Process_Dll::feature_size() const {
    +  return feature_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_feature() {
    +  feature_.Clear();
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature ClientIncidentReport_EnvironmentData_Process_Dll::feature(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.feature)
    +  return static_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature >(feature_.Get(index));
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_feature(int index, ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature value) {
    +  assert(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature_IsValid(value));
    +  feature_.Set(index, value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.feature)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::add_feature(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature value) {
    +  assert(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll_Feature_IsValid(value));
    +  feature_.Add(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.feature)
    +}
    +inline const ::google::protobuf::RepeatedField&
    +ClientIncidentReport_EnvironmentData_Process_Dll::feature() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.feature)
    +  return feature_;
    +}
    +inline ::google::protobuf::RepeatedField*
    +ClientIncidentReport_EnvironmentData_Process_Dll::mutable_feature() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.feature)
    +  return &feature_;
    +}
    +
    +// optional .safe_browsing.ClientDownloadRequest.ImageHeaders image_headers = 5;
    +inline bool ClientIncidentReport_EnvironmentData_Process_Dll::has_image_headers() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_has_image_headers() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_has_image_headers() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::clear_image_headers() {
    +  if (image_headers_ != NULL) image_headers_->::safe_browsing::ClientDownloadRequest_ImageHeaders::Clear();
    +  clear_has_image_headers();
    +}
    +inline const ::safe_browsing::ClientDownloadRequest_ImageHeaders& ClientIncidentReport_EnvironmentData_Process_Dll::image_headers() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.image_headers)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return image_headers_ != NULL ? *image_headers_ : *default_instance().image_headers_;
    +#else
    +  return image_headers_ != NULL ? *image_headers_ : *default_instance_->image_headers_;
    +#endif
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientIncidentReport_EnvironmentData_Process_Dll::mutable_image_headers() {
    +  set_has_image_headers();
    +  if (image_headers_ == NULL) image_headers_ = new ::safe_browsing::ClientDownloadRequest_ImageHeaders;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.image_headers)
    +  return image_headers_;
    +}
    +inline ::safe_browsing::ClientDownloadRequest_ImageHeaders* ClientIncidentReport_EnvironmentData_Process_Dll::release_image_headers() {
    +  clear_has_image_headers();
    +  ::safe_browsing::ClientDownloadRequest_ImageHeaders* temp = image_headers_;
    +  image_headers_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_Dll::set_allocated_image_headers(::safe_browsing::ClientDownloadRequest_ImageHeaders* image_headers) {
    +  delete image_headers_;
    +  image_headers_ = image_headers;
    +  if (image_headers) {
    +    set_has_image_headers();
    +  } else {
    +    clear_has_image_headers();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll.image_headers)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData_Process_ModuleState
    +
    +// optional string name = 1;
    +inline bool ClientIncidentReport_EnvironmentData_Process_ModuleState::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process_ModuleState::name() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.name)
    +  return *name_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.name)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.name)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.name)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_ModuleState::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.name)
    +  return name_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_ModuleState::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.name)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.ModifiedState modified_state = 2;
    +inline bool ClientIncidentReport_EnvironmentData_Process_ModuleState::has_modified_state() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_has_modified_state() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::clear_has_modified_state() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::clear_modified_state() {
    +  modified_state_ = 0;
    +  clear_has_modified_state();
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState ClientIncidentReport_EnvironmentData_Process_ModuleState::modified_state() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_state)
    +  return static_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState >(modified_state_);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_modified_state(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState value) {
    +  assert(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState_IsValid(value));
    +  set_has_modified_state();
    +  modified_state_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_state)
    +}
    +
    +// repeated string modified_export = 3;
    +inline int ClientIncidentReport_EnvironmentData_Process_ModuleState::modified_export_size() const {
    +  return modified_export_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::clear_modified_export() {
    +  modified_export_.Clear();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process_ModuleState::modified_export(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +  return modified_export_.Get(index);
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_ModuleState::mutable_modified_export(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +  return modified_export_.Mutable(index);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_modified_export(int index, const ::std::string& value) {
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +  modified_export_.Mutable(index)->assign(value);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_modified_export(int index, const char* value) {
    +  modified_export_.Mutable(index)->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::set_modified_export(int index, const char* value, size_t size) {
    +  modified_export_.Mutable(index)->assign(
    +    reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process_ModuleState::add_modified_export() {
    +  return modified_export_.Add();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::add_modified_export(const ::std::string& value) {
    +  modified_export_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::add_modified_export(const char* value) {
    +  modified_export_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process_ModuleState::add_modified_export(const char* value, size_t size) {
    +  modified_export_.Add()->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_add_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
    +ClientIncidentReport_EnvironmentData_Process_ModuleState::modified_export() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +  return modified_export_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::std::string>*
    +ClientIncidentReport_EnvironmentData_Process_ModuleState::mutable_modified_export() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState.modified_export)
    +  return &modified_export_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData_Process
    +
    +// optional string version = 1;
    +inline bool ClientIncidentReport_EnvironmentData_Process::has_version() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_has_version() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_has_version() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_version() {
    +  if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_->clear();
    +  }
    +  clear_has_version();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process::version() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.version)
    +  return *version_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_version(const ::std::string& value) {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  version_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.version)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_version(const char* value) {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  version_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.version)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_version(const char* value, size_t size) {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  version_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.version)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process::mutable_version() {
    +  set_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    version_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.version)
    +  return version_;
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process::release_version() {
    +  clear_has_version();
    +  if (version_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = version_;
    +    version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_allocated_version(::std::string* version) {
    +  if (version_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete version_;
    +  }
    +  if (version) {
    +    set_has_version();
    +    version_ = version;
    +  } else {
    +    clear_has_version();
    +    version_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.Process.version)
    +}
    +
    +// repeated string OBSOLETE_dlls = 2;
    +inline int ClientIncidentReport_EnvironmentData_Process::obsolete_dlls_size() const {
    +  return obsolete_dlls_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_obsolete_dlls() {
    +  obsolete_dlls_.Clear();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process::obsolete_dlls(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +  return obsolete_dlls_.Get(index);
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process::mutable_obsolete_dlls(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +  return obsolete_dlls_.Mutable(index);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_obsolete_dlls(int index, const ::std::string& value) {
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +  obsolete_dlls_.Mutable(index)->assign(value);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_obsolete_dlls(int index, const char* value) {
    +  obsolete_dlls_.Mutable(index)->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_obsolete_dlls(int index, const char* value, size_t size) {
    +  obsolete_dlls_.Mutable(index)->assign(
    +    reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process::add_obsolete_dlls() {
    +  return obsolete_dlls_.Add();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::add_obsolete_dlls(const ::std::string& value) {
    +  obsolete_dlls_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::add_obsolete_dlls(const char* value) {
    +  obsolete_dlls_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::add_obsolete_dlls(const char* value, size_t size) {
    +  obsolete_dlls_.Add()->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_add_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
    +ClientIncidentReport_EnvironmentData_Process::obsolete_dlls() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +  return obsolete_dlls_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::std::string>*
    +ClientIncidentReport_EnvironmentData_Process::mutable_obsolete_dlls() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.OBSOLETE_dlls)
    +  return &obsolete_dlls_;
    +}
    +
    +// repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Patch patches = 3;
    +inline int ClientIncidentReport_EnvironmentData_Process::patches_size() const {
    +  return patches_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_patches() {
    +  patches_.Clear();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch& ClientIncidentReport_EnvironmentData_Process::patches(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.patches)
    +  return patches_.Get(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch* ClientIncidentReport_EnvironmentData_Process::mutable_patches(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.patches)
    +  return patches_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch* ClientIncidentReport_EnvironmentData_Process::add_patches() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.patches)
    +  return patches_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch >&
    +ClientIncidentReport_EnvironmentData_Process::patches() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.patches)
    +  return patches_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Patch >*
    +ClientIncidentReport_EnvironmentData_Process::mutable_patches() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.patches)
    +  return &patches_;
    +}
    +
    +// repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.NetworkProvider network_providers = 4;
    +inline int ClientIncidentReport_EnvironmentData_Process::network_providers_size() const {
    +  return network_providers_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_network_providers() {
    +  network_providers_.Clear();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider& ClientIncidentReport_EnvironmentData_Process::network_providers(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.network_providers)
    +  return network_providers_.Get(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider* ClientIncidentReport_EnvironmentData_Process::mutable_network_providers(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.network_providers)
    +  return network_providers_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider* ClientIncidentReport_EnvironmentData_Process::add_network_providers() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.network_providers)
    +  return network_providers_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider >&
    +ClientIncidentReport_EnvironmentData_Process::network_providers() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.network_providers)
    +  return network_providers_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_NetworkProvider >*
    +ClientIncidentReport_EnvironmentData_Process::mutable_network_providers() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.network_providers)
    +  return &network_providers_;
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Channel chrome_update_channel = 5;
    +inline bool ClientIncidentReport_EnvironmentData_Process::has_chrome_update_channel() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_has_chrome_update_channel() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_has_chrome_update_channel() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_chrome_update_channel() {
    +  chrome_update_channel_ = 0;
    +  clear_has_chrome_update_channel();
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel ClientIncidentReport_EnvironmentData_Process::chrome_update_channel() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.chrome_update_channel)
    +  return static_cast< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel >(chrome_update_channel_);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_chrome_update_channel(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel value) {
    +  assert(::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Channel_IsValid(value));
    +  set_has_chrome_update_channel();
    +  chrome_update_channel_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.chrome_update_channel)
    +}
    +
    +// optional int64 uptime_msec = 6;
    +inline bool ClientIncidentReport_EnvironmentData_Process::has_uptime_msec() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_has_uptime_msec() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_has_uptime_msec() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_uptime_msec() {
    +  uptime_msec_ = GOOGLE_LONGLONG(0);
    +  clear_has_uptime_msec();
    +}
    +inline ::google::protobuf::int64 ClientIncidentReport_EnvironmentData_Process::uptime_msec() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.uptime_msec)
    +  return uptime_msec_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_uptime_msec(::google::protobuf::int64 value) {
    +  set_has_uptime_msec();
    +  uptime_msec_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.uptime_msec)
    +}
    +
    +// optional bool metrics_consent = 7;
    +inline bool ClientIncidentReport_EnvironmentData_Process::has_metrics_consent() const {
    +  return (_has_bits_[0] & 0x00000040u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_has_metrics_consent() {
    +  _has_bits_[0] |= 0x00000040u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_has_metrics_consent() {
    +  _has_bits_[0] &= ~0x00000040u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_metrics_consent() {
    +  metrics_consent_ = false;
    +  clear_has_metrics_consent();
    +}
    +inline bool ClientIncidentReport_EnvironmentData_Process::metrics_consent() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.metrics_consent)
    +  return metrics_consent_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_metrics_consent(bool value) {
    +  set_has_metrics_consent();
    +  metrics_consent_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.metrics_consent)
    +}
    +
    +// optional bool extended_consent = 8;
    +inline bool ClientIncidentReport_EnvironmentData_Process::has_extended_consent() const {
    +  return (_has_bits_[0] & 0x00000080u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_has_extended_consent() {
    +  _has_bits_[0] |= 0x00000080u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_has_extended_consent() {
    +  _has_bits_[0] &= ~0x00000080u;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_extended_consent() {
    +  extended_consent_ = false;
    +  clear_has_extended_consent();
    +}
    +inline bool ClientIncidentReport_EnvironmentData_Process::extended_consent() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.extended_consent)
    +  return extended_consent_;
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_extended_consent(bool value) {
    +  set_has_extended_consent();
    +  extended_consent_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.extended_consent)
    +}
    +
    +// repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.Dll dll = 9;
    +inline int ClientIncidentReport_EnvironmentData_Process::dll_size() const {
    +  return dll_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_dll() {
    +  dll_.Clear();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll& ClientIncidentReport_EnvironmentData_Process::dll(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.dll)
    +  return dll_.Get(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll* ClientIncidentReport_EnvironmentData_Process::mutable_dll(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.dll)
    +  return dll_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll* ClientIncidentReport_EnvironmentData_Process::add_dll() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.dll)
    +  return dll_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll >&
    +ClientIncidentReport_EnvironmentData_Process::dll() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.dll)
    +  return dll_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_Dll >*
    +ClientIncidentReport_EnvironmentData_Process::mutable_dll() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.dll)
    +  return &dll_;
    +}
    +
    +// repeated string blacklisted_dll = 10;
    +inline int ClientIncidentReport_EnvironmentData_Process::blacklisted_dll_size() const {
    +  return blacklisted_dll_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_blacklisted_dll() {
    +  blacklisted_dll_.Clear();
    +}
    +inline const ::std::string& ClientIncidentReport_EnvironmentData_Process::blacklisted_dll(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +  return blacklisted_dll_.Get(index);
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process::mutable_blacklisted_dll(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +  return blacklisted_dll_.Mutable(index);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_blacklisted_dll(int index, const ::std::string& value) {
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +  blacklisted_dll_.Mutable(index)->assign(value);
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_blacklisted_dll(int index, const char* value) {
    +  blacklisted_dll_.Mutable(index)->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::set_blacklisted_dll(int index, const char* value, size_t size) {
    +  blacklisted_dll_.Mutable(index)->assign(
    +    reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +}
    +inline ::std::string* ClientIncidentReport_EnvironmentData_Process::add_blacklisted_dll() {
    +  return blacklisted_dll_.Add();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::add_blacklisted_dll(const ::std::string& value) {
    +  blacklisted_dll_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::add_blacklisted_dll(const char* value) {
    +  blacklisted_dll_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add_char:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::add_blacklisted_dll(const char* value, size_t size) {
    +  blacklisted_dll_.Add()->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_add_pointer:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
    +ClientIncidentReport_EnvironmentData_Process::blacklisted_dll() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +  return blacklisted_dll_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::std::string>*
    +ClientIncidentReport_EnvironmentData_Process::mutable_blacklisted_dll() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.blacklisted_dll)
    +  return &blacklisted_dll_;
    +}
    +
    +// repeated .safe_browsing.ClientIncidentReport.EnvironmentData.Process.ModuleState module_state = 11;
    +inline int ClientIncidentReport_EnvironmentData_Process::module_state_size() const {
    +  return module_state_.size();
    +}
    +inline void ClientIncidentReport_EnvironmentData_Process::clear_module_state() {
    +  module_state_.Clear();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState& ClientIncidentReport_EnvironmentData_Process::module_state(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.Process.module_state)
    +  return module_state_.Get(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState* ClientIncidentReport_EnvironmentData_Process::mutable_module_state(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.Process.module_state)
    +  return module_state_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState* ClientIncidentReport_EnvironmentData_Process::add_module_state() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.EnvironmentData.Process.module_state)
    +  return module_state_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState >&
    +ClientIncidentReport_EnvironmentData_Process::module_state() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.module_state)
    +  return module_state_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_EnvironmentData_Process_ModuleState >*
    +ClientIncidentReport_EnvironmentData_Process::mutable_module_state() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.EnvironmentData.Process.module_state)
    +  return &module_state_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport_EnvironmentData
    +
    +// optional .safe_browsing.ClientIncidentReport.EnvironmentData.OS os = 1;
    +inline bool ClientIncidentReport_EnvironmentData::has_os() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData::set_has_os() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData::clear_has_os() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentReport_EnvironmentData::clear_os() {
    +  if (os_ != NULL) os_->::safe_browsing::ClientIncidentReport_EnvironmentData_OS::Clear();
    +  clear_has_os();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_OS& ClientIncidentReport_EnvironmentData::os() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.os)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return os_ != NULL ? *os_ : *default_instance().os_;
    +#else
    +  return os_ != NULL ? *os_ : *default_instance_->os_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_OS* ClientIncidentReport_EnvironmentData::mutable_os() {
    +  set_has_os();
    +  if (os_ == NULL) os_ = new ::safe_browsing::ClientIncidentReport_EnvironmentData_OS;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.os)
    +  return os_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_OS* ClientIncidentReport_EnvironmentData::release_os() {
    +  clear_has_os();
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData_OS* temp = os_;
    +  os_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_EnvironmentData::set_allocated_os(::safe_browsing::ClientIncidentReport_EnvironmentData_OS* os) {
    +  delete os_;
    +  os_ = os;
    +  if (os) {
    +    set_has_os();
    +  } else {
    +    clear_has_os();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.os)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.EnvironmentData.Machine machine = 2;
    +inline bool ClientIncidentReport_EnvironmentData::has_machine() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData::set_has_machine() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData::clear_has_machine() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport_EnvironmentData::clear_machine() {
    +  if (machine_ != NULL) machine_->::safe_browsing::ClientIncidentReport_EnvironmentData_Machine::Clear();
    +  clear_has_machine();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine& ClientIncidentReport_EnvironmentData::machine() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.machine)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return machine_ != NULL ? *machine_ : *default_instance().machine_;
    +#else
    +  return machine_ != NULL ? *machine_ : *default_instance_->machine_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* ClientIncidentReport_EnvironmentData::mutable_machine() {
    +  set_has_machine();
    +  if (machine_ == NULL) machine_ = new ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.machine)
    +  return machine_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* ClientIncidentReport_EnvironmentData::release_machine() {
    +  clear_has_machine();
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* temp = machine_;
    +  machine_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_EnvironmentData::set_allocated_machine(::safe_browsing::ClientIncidentReport_EnvironmentData_Machine* machine) {
    +  delete machine_;
    +  machine_ = machine;
    +  if (machine) {
    +    set_has_machine();
    +  } else {
    +    clear_has_machine();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.machine)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.EnvironmentData.Process process = 3;
    +inline bool ClientIncidentReport_EnvironmentData::has_process() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientIncidentReport_EnvironmentData::set_has_process() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientIncidentReport_EnvironmentData::clear_has_process() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientIncidentReport_EnvironmentData::clear_process() {
    +  if (process_ != NULL) process_->::safe_browsing::ClientIncidentReport_EnvironmentData_Process::Clear();
    +  clear_has_process();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData_Process& ClientIncidentReport_EnvironmentData::process() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.EnvironmentData.process)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return process_ != NULL ? *process_ : *default_instance().process_;
    +#else
    +  return process_ != NULL ? *process_ : *default_instance_->process_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process* ClientIncidentReport_EnvironmentData::mutable_process() {
    +  set_has_process();
    +  if (process_ == NULL) process_ = new ::safe_browsing::ClientIncidentReport_EnvironmentData_Process;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.EnvironmentData.process)
    +  return process_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData_Process* ClientIncidentReport_EnvironmentData::release_process() {
    +  clear_has_process();
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData_Process* temp = process_;
    +  process_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport_EnvironmentData::set_allocated_process(::safe_browsing::ClientIncidentReport_EnvironmentData_Process* process) {
    +  delete process_;
    +  process_ = process;
    +  if (process) {
    +    set_has_process();
    +  } else {
    +    clear_has_process();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.EnvironmentData.process)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentReport
    +
    +// repeated .safe_browsing.ClientIncidentReport.IncidentData incident = 1;
    +inline int ClientIncidentReport::incident_size() const {
    +  return incident_.size();
    +}
    +inline void ClientIncidentReport::clear_incident() {
    +  incident_.Clear();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_IncidentData& ClientIncidentReport::incident(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.incident)
    +  return incident_.Get(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData* ClientIncidentReport::mutable_incident(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.incident)
    +  return incident_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientIncidentReport_IncidentData* ClientIncidentReport::add_incident() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentReport.incident)
    +  return incident_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_IncidentData >&
    +ClientIncidentReport::incident() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentReport.incident)
    +  return incident_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentReport_IncidentData >*
    +ClientIncidentReport::mutable_incident() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentReport.incident)
    +  return &incident_;
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +inline bool ClientIncidentReport::has_download() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentReport::set_has_download() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentReport::clear_has_download() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentReport::clear_download() {
    +  if (download_ != NULL) download_->::safe_browsing::ClientIncidentReport_DownloadDetails::Clear();
    +  clear_has_download();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_DownloadDetails& ClientIncidentReport::download() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.download)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return download_ != NULL ? *download_ : *default_instance().download_;
    +#else
    +  return download_ != NULL ? *download_ : *default_instance_->download_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_DownloadDetails* ClientIncidentReport::mutable_download() {
    +  set_has_download();
    +  if (download_ == NULL) download_ = new ::safe_browsing::ClientIncidentReport_DownloadDetails;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.download)
    +  return download_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_DownloadDetails* ClientIncidentReport::release_download() {
    +  clear_has_download();
    +  ::safe_browsing::ClientIncidentReport_DownloadDetails* temp = download_;
    +  download_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport::set_allocated_download(::safe_browsing::ClientIncidentReport_DownloadDetails* download) {
    +  delete download_;
    +  download_ = download;
    +  if (download) {
    +    set_has_download();
    +  } else {
    +    clear_has_download();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.download)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.EnvironmentData environment = 3;
    +inline bool ClientIncidentReport::has_environment() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ClientIncidentReport::set_has_environment() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ClientIncidentReport::clear_has_environment() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ClientIncidentReport::clear_environment() {
    +  if (environment_ != NULL) environment_->::safe_browsing::ClientIncidentReport_EnvironmentData::Clear();
    +  clear_has_environment();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_EnvironmentData& ClientIncidentReport::environment() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentReport.environment)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return environment_ != NULL ? *environment_ : *default_instance().environment_;
    +#else
    +  return environment_ != NULL ? *environment_ : *default_instance_->environment_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData* ClientIncidentReport::mutable_environment() {
    +  set_has_environment();
    +  if (environment_ == NULL) environment_ = new ::safe_browsing::ClientIncidentReport_EnvironmentData;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentReport.environment)
    +  return environment_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_EnvironmentData* ClientIncidentReport::release_environment() {
    +  clear_has_environment();
    +  ::safe_browsing::ClientIncidentReport_EnvironmentData* temp = environment_;
    +  environment_ = NULL;
    +  return temp;
    +}
    +inline void ClientIncidentReport::set_allocated_environment(::safe_browsing::ClientIncidentReport_EnvironmentData* environment) {
    +  delete environment_;
    +  environment_ = environment;
    +  if (environment) {
    +    set_has_environment();
    +  } else {
    +    clear_has_environment();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentReport.environment)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentResponse_EnvironmentRequest
    +
    +// optional int32 dll_index = 1;
    +inline bool ClientIncidentResponse_EnvironmentRequest::has_dll_index() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentResponse_EnvironmentRequest::set_has_dll_index() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentResponse_EnvironmentRequest::clear_has_dll_index() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentResponse_EnvironmentRequest::clear_dll_index() {
    +  dll_index_ = 0;
    +  clear_has_dll_index();
    +}
    +inline ::google::protobuf::int32 ClientIncidentResponse_EnvironmentRequest::dll_index() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentResponse.EnvironmentRequest.dll_index)
    +  return dll_index_;
    +}
    +inline void ClientIncidentResponse_EnvironmentRequest::set_dll_index(::google::protobuf::int32 value) {
    +  set_has_dll_index();
    +  dll_index_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentResponse.EnvironmentRequest.dll_index)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ClientIncidentResponse
    +
    +// optional bytes token = 1;
    +inline bool ClientIncidentResponse::has_token() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ClientIncidentResponse::set_has_token() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ClientIncidentResponse::clear_has_token() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ClientIncidentResponse::clear_token() {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_->clear();
    +  }
    +  clear_has_token();
    +}
    +inline const ::std::string& ClientIncidentResponse::token() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentResponse.token)
    +  return *token_;
    +}
    +inline void ClientIncidentResponse::set_token(const ::std::string& value) {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  token_->assign(value);
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentResponse.token)
    +}
    +inline void ClientIncidentResponse::set_token(const char* value) {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  token_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:safe_browsing.ClientIncidentResponse.token)
    +}
    +inline void ClientIncidentResponse::set_token(const void* value, size_t size) {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  token_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:safe_browsing.ClientIncidentResponse.token)
    +}
    +inline ::std::string* ClientIncidentResponse::mutable_token() {
    +  set_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    token_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentResponse.token)
    +  return token_;
    +}
    +inline ::std::string* ClientIncidentResponse::release_token() {
    +  clear_has_token();
    +  if (token_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = token_;
    +    token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ClientIncidentResponse::set_allocated_token(::std::string* token) {
    +  if (token_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete token_;
    +  }
    +  if (token) {
    +    set_has_token();
    +    token_ = token;
    +  } else {
    +    clear_has_token();
    +    token_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.ClientIncidentResponse.token)
    +}
    +
    +// optional bool download_requested = 2;
    +inline bool ClientIncidentResponse::has_download_requested() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void ClientIncidentResponse::set_has_download_requested() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void ClientIncidentResponse::clear_has_download_requested() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void ClientIncidentResponse::clear_download_requested() {
    +  download_requested_ = false;
    +  clear_has_download_requested();
    +}
    +inline bool ClientIncidentResponse::download_requested() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentResponse.download_requested)
    +  return download_requested_;
    +}
    +inline void ClientIncidentResponse::set_download_requested(bool value) {
    +  set_has_download_requested();
    +  download_requested_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.ClientIncidentResponse.download_requested)
    +}
    +
    +// repeated .safe_browsing.ClientIncidentResponse.EnvironmentRequest environment_requests = 3;
    +inline int ClientIncidentResponse::environment_requests_size() const {
    +  return environment_requests_.size();
    +}
    +inline void ClientIncidentResponse::clear_environment_requests() {
    +  environment_requests_.Clear();
    +}
    +inline const ::safe_browsing::ClientIncidentResponse_EnvironmentRequest& ClientIncidentResponse::environment_requests(int index) const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.ClientIncidentResponse.environment_requests)
    +  return environment_requests_.Get(index);
    +}
    +inline ::safe_browsing::ClientIncidentResponse_EnvironmentRequest* ClientIncidentResponse::mutable_environment_requests(int index) {
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.ClientIncidentResponse.environment_requests)
    +  return environment_requests_.Mutable(index);
    +}
    +inline ::safe_browsing::ClientIncidentResponse_EnvironmentRequest* ClientIncidentResponse::add_environment_requests() {
    +  // @@protoc_insertion_point(field_add:safe_browsing.ClientIncidentResponse.environment_requests)
    +  return environment_requests_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentResponse_EnvironmentRequest >&
    +ClientIncidentResponse::environment_requests() const {
    +  // @@protoc_insertion_point(field_list:safe_browsing.ClientIncidentResponse.environment_requests)
    +  return environment_requests_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::safe_browsing::ClientIncidentResponse_EnvironmentRequest >*
    +ClientIncidentResponse::mutable_environment_requests() {
    +  // @@protoc_insertion_point(field_mutable_list:safe_browsing.ClientIncidentResponse.environment_requests)
    +  return &environment_requests_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// DownloadMetadata
    +
    +// optional uint32 download_id = 1;
    +inline bool DownloadMetadata::has_download_id() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void DownloadMetadata::set_has_download_id() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void DownloadMetadata::clear_has_download_id() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void DownloadMetadata::clear_download_id() {
    +  download_id_ = 0u;
    +  clear_has_download_id();
    +}
    +inline ::google::protobuf::uint32 DownloadMetadata::download_id() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.DownloadMetadata.download_id)
    +  return download_id_;
    +}
    +inline void DownloadMetadata::set_download_id(::google::protobuf::uint32 value) {
    +  set_has_download_id();
    +  download_id_ = value;
    +  // @@protoc_insertion_point(field_set:safe_browsing.DownloadMetadata.download_id)
    +}
    +
    +// optional .safe_browsing.ClientIncidentReport.DownloadDetails download = 2;
    +inline bool DownloadMetadata::has_download() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void DownloadMetadata::set_has_download() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void DownloadMetadata::clear_has_download() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void DownloadMetadata::clear_download() {
    +  if (download_ != NULL) download_->::safe_browsing::ClientIncidentReport_DownloadDetails::Clear();
    +  clear_has_download();
    +}
    +inline const ::safe_browsing::ClientIncidentReport_DownloadDetails& DownloadMetadata::download() const {
    +  // @@protoc_insertion_point(field_get:safe_browsing.DownloadMetadata.download)
    +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
    +  return download_ != NULL ? *download_ : *default_instance().download_;
    +#else
    +  return download_ != NULL ? *download_ : *default_instance_->download_;
    +#endif
    +}
    +inline ::safe_browsing::ClientIncidentReport_DownloadDetails* DownloadMetadata::mutable_download() {
    +  set_has_download();
    +  if (download_ == NULL) download_ = new ::safe_browsing::ClientIncidentReport_DownloadDetails;
    +  // @@protoc_insertion_point(field_mutable:safe_browsing.DownloadMetadata.download)
    +  return download_;
    +}
    +inline ::safe_browsing::ClientIncidentReport_DownloadDetails* DownloadMetadata::release_download() {
    +  clear_has_download();
    +  ::safe_browsing::ClientIncidentReport_DownloadDetails* temp = download_;
    +  download_ = NULL;
    +  return temp;
    +}
    +inline void DownloadMetadata::set_allocated_download(::safe_browsing::ClientIncidentReport_DownloadDetails* download) {
    +  delete download_;
    +  download_ = download;
    +  if (download) {
    +    set_has_download();
    +  } else {
    +    clear_has_download();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:safe_browsing.DownloadMetadata.download)
    +}
     
     
     // @@protoc_insertion_point(namespace_scope)
    diff --git a/toolkit/components/downloads/csd.proto b/toolkit/components/downloads/csd.proto
    new file mode 100644
    index 000000000000..ae0e7b906ae3
    --- /dev/null
    +++ b/toolkit/components/downloads/csd.proto
    @@ -0,0 +1,487 @@
    +// Copyright (c) 2012 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.
    +//
    +// Client side phishing and malware detection request and response
    +// protocol buffers.  Those protocol messages should be kept in sync
    +// with the server implementation.
    +//
    +// If you want to change this protocol definition or you have questions
    +// regarding its format please contact chrome-anti-phishing@googlegroups.com.
    +
    +syntax = "proto2";
    +
    +option optimize_for = LITE_RUNTIME;
    +
    +package safe_browsing;
    +
    +message ClientPhishingRequest {
    +  // URL that the client visited.  The CGI parameters are stripped by the
    +  // client.
    +  optional string url = 1;
    +
    +  // A 5-byte SHA-256 hash prefix of the URL.  Before hashing the URL is
    +  // canonicalized, converted to a suffix-prefix expression and broadened
    +  // (www prefix is removed and everything past the last '/' is stripped).
    +  //
    +  // Marked OBSOLETE because the URL is sent for all users, making the hash
    +  // prefix unnecessary.
    +  optional bytes OBSOLETE_hash_prefix = 10;
    +
    +  // Score that was computed on the client.  Value is between 0.0 and 1.0.
    +  // The larger the value the more likely the url is phishing.
    +  required float client_score = 2;
    +
    +  // Note: we're skipping tag 3 because it was previously used.
    +
    +  // Is true if the features for this URL were classified as phishing.
    +  // Currently, this will always be true for all client-phishing requests
    +  // that are sent to the server.
    +  optional bool is_phishing = 4;
    +
    +  message Feature {
    +    // Feature name.  E.g., 'PageHasForms'.
    +    required string name = 1;
    +
    +    // Feature value is always in the range [0.0, 1.0].  Boolean features
    +    // have value 1.0.
    +    required double value = 2;
    +  }
    +
    +  // List of features that were extracted.  Those are the features that were
    +  // sent to the scorer and which resulted in client_score being computed.
    +  repeated Feature feature_map = 5;
    +
    +  // The version number of the model that was used to compute the client-score.
    +  // Copied from ClientSideModel.version().
    +  optional int32 model_version = 6;
    +
    +  // Field 7 is only used on the server.
    +
    +  // List of features that are extracted in the client but are not used in the
    +  // machine learning model.
    +  repeated Feature non_model_feature_map = 8;
    +
    +  // The referrer URL.  This field might not be set, for example, in the case
    +  // where the referrer uses HTTPs.
    +  // OBSOLETE: Use feature 'Referrer=' instead.
    +  optional string OBSOLETE_referrer_url = 9;
    +
    +  // Field 11 is only used on the server.
    +
    +  // List of shingle hashes we extracted.
    +  repeated uint32 shingle_hashes = 12 [packed = true];
    +}
    +
    +message ClientPhishingResponse {
    +  required bool phishy = 1;
    +
    +  // A list of SafeBrowsing host-suffix / path-prefix expressions that
    +  // are whitelisted.  The client must match the current top-level URL
    +  // against these whitelisted expressions and only apply a positive
    +  // phishing verdict above if the URL does not match any expression
    +  // on this whitelist.  The client must not cache these whitelisted
    +  // expressions.  This whitelist will be empty for the vast majority
    +  // of the responses but might contain up to 100 entries in emergency
    +  // situations.
    +  //
    +  // Marked OBSOLETE because the URL is sent for all users, so the server
    +  // can do whitelist matching.
    +  repeated string OBSOLETE_whitelist_expression = 2;
    +}
    +
    +message ClientMalwareRequest {
    +  // URL that the client visited.  The CGI parameters are stripped by the
    +  // client.
    +  required string url = 1;
    +
    +  // Field 2 is deleted and no longer in use.
    +
    +  // Field 3 is only used on the server.
    +
    +  // The referrer URL.  This field might not be set, for example, in the case
    +  // where the referrer uses HTTPS.
    +  optional string referrer_url = 4;
    +
    +  // Field 5 and 6 are only used on the server.
    +
    +  message UrlInfo {
    +    required string ip = 1;
    +    required string url = 2;
    +    optional string method = 3;
    +    optional string referrer = 4;
    +    // Resource type, the int value is a direct cast from the Type enum
    +    // of ResourceType class defined in //src/webkit/commom/resource_type.h
    +    optional int32 resource_type = 5;
    +  }
    +
    +  // List of resource urls that match the malware IP list.
    +  repeated UrlInfo bad_ip_url_info = 7;
    +}
    +
    +message ClientMalwareResponse {
    +  required bool blacklist = 1;
    +  // The confirmed blacklisted bad IP and its url, which will be shown in
    +  // malware warning, if the blacklist verdict is true.
    +  // This IP string could be either in IPv4 or IPv6 format, which is the same
    +  // as the ones client sent to server.
    +  optional string bad_ip = 2;
    +  optional string bad_url = 3;
    +}
    +
    +message ClientDownloadRequest {
    +  // The final URL of the download (after all redirects).
    +  required string url = 1;
    +
    +  // This message contains various binary digests of the download payload.
    +  message Digests {
    +    optional bytes sha256 = 1;
    +    optional bytes sha1 = 2;
    +    optional bytes md5 = 3;
    +  }
    +  required Digests digests = 2;
    +
    +  // This is the length in bytes of the download payload.
    +  required int64 length = 3;
    +
    +  // Type of the resources stored below.
    +  enum ResourceType {
    +    // The final URL of the download payload.  The resource URL should
    +    // correspond to the URL field above.
    +    DOWNLOAD_URL = 0;
    +    // A redirect URL that was fetched before hitting the final DOWNLOAD_URL.
    +    DOWNLOAD_REDIRECT = 1;
    +    // The final top-level URL of the tab that triggered the download.
    +    TAB_URL = 2;
    +    // A redirect URL thas was fetched before hitting the final TAB_URL.
    +    TAB_REDIRECT = 3;
    +  }
    +
    +  message Resource {
    +    required string url = 1;
    +    required ResourceType type = 2;
    +    optional bytes remote_ip = 3;
    +    // This will only be set if the referrer is available and if the
    +    // resource type is either TAB_URL or DOWNLOAD_URL.
    +    optional string referrer = 4;
    +
    +    // TODO(noelutz): add the transition type?
    +  }
    +
    +  // This repeated field will store all the redirects as well as the
    +  // final URLs for the top-level tab URL (i.e., the URL that
    +  // triggered the download) as well as for the download URL itself.
    +  repeated Resource resources = 4;
    +
    +  // A trust chain of certificates.  Each chain begins with the signing
    +  // certificate of the binary, and ends with a self-signed certificate,
    +  // typically from a trusted root CA.  This structure is analogous to
    +  // CERT_CHAIN_CONTEXT on Windows.
    +  message CertificateChain {
    +    // A single link in the chain.
    +    message Element {
    +      // DER-encoded X.509 representation of the certificate.
    +      optional bytes certificate = 1;
    +      // Fields 2 - 7 are only used on the server.
    +    }
    +    repeated Element element = 1;
    +  }
    +
    +  message SignatureInfo {
    +    // All of the certificate chains for the binary's signing certificate.
    +    // If no chains are present, the binary is not signed.  Multiple chains
    +    // may be present if any certificate has multiple signers.
    +    repeated CertificateChain certificate_chain = 1;
    +
    +    // True if the signature was trusted on the client.
    +    optional bool trusted = 2;
    +  }
    +
    +  // This field will only be set if the binary is signed.
    +  optional SignatureInfo signature = 5;
    +
    +  // True if the download was user initiated.
    +  optional bool user_initiated = 6;
    +
    +  // Fields 7 and 8 are only used on the server.
    +
    +  // Name of the file where the download would be stored if the
    +  // download completes.  E.g., "bla.exe".
    +  optional string file_basename = 9;
    +
    +  // Starting with Chrome M19 we're also sending back pings for Chrome
    +  // extensions that get downloaded by users.
    +  enum DownloadType {
    +    WIN_EXECUTABLE = 0;    // Currently all .exe, .cab and .msi files.
    +    CHROME_EXTENSION = 1;  // .crx files.
    +    ANDROID_APK = 2;       // .apk files.
    +    // .zip files containing one of the other executable types.
    +    ZIPPED_EXECUTABLE = 3;
    +    MAC_EXECUTABLE = 4;    // .dmg, .pkg, etc.
    +  }
    +  optional DownloadType download_type = 10 [default = WIN_EXECUTABLE];
    +
    +  // Locale of the device, eg en, en_US.
    +  optional string locale = 11;
    +
    +  message PEImageHeaders {
    +    // IMAGE_DOS_HEADER.
    +    optional bytes dos_header = 1;
    +    // IMAGE_FILE_HEADER.
    +    optional bytes file_header = 2;
    +    // IMAGE_OPTIONAL_HEADER32. Present only for 32-bit PE images.
    +    optional bytes optional_headers32 = 3;
    +    // IMAGE_OPTIONAL_HEADER64. Present only for 64-bit PE images.
    +    optional bytes optional_headers64 = 4;
    +    // IMAGE_SECTION_HEADER.
    +    repeated bytes section_header = 5;
    +    // Contents of the .edata section.
    +    optional bytes export_section_data = 6;
    +
    +    message DebugData {
    +      // IMAGE_DEBUG_DIRECTORY.
    +      optional bytes directory_entry = 1;
    +      optional bytes raw_data = 2;
    +    }
    +
    +    repeated DebugData debug_data = 7;
    +  }
    +
    +  message ImageHeaders {
    +    // Windows Portable Executable image headers.
    +    optional PEImageHeaders pe_headers = 1;
    +  };
    +
    +  // Fields 12-17 are reserved for server-side use and are never sent by the
    +  // client.
    +
    +  optional ImageHeaders image_headers = 18;
    +
    +  // Fields 19-21 are reserved for server-side use and are never sent by the
    +  // client.
    +
    +  // A binary contained in an archive (e.g., a .zip archive).
    +  message ArchivedBinary {
    +    optional string file_basename = 1;
    +    optional DownloadType download_type = 2;
    +    optional Digests digests = 3;
    +    optional int64 length = 4;
    +    optional SignatureInfo signature = 5;
    +    optional ImageHeaders image_headers = 6;
    +  }
    +
    +  repeated ArchivedBinary archived_binary = 22;
    +}
    +
    +message ClientDownloadResponse {
    +  enum Verdict {
    +    // Download is considered safe.
    +    SAFE = 0;
    +    // Download is considered dangerous.  Chrome should show a warning to the
    +    // user.
    +    DANGEROUS = 1;
    +    // Download is unknown.  Chrome should display a less severe warning.
    +    UNCOMMON = 2;
    +    // The download is potentially unwanted.
    +    POTENTIALLY_UNWANTED = 3;
    +    // The download is from a dangerous host.
    +    DANGEROUS_HOST = 4;
    +  }
    +  required Verdict verdict = 1;
    +
    +  message MoreInfo {
    +    // A human-readable string describing the nature of the warning.
    +    // Only if verdict != SAFE. Localized based on request.locale.
    +    optional string description = 1;
    +
    +    // A URL to get more information about this warning, if available.
    +    optional string url = 2;
    +  }
    +  optional MoreInfo more_info = 2;
    +
    +  // An arbitrary token that should be sent along for further server requests.
    +  optional bytes token = 3;
    +}
    +
    +// The following protocol buffer holds the feedback report gathered
    +// from the user regarding the download.
    +message ClientDownloadReport {
    +  // The information of user who provided the feedback.
    +  // This is going to be useful for handling appeals.
    +  message UserInformation {
    +    optional string email = 1;
    +  }
    +
    +  enum Reason {
    +    SHARE = 0;
    +    FALSE_POSITIVE = 1;
    +    APPEAL = 2;
    +  }
    +
    +  // The type of feedback for this report.
    +  optional Reason reason = 1;
    +
    +  // The original download ping
    +  optional ClientDownloadRequest download_request = 2;
    +
    +  // Stores the information of the user who provided the feedback.
    +  optional UserInformation user_information = 3;
    +
    +  // Unstructed comments provided by the user.
    +  optional bytes comment = 4;
    +
    +  // The original download response sent from the verdict server.
    +  optional ClientDownloadResponse download_response = 5;
    +}
    +
    +// This is used to send back upload status to the client after upload completion
    +message ClientUploadResponse {
    +  enum UploadStatus {
    +    // The upload was successful and a complete response can be expected
    +    SUCCESS = 0;
    +
    +    // The upload was unsuccessful and the response is incomplete.
    +    UPLOAD_FAILURE = 1;
    +  }
    +
    +  // Holds the upload status
    +  optional UploadStatus status = 1;
    +
    +  // Holds the permalink where the results of scanning the binary are available
    +  optional string permalink = 2;
    +}
    +
    +message ClientIncidentReport {
    +  message IncidentData {
    +    message TrackedPreferenceIncident {
    +      enum ValueState {
    +        UNKNOWN = 0;
    +        CLEARED = 1;
    +        WEAK_LEGACY_OBSOLETE = 2;
    +        CHANGED = 3;
    +        UNTRUSTED_UNKNOWN_VALUE = 4;
    +      }
    +
    +      optional string path = 1;
    +      optional string atomic_value = 2;
    +      repeated string split_key = 3;
    +      optional ValueState value_state = 4;
    +    }
    +    message BinaryIntegrityIncident {
    +      optional string file_basename = 1;
    +      optional ClientDownloadRequest.SignatureInfo signature = 2;
    +    }
    +    message BlacklistLoadIncident {
    +      optional string path = 1;
    +      optional ClientDownloadRequest.Digests digest = 2;
    +      optional string version = 3;
    +      optional bool blacklist_initialized = 4;
    +      optional ClientDownloadRequest.SignatureInfo signature = 5;
    +      optional ClientDownloadRequest.ImageHeaders image_headers = 6;
    +    }
    +    message VariationsSeedSignatureIncident {
    +      optional string variations_seed_signature = 1;
    +    }
    +    message ScriptRequestIncident {
    +      optional string script_digest = 1;
    +      optional string inclusion_origin = 2;
    +    }
    +    optional int64 incident_time_msec = 1;
    +    optional TrackedPreferenceIncident tracked_preference = 2;
    +    optional BinaryIntegrityIncident binary_integrity = 3;
    +    optional BlacklistLoadIncident blacklist_load = 4;
    +    // Note: skip tag 5 because it was previously used.
    +    optional VariationsSeedSignatureIncident variations_seed_signature = 6;
    +    optional ScriptRequestIncident script_request = 7;
    +  }
    +
    +  repeated IncidentData incident = 1;
    +
    +  message DownloadDetails {
    +    optional bytes token = 1;
    +    optional ClientDownloadRequest download = 2;
    +    optional int64 download_time_msec = 3;
    +    optional int64 open_time_msec = 4;
    +  }
    +
    +  optional DownloadDetails download = 2;
    +
    +  message EnvironmentData {
    +    message OS {
    +      optional string os_name = 1;
    +      optional string os_version = 2;
    +    }
    +    optional OS os = 1;
    +    message Machine {
    +      optional string cpu_architecture = 1;
    +      optional string cpu_vendor = 2;
    +      optional uint32 cpuid = 3;
    +    }
    +    optional Machine machine = 2;
    +    message Process {
    +      optional string version = 1;
    +      repeated string OBSOLETE_dlls = 2;
    +      message Patch {
    +        optional string function = 1;
    +        optional string target_dll = 2;
    +      }
    +      repeated Patch patches = 3;
    +      message NetworkProvider {}
    +      repeated NetworkProvider network_providers = 4;
    +      enum Channel {
    +        CHANNEL_UNKNOWN = 0;
    +        CHANNEL_CANARY = 1;
    +        CHANNEL_DEV = 2;
    +        CHANNEL_BETA = 3;
    +        CHANNEL_STABLE = 4;
    +      }
    +      optional Channel chrome_update_channel = 5;
    +      optional int64 uptime_msec = 6;
    +      optional bool metrics_consent = 7;
    +      optional bool extended_consent = 8;
    +      message Dll {
    +        enum Feature {
    +          UNKNOWN = 0;
    +          LSP = 1;
    +        }
    +        optional string path = 1;
    +        optional uint64 base_address = 2;
    +        optional uint32 length = 3;
    +        repeated Feature feature = 4;
    +        optional ClientDownloadRequest.ImageHeaders image_headers = 5;
    +      }
    +      repeated Dll dll = 9;
    +      repeated string blacklisted_dll = 10;
    +      message ModuleState {
    +        enum ModifiedState {
    +          UNKNOWN = 0;
    +          MODULE_STATE_UNKNOWN = 1;
    +          MODULE_STATE_UNMODIFIED = 2;
    +          MODULE_STATE_MODIFIED = 3;
    +        }
    +        optional string name = 1;
    +        optional ModifiedState modified_state = 2;
    +        repeated string modified_export = 3;
    +      }
    +      repeated ModuleState module_state = 11;
    +    }
    +    optional Process process = 3;
    +  }
    +
    +  optional EnvironmentData environment = 3;
    +}
    +
    +message ClientIncidentResponse {
    +  optional bytes token = 1;
    +  optional bool download_requested = 2;
    +
    +  message EnvironmentRequest { optional int32 dll_index = 1; }
    +
    +  repeated EnvironmentRequest environment_requests = 3;
    +}
    +
    +message DownloadMetadata {
    +  optional uint32 download_id = 1;
    +
    +  optional ClientIncidentReport.DownloadDetails download = 2;
    +}
    diff --git a/toolkit/components/downloads/generate_csd.sh b/toolkit/components/downloads/generate_csd.sh
    index a0eba711ae77..213ea179e49f 100755
    --- a/toolkit/components/downloads/generate_csd.sh
    +++ b/toolkit/components/downloads/generate_csd.sh
    @@ -1,11 +1,15 @@
    -#!/bin/bash
    +#!/usr/bin/env bash
    +
     # A script to generate toolkit/components/downloads/csd.pb.{cc,h} for use in
     # nsIApplicationReputationQuery. This script assumes you have downloaded and
     # installed the protocol buffer compiler.
     # As of June 26 2014, csd.proto contains many protobufs that are currently
     # unused by ApplicationReputation. You may want to strip csd.proto of these
     # before running the protocol compiler on it.
    -if [ -n $PROTOC_PATH ]; then
    +
    +set -e
    +
    +if [ "${PROTOC_PATH:+set}" != "set" ]; then
       PROTOC_PATH=/usr/local/bin/protoc
     fi
     
    @@ -17,9 +21,14 @@ if [ ! -e $PROTOC_PATH ]; then
       exit 1
     fi
     
    -# Get the protocol buffer and compile it
    -CMD='wget http://src.chromium.org/chrome/trunk/src/chrome/common/safe_browsing/csd.proto -O csd.proto'
    -OUTPUT_PATH=toolkit/components/downloads
    +if [ ! -f nsDownloadManager.cpp ]; then
    +    echo "You must run this script in the toolkit/components/downloads" >&2
    +    echo "directory of the source tree." >&2
    +    exit 1
    +fi
     
    -$CMD
    -$PROTOC_PATH csd.proto --cpp_out=$OUTPUT_PATH
    +# Get the protocol buffer and compile it
    +CSD_PROTO_URL="https://chromium.googlesource.com/playground/chromium-blink-merge/+/master/chrome/common/safe_browsing/csd.proto?format=TEXT"
    +
    +curl $CSD_PROTO_URL | base64 --decode > csd.proto
    +$PROTOC_PATH csd.proto --cpp_out=.
    diff --git a/toolkit/components/downloads/moz.build b/toolkit/components/downloads/moz.build
    index cca94b367bbe..6aa5a8f26891 100644
    --- a/toolkit/components/downloads/moz.build
    +++ b/toolkit/components/downloads/moz.build
    @@ -76,5 +76,6 @@ LOCAL_INCLUDES += [
     ]
     
     DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
    +DEFINES['GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER'] = True
     
     CXXFLAGS += CONFIG['TK_CFLAGS']
    diff --git a/toolkit/components/protobuf/README.txt b/toolkit/components/protobuf/README.txt
    index 822ae96cdf29..c63704ac50ac 100644
    --- a/toolkit/components/protobuf/README.txt
    +++ b/toolkit/components/protobuf/README.txt
    @@ -1,19 +1,25 @@
    -This library has been updated to protobuf-2.4.1 as of 11/30/12.
    -
     Protocol Buffers (protobuf) source is available (via svn) at:
    -svn checkout http://protobuf.googlecode.com/svn/trunk/ protobuf-read-only
    +
    +    svn checkout http://protobuf.googlecode.com/svn/trunk/ protobuf-read-only
    +
    +Or via git at:
    +
    +    https://github.com/google/protobuf
     
     This code is covered under the BSD license (see COPYING.txt). Documentation is
     available at http://code.google.com/p/protobuf.
     
    -This import includes only files in protobuf-lite, a lighter-weight library that
    -does not support reflection or descriptors. Manual changes include removing all
    -tests, testdata, config.h, and all files not used in protobuf-lite.
    +The tree's current version of the protobuf library is 2.6.1.
     
    -Applied Patches
    -===============
    -r512.patch:
    -  Support VS2013 (from revision r512)
    +We do not include the protobuf tests or the protoc compiler.
     
    -vs2013.patch
    -  Additional changes to support VS2013 missed from revision r512.
    +--------------------------------------------------------------------------------
    +
    +# Upgrading the Protobuf Library
    +
    +1. Get a new protobuf release from https://github.com/google/protobuf/releases
    +
    +2. Run `$ ./toolkit/components/protobuf/upgrade_protobuf.sh ~/path/to/release/checkout/of/protobuf`.
    +
    +3. Update the moz.build to export the new set of headers and add any new .cc
    +   files to the unified sources and remove old ones.
    diff --git a/toolkit/components/protobuf/google/protobuf/stubs/map-util.h b/toolkit/components/protobuf/google/protobuf/stubs/map-util.h
    deleted file mode 100644
    index f5c9d6b6d9bc..000000000000
    --- a/toolkit/components/protobuf/google/protobuf/stubs/map-util.h
    +++ /dev/null
    @@ -1,119 +0,0 @@
    -// Protocol Buffers - Google's data interchange format
    -// Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    -//
    -// Redistribution and use in source and binary forms, with or without
    -// modification, are permitted provided that the following conditions are
    -// met:
    -//
    -//     * Redistributions of source code must retain the above copyright
    -// notice, this list of conditions and the following disclaimer.
    -//     * Redistributions in binary form must reproduce the above
    -// copyright notice, this list of conditions and the following disclaimer
    -// in the documentation and/or other materials provided with the
    -// distribution.
    -//     * Neither the name of Google Inc. nor the names of its
    -// contributors may be used to endorse or promote products derived from
    -// this software without specific prior written permission.
    -//
    -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -// from google3/util/gtl/map-util.h
    -// Author: Anton Carver
    -
    -#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
    -#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
    -
    -#include 
    -
    -namespace google {
    -namespace protobuf {
    -
    -// Perform a lookup in a map or hash_map.
    -// If the key is present in the map then the value associated with that
    -// key is returned, otherwise the value passed as a default is returned.
    -template 
    -const typename Collection::value_type::second_type&
    -FindWithDefault(const Collection& collection,
    -                const typename Collection::value_type::first_type& key,
    -                const typename Collection::value_type::second_type& value) {
    -  typename Collection::const_iterator it = collection.find(key);
    -  if (it == collection.end()) {
    -    return value;
    -  }
    -  return it->second;
    -}
    -
    -// Perform a lookup in a map or hash_map.
    -// If the key is present a const pointer to the associated value is returned,
    -// otherwise a NULL pointer is returned.
    -template 
    -const typename Collection::value_type::second_type*
    -FindOrNull(const Collection& collection,
    -           const typename Collection::value_type::first_type& key) {
    -  typename Collection::const_iterator it = collection.find(key);
    -  if (it == collection.end()) {
    -    return 0;
    -  }
    -  return &it->second;
    -}
    -
    -// Perform a lookup in a map or hash_map whose values are pointers.
    -// If the key is present a const pointer to the associated value is returned,
    -// otherwise a NULL pointer is returned.
    -// This function does not distinguish between a missing key and a key mapped
    -// to a NULL value.
    -template 
    -const typename Collection::value_type::second_type
    -FindPtrOrNull(const Collection& collection,
    -              const typename Collection::value_type::first_type& key) {
    -  typename Collection::const_iterator it = collection.find(key);
    -  if (it == collection.end()) {
    -    return 0;
    -  }
    -  return it->second;
    -}
    -
    -// Change the value associated with a particular key in a map or hash_map.
    -// If the key is not present in the map the key and value are inserted,
    -// otherwise the value is updated to be a copy of the value provided.
    -// True indicates that an insert took place, false indicates an update.
    -template 
    -bool InsertOrUpdate(Collection * const collection,
    -                   const Key& key, const Value& value) {
    -  pair ret =
    -    collection->insert(typename Collection::value_type(key, value));
    -  if (!ret.second) {
    -    // update
    -    ret.first->second = value;
    -    return false;
    -  }
    -  return true;
    -}
    -
    -// Insert a new key and value into a map or hash_map.
    -// If the key is not present in the map the key and value are
    -// inserted, otherwise nothing happens. True indicates that an insert
    -// took place, false indicates the key was already present.
    -template 
    -bool InsertIfNotPresent(Collection * const collection,
    -                        const Key& key, const Value& value) {
    -  pair ret =
    -    collection->insert(typename Collection::value_type(key, value));
    -  return ret.second;
    -}
    -
    -}  // namespace protobuf
    -}  // namespace google
    -
    -#endif  // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
    diff --git a/toolkit/components/protobuf/m-c-changes.patch b/toolkit/components/protobuf/m-c-changes.patch
    new file mode 100644
    index 000000000000..20a1368a4c2d
    --- /dev/null
    +++ b/toolkit/components/protobuf/m-c-changes.patch
    @@ -0,0 +1,365 @@
    +--- a/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
    ++++ b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
    +@@ -35,16 +35,17 @@
    + //  Sanjay Ghemawat, Jeff Dean, and others.
    + //
    + // This header is logically internal, but is made public because it is used
    + // from protocol-compiler-generated code, which may reside in other components.
    + 
    + #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
    + #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
    + 
    ++#include 
    + #include 
    + #include 
    + #include 
    + #include   // for CodedOutputStream::Varint32Size
    + 
    + namespace google {
    + 
    + namespace protobuf {
    +--- a/toolkit/components/protobuf/src/google/protobuf/wire_format.cc
    ++++ b/toolkit/components/protobuf/src/google/protobuf/wire_format.cc
    +@@ -819,30 +819,35 @@ void WireFormat::SerializeFieldWithCachedSizes(
    +       HANDLE_PRIMITIVE_TYPE(SFIXED64,  int64, SFixed64,  Int64)
    + 
    +       HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
    +       HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
    + 
    +       HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
    + #undef HANDLE_PRIMITIVE_TYPE
    + 
    +-#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                       \
    +-      case FieldDescriptor::TYPE_##TYPE:                                     \
    +-        WireFormatLite::Write##TYPE_METHOD(                                  \
    +-              field->number(),                                               \
    +-              field->is_repeated() ?                                         \
    +-                message_reflection->GetRepeated##CPPTYPE_METHOD(             \
    +-                  message, field, j) :                                       \
    +-                message_reflection->Get##CPPTYPE_METHOD(message, field),     \
    +-              output);                                                       \
    ++      case FieldDescriptor::TYPE_GROUP:
    ++        WireFormatLite::WriteGroup(
    ++              field->number(),
    ++              field->is_repeated() ?
    ++                message_reflection->GetRepeatedMessage(
    ++                  message, field, j) :
    ++                message_reflection->GetMessage(message, field),
    ++              output);
    +         break;
    + 
    +-      HANDLE_TYPE(GROUP  , Group  , Message)
    +-      HANDLE_TYPE(MESSAGE, Message, Message)
    +-#undef HANDLE_TYPE
    ++      case FieldDescriptor::TYPE_MESSAGE:
    ++        WireFormatLite::WriteMessage(
    ++              field->number(),
    ++              field->is_repeated() ?
    ++                message_reflection->GetRepeatedMessage(
    ++                  message, field, j) :
    ++                message_reflection->GetMessage(message, field),
    ++              output);
    ++        break;
    + 
    +       case FieldDescriptor::TYPE_ENUM: {
    +         const EnumValueDescriptor* value = field->is_repeated() ?
    +           message_reflection->GetRepeatedEnum(message, field, j) :
    +           message_reflection->GetEnum(message, field);
    +         if (is_packed) {
    +           WireFormatLite::WriteEnumNoTag(value->number(), output);
    +         } else {
    +--- b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc
    ++++ a/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc
    +@@ -28,17 +28,16 @@
    + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + 
    + // Author: brianolson@google.com (Brian Olson)
    + //
    + // This file contains the implementation of classes GzipInputStream and
    + // GzipOutputStream.
    + 
    +-#include "config.h"
    + 
    + #if HAVE_ZLIB
    + #include 
    + 
    + #include 
    + 
    + namespace google {
    + namespace protobuf {
    +--- b/toolkit/components/protobuf/src/google/protobuf/stubs/common.cc
    ++++ a/toolkit/components/protobuf/src/google/protobuf/stubs/common.cc
    +@@ -31,23 +31,22 @@
    + // Author: kenton@google.com (Kenton Varda)
    + 
    + #include 
    + #include 
    + #include 
    + #include 
    + #include 
    + 
    +-#include "config.h"
    + 
    + #ifdef _WIN32
    + #define WIN32_LEAN_AND_MEAN  // We only need minimal includes
    + #include 
    + #define snprintf _snprintf    // see comment in strutil.cc
    ++#elif defined(HAVE_PTHREAD_H)
    +-#elif defined(HAVE_PTHREAD)
    + #include 
    + #else
    + #error "No suitable threading library available."
    + #endif
    + 
    + namespace google {
    + namespace protobuf {
    + 
    +--- b/toolkit/components/protobuf/src/google/protobuf/stubs/common.h
    ++++ a/toolkit/components/protobuf/src/google/protobuf/stubs/common.h
    +@@ -363,71 +363,20 @@
    + // or to make sure a struct is smaller than a certain size:
    + //
    + //   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
    + //
    + // The second argument to the macro is the name of the variable. If
    + // the expression is false, most compilers will issue a warning/error
    + // containing the name of the variable.
    + 
    ++#define GOOGLE_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
    +-namespace internal {
    +-
    +-template 
    +-struct CompileAssert {
    +-};
    +-
    +-}  // namespace internal
    + 
    +-#undef GOOGLE_COMPILE_ASSERT
    +-#define GOOGLE_COMPILE_ASSERT(expr, msg) \
    +-  typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \
    +-          msg[bool(expr) ? 1 : -1]
    + 
    + 
    +-// Implementation details of COMPILE_ASSERT:
    +-//
    +-// - COMPILE_ASSERT works by defining an array type that has -1
    +-//   elements (and thus is invalid) when the expression is false.
    +-//
    +-// - The simpler definition
    +-//
    +-//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
    +-//
    +-//   does not work, as gcc supports variable-length arrays whose sizes
    +-//   are determined at run-time (this is gcc's extension and not part
    +-//   of the C++ standard).  As a result, gcc fails to reject the
    +-//   following code with the simple definition:
    +-//
    +-//     int foo;
    +-//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
    +-//                               // not a compile-time constant.
    +-//
    +-// - By using the type CompileAssert<(bool(expr))>, we ensures that
    +-//   expr is a compile-time constant.  (Template arguments must be
    +-//   determined at compile-time.)
    +-//
    +-// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
    +-//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
    +-//
    +-//     CompileAssert
    +-//
    +-//   instead, these compilers will refuse to compile
    +-//
    +-//     COMPILE_ASSERT(5 > 0, some_message);
    +-//
    +-//   (They seem to think the ">" in "5 > 0" marks the end of the
    +-//   template argument list.)
    +-//
    +-// - The array size is (bool(expr) ? 1 : -1), instead of simply
    +-//
    +-//     ((expr) ? 1 : -1).
    +-//
    +-//   This is to avoid running into a bug in MS VC 7.1, which
    +-//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
    +-
    + // ===================================================================
    + // from google3/base/scoped_ptr.h
    + 
    + namespace internal {
    + 
    + //  This is an implementation designed to match the anticipated future TR2
    + //  implementation of the scoped_ptr class, and its closely-related brethren,
    + //  scoped_array, scoped_ptr_malloc, and make_scoped_ptr.
    +@@ -582,16 +582,27 @@ enum LogLevel {
    +                      // in the code which calls the library, especially when
    +                      // compiled in debug mode.
    + 
    + #ifdef NDEBUG
    +   LOGLEVEL_DFATAL = LOGLEVEL_ERROR
    + #else
    +   LOGLEVEL_DFATAL = LOGLEVEL_FATAL
    + #endif
    ++
    ++#ifdef ERROR
    ++  // ERROR is defined as 0 on some windows builds, so `GOOGLE_LOG(ERROR, ...)`
    ++  // expands into `GOOGLE_LOG(0, ...)` which then expands into
    ++  // `someGoogleLogging(LOGLEVEL_0, ...)`. This is not ideal, because the
    ++  // GOOGLE_LOG macro expects to expand itself into
    ++  // `someGoogleLogging(LOGLEVEL_ERROR, ...)` instead. The workaround to get
    ++  // everything building is to simply define LOGLEVEL_0 as LOGLEVEL_ERROR and
    ++  // move on with our lives.
    ++  , LOGLEVEL_0 = LOGLEVEL_ERROR
    ++#endif
    + };
    + 
    + namespace internal {
    + 
    + class LogFinisher;
    + 
    + class LIBPROTOBUF_EXPORT LogMessage {
    +  public:
    +--- b/toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
    ++++ a/toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
    +@@ -32,17 +32,16 @@
    + //
    + // Deals with the fact that hash_map is not defined everywhere.
    + 
    + #ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
    + #define GOOGLE_PROTOBUF_STUBS_HASH_H__
    + 
    + #include 
    + #include 
    +-#include "config.h"
    + 
    + #if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET)
    + #include HASH_MAP_H
    + #include HASH_SET_H
    + #else
    + #define MISSING_HASH
    + #include 
    + #include 
    +--- b/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc
    ++++ a/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc
    +@@ -32,17 +32,16 @@
    + 
    + #include 
    + 
    + #include 
    + #include  // For va_list and related operations
    + #include  // MSVC requires this for _vsnprintf
    + #include 
    + #include 
    +-#include 
    + 
    + namespace google {
    + namespace protobuf {
    + 
    + #ifdef _MSC_VER
    + enum { IS_COMPILER_MSVC = 1 };
    + #ifndef va_copy
    + // Define va_copy for MSVC. This is a hack, assuming va_list is simply a
    +--- b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h
    ++++ a/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h
    +@@ -332,16 +332,17 @@
    +     return strtoul(nptr, endptr, base);
    +   else
    +     return strtou32_adaptor(nptr, endptr, base);
    + }
    + 
    + // For now, long long is 64-bit on all the platforms we care about, so these
    + // functions can simply pass the call to strto[u]ll.
    + inline int64 strto64(const char *nptr, char **endptr, int base) {
    ++  static_assert(sizeof(int64) == sizeof(long long), "Protobuf needs sizeof(int64) == sizeof(long long)");
    +   GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
    +                         sizeof_int64_is_not_sizeof_long_long);
    +   return strtoll(nptr, endptr, base);
    + }
    + 
    + inline uint64 strtou64(const char *nptr, char **endptr, int base) {
    +   GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
    +                         sizeof_uint64_is_not_sizeof_long_long);
    +--- a/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc
    ++++ b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc
    +@@ -33,16 +33,18 @@
    + #include 
    + #include 
    + #include     // FLT_DIG and DBL_DIG
    + #include 
    + #include 
    + #include 
    + #include 
    + 
    ++#include "mozilla/FloatingPoint.h"
    ++
    + #ifdef _WIN32
    + // MSVC has only _snprintf, not snprintf.
    + //
    + // MinGW has both snprintf and _snprintf, but they appear to be different
    + // functions.  The former is buggy.  When invoked like so:
    + //   char buffer[32];
    + //   snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f);
    + // it prints "1.23000e+10".  This is plainly wrong:  %g should never print
    +@@ -51,18 +53,17 @@
    + // right thing, so we use it.
    + #define snprintf _snprintf
    + #endif
    + 
    + namespace google {
    + namespace protobuf {
    + 
    + inline bool IsNaN(double value) {
    +-  // NaN is never equal to anything, even itself.
    +-  return value != value;
    ++  return ::mozilla::IsNaN(value);
    + }
    + 
    + // These are defined as macros on some platforms.  #undef them so that we can
    + // redefine them.
    + #undef isxdigit
    + #undef isprint
    + 
    + // The definitions of these in ctype.h change based on locale.  Since our
    +--- b/toolkit/components/protobuf/src/google/protobuf/stubs/type_traits.h
    ++++ a/toolkit/components/protobuf/src/google/protobuf/stubs/type_traits.h
    +@@ -107,20 +107,18 @@
    + template<> struct is_integral : true_type { };
    + #endif
    + template<> struct is_integral : true_type { };
    + template<> struct is_integral : true_type { };
    + template<> struct is_integral : true_type { };
    + template<> struct is_integral : true_type { };
    + template<> struct is_integral : true_type { };
    + template<> struct is_integral : true_type { };
    +-#ifdef HAVE_LONG_LONG
    + template<> struct is_integral : true_type { };
    + template<> struct is_integral : true_type { };
    +-#endif
    + template  struct is_integral : is_integral { };
    + template  struct is_integral : is_integral { };
    + template  struct is_integral : is_integral { };
    + 
    + // is_floating_point is false except for the built-in floating-point types.
    + // A cv-qualified type is integral if and only if the underlying type is.
    + template  struct is_floating_point : false_type { };
    + template<> struct is_floating_point : true_type { };
    +--- a/toolkit/components/protobuf/src/google/protobuf/wire_format_lite_inl.h
    ++++ b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite_inl.h
    +@@ -375,17 +375,17 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
    +     void* dest = reinterpret_cast(values->mutable_data() + old_entries);
    +     if (!input->ReadRaw(dest, new_bytes)) {
    +       values->Truncate(old_entries);
    +       return false;
    +     }
    + #else
    +     values->Reserve(old_entries + new_entries);
    +     CType value;
    +-    for (int i = 0; i < new_entries; ++i) {
    ++    for (uint32 i = 0; i < new_entries; ++i) {
    +       if (!ReadPrimitive(input, &value)) return false;
    +       values->AddAlreadyReserved(value);
    +     }
    + #endif
    +   } else {
    +     // This is the slow-path case where "length" may be too large to
    +     // safely allocate.  We read as much as we can into *values
    +     // without pre-allocating "length" bytes.
    diff --git a/toolkit/components/protobuf/moz.build b/toolkit/components/protobuf/moz.build
    index a7b1bd41cce0..9a65cc284d23 100644
    --- a/toolkit/components/protobuf/moz.build
    +++ b/toolkit/components/protobuf/moz.build
    @@ -5,52 +5,117 @@
     # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     
     EXPORTS.google.protobuf += [
    -    'google/protobuf/extension_set.h',
    -    'google/protobuf/generated_message_util.h',
    -    'google/protobuf/message_lite.h',
    -    'google/protobuf/repeated_field.h',
    -    'google/protobuf/wire_format_lite.h',
    -    'google/protobuf/wire_format_lite_inl.h',
    -]
    -
    -EXPORTS.google.protobuf.stubs += [
    -    'google/protobuf/stubs/common.h',
    -    'google/protobuf/stubs/hash.h',
    -    'google/protobuf/stubs/map-util.h',
    -    'google/protobuf/stubs/once.h',
    -    'google/protobuf/stubs/stl_util-inl.h',
    +    'src/google/protobuf/descriptor.h',
    +    'src/google/protobuf/descriptor.pb.h',
    +    'src/google/protobuf/descriptor_database.h',
    +    'src/google/protobuf/dynamic_message.h',
    +    'src/google/protobuf/extension_set.h',
    +    'src/google/protobuf/generated_enum_reflection.h',
    +    'src/google/protobuf/generated_message_reflection.h',
    +    'src/google/protobuf/generated_message_util.h',
    +    'src/google/protobuf/message.h',
    +    'src/google/protobuf/message_lite.h',
    +    'src/google/protobuf/package_info.h',
    +    'src/google/protobuf/reflection_ops.h',
    +    'src/google/protobuf/repeated_field.h',
    +    'src/google/protobuf/service.h',
    +    'src/google/protobuf/text_format.h',
    +    'src/google/protobuf/unknown_field_set.h',
    +    'src/google/protobuf/wire_format.h',
    +    'src/google/protobuf/wire_format_lite.h',
    +    'src/google/protobuf/wire_format_lite_inl.h',
     ]
     
     EXPORTS.google.protobuf.io += [
    -    'google/protobuf/io/coded_stream.h',
    -    'google/protobuf/io/coded_stream_inl.h',
    -    'google/protobuf/io/zero_copy_stream.h',
    -    'google/protobuf/io/zero_copy_stream_impl.h',
    -    'google/protobuf/io/zero_copy_stream_impl_lite.h',
    -    'google/protobuf/package_info.h',
    +    'src/google/protobuf/io/coded_stream.h',
    +    'src/google/protobuf/io/coded_stream_inl.h',
    +    'src/google/protobuf/io/gzip_stream.h',
    +    'src/google/protobuf/io/package_info.h',
    +    'src/google/protobuf/io/printer.h',
    +    'src/google/protobuf/io/strtod.h',
    +    'src/google/protobuf/io/tokenizer.h',
    +    'src/google/protobuf/io/zero_copy_stream.h',
    +    'src/google/protobuf/io/zero_copy_stream_impl.h',
    +    'src/google/protobuf/io/zero_copy_stream_impl_lite.h',
    +]
    +
    +EXPORTS.google.protobuf.stubs += [
    +    'src/google/protobuf/stubs/atomicops.h',
    +    'src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h',
    +    'src/google/protobuf/stubs/atomicops_internals_arm_gcc.h',
    +    'src/google/protobuf/stubs/atomicops_internals_arm_qnx.h',
    +    'src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h',
    +    'src/google/protobuf/stubs/atomicops_internals_generic_gcc.h',
    +    'src/google/protobuf/stubs/atomicops_internals_macosx.h',
    +    'src/google/protobuf/stubs/atomicops_internals_mips_gcc.h',
    +    'src/google/protobuf/stubs/atomicops_internals_pnacl.h',
    +    'src/google/protobuf/stubs/atomicops_internals_solaris.h',
    +    'src/google/protobuf/stubs/atomicops_internals_tsan.h',
    +    'src/google/protobuf/stubs/atomicops_internals_x86_gcc.h',
    +    'src/google/protobuf/stubs/atomicops_internals_x86_msvc.h',
    +    'src/google/protobuf/stubs/common.h',
    +    'src/google/protobuf/stubs/hash.h',
    +    'src/google/protobuf/stubs/map_util.h',
    +    'src/google/protobuf/stubs/once.h',
    +    'src/google/protobuf/stubs/platform_macros.h',
    +    'src/google/protobuf/stubs/shared_ptr.h',
    +    'src/google/protobuf/stubs/stl_util.h',
    +    'src/google/protobuf/stubs/stringprintf.h',
    +    'src/google/protobuf/stubs/strutil.h',
    +    'src/google/protobuf/stubs/substitute.h',
    +    'src/google/protobuf/stubs/template_util.h',
    +    'src/google/protobuf/stubs/type_traits.h',
     ]
     
     UNIFIED_SOURCES += [
    -    'google/protobuf/extension_set.cc',
    -    'google/protobuf/generated_message_util.cc',
    -    'google/protobuf/io/coded_stream.cc',
    -    'google/protobuf/io/zero_copy_stream.cc',
    -    'google/protobuf/io/zero_copy_stream_impl_lite.cc',
    -    'google/protobuf/message_lite.cc',
    -    'google/protobuf/repeated_field.cc',
    -    'google/protobuf/stubs/common.cc',
    -    'google/protobuf/stubs/once.cc',
    -    'google/protobuf/wire_format_lite.cc',
    +    'src/google/protobuf/descriptor.cc',
    +    'src/google/protobuf/descriptor.pb.cc',
    +    'src/google/protobuf/descriptor_database.cc',
    +    'src/google/protobuf/dynamic_message.cc',
    +    'src/google/protobuf/extension_set.cc',
    +    'src/google/protobuf/generated_message_reflection.cc',
    +    'src/google/protobuf/generated_message_util.cc',
    +    'src/google/protobuf/io/coded_stream.cc',
    +    'src/google/protobuf/io/gzip_stream.cc',
    +    'src/google/protobuf/io/printer.cc',
    +    'src/google/protobuf/io/strtod.cc',
    +    'src/google/protobuf/io/tokenizer.cc',
    +    'src/google/protobuf/io/zero_copy_stream.cc',
    +    'src/google/protobuf/io/zero_copy_stream_impl.cc',
    +    'src/google/protobuf/io/zero_copy_stream_impl_lite.cc',
    +    'src/google/protobuf/message.cc',
    +    'src/google/protobuf/message_lite.cc',
    +    'src/google/protobuf/reflection_ops.cc',
    +    'src/google/protobuf/repeated_field.cc',
    +    'src/google/protobuf/service.cc',
    +    'src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc',
    +    'src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc',
    +    'src/google/protobuf/stubs/common.cc',
    +    'src/google/protobuf/stubs/once.cc',
    +    'src/google/protobuf/stubs/stringprintf.cc',
    +    'src/google/protobuf/stubs/structurally_valid.cc',
    +    'src/google/protobuf/stubs/strutil.cc',
    +    'src/google/protobuf/stubs/substitute.cc',
    +    'src/google/protobuf/unknown_field_set.cc',
    +    'src/google/protobuf/wire_format_lite.cc',
    +]
    +
    +SOURCES += [
    +    'src/google/protobuf/extension_set_heavy.cc',
    +    'src/google/protobuf/text_format.cc',
    +    'src/google/protobuf/wire_format.cc',
     ]
     
     FINAL_LIBRARY = 'xul'
     
     DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
    +DEFINES['GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER'] = True
     
     # Suppress warnings in third-party code.
     if CONFIG['GNU_CXX']:
         CXXFLAGS += [
             '-Wno-null-conversion',
    +        '-Wno-return-type',
             '-Wno-sign-compare',
         ]
     elif CONFIG['_MSC_VER']:
    @@ -60,4 +125,10 @@ elif CONFIG['_MSC_VER']:
             '-wd4099', # mismatched class/struct tags
         ]
     
    +if CONFIG['MOZ_USE_PTHREADS']:
    +    DEFINES['HAVE_PTHREAD'] = True
    +
    +# Needed for the gzip streams.
    +DEFINES['HAVE_ZLIB'] = True
    +
     CXXFLAGS += CONFIG['TK_CFLAGS']
    diff --git a/toolkit/components/protobuf/r512.patch b/toolkit/components/protobuf/r512.patch
    deleted file mode 100644
    index 235db7017d55..000000000000
    --- a/toolkit/components/protobuf/r512.patch
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -Index: src/google/protobuf/io/zero_copy_stream_impl_lite.cc
    -===================================================================
    ---- src/google/protobuf/io/zero_copy_stream_impl_lite.cc	(revision 511)
    -+++ src/google/protobuf/io/zero_copy_stream_impl_lite.cc	(revision 512)
    -@@ -36,6 +36,8 @@
    - #include 
    - #include 
    - 
    -+#include 
    -+
    - namespace google {
    - namespace protobuf {
    - namespace io {
    diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.cc b/toolkit/components/protobuf/src/google/protobuf/descriptor.cc
    new file mode 100644
    index 000000000000..21dda5987f7f
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.cc
    @@ -0,0 +1,5420 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#undef PACKAGE  // autoheader #defines this.  :(
    +
    +namespace google {
    +namespace protobuf {
    +
    +const FieldDescriptor::CppType
    +FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
    +  static_cast(0),  // 0 is reserved for errors
    +
    +  CPPTYPE_DOUBLE,   // TYPE_DOUBLE
    +  CPPTYPE_FLOAT,    // TYPE_FLOAT
    +  CPPTYPE_INT64,    // TYPE_INT64
    +  CPPTYPE_UINT64,   // TYPE_UINT64
    +  CPPTYPE_INT32,    // TYPE_INT32
    +  CPPTYPE_UINT64,   // TYPE_FIXED64
    +  CPPTYPE_UINT32,   // TYPE_FIXED32
    +  CPPTYPE_BOOL,     // TYPE_BOOL
    +  CPPTYPE_STRING,   // TYPE_STRING
    +  CPPTYPE_MESSAGE,  // TYPE_GROUP
    +  CPPTYPE_MESSAGE,  // TYPE_MESSAGE
    +  CPPTYPE_STRING,   // TYPE_BYTES
    +  CPPTYPE_UINT32,   // TYPE_UINT32
    +  CPPTYPE_ENUM,     // TYPE_ENUM
    +  CPPTYPE_INT32,    // TYPE_SFIXED32
    +  CPPTYPE_INT64,    // TYPE_SFIXED64
    +  CPPTYPE_INT32,    // TYPE_SINT32
    +  CPPTYPE_INT64,    // TYPE_SINT64
    +};
    +
    +const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
    +  "ERROR",     // 0 is reserved for errors
    +
    +  "double",    // TYPE_DOUBLE
    +  "float",     // TYPE_FLOAT
    +  "int64",     // TYPE_INT64
    +  "uint64",    // TYPE_UINT64
    +  "int32",     // TYPE_INT32
    +  "fixed64",   // TYPE_FIXED64
    +  "fixed32",   // TYPE_FIXED32
    +  "bool",      // TYPE_BOOL
    +  "string",    // TYPE_STRING
    +  "group",     // TYPE_GROUP
    +  "message",   // TYPE_MESSAGE
    +  "bytes",     // TYPE_BYTES
    +  "uint32",    // TYPE_UINT32
    +  "enum",      // TYPE_ENUM
    +  "sfixed32",  // TYPE_SFIXED32
    +  "sfixed64",  // TYPE_SFIXED64
    +  "sint32",    // TYPE_SINT32
    +  "sint64",    // TYPE_SINT64
    +};
    +
    +const char * const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = {
    +  "ERROR",     // 0 is reserved for errors
    +
    +  "int32",     // CPPTYPE_INT32
    +  "int64",     // CPPTYPE_INT64
    +  "uint32",    // CPPTYPE_UINT32
    +  "uint64",    // CPPTYPE_UINT64
    +  "double",    // CPPTYPE_DOUBLE
    +  "float",     // CPPTYPE_FLOAT
    +  "bool",      // CPPTYPE_BOOL
    +  "enum",      // CPPTYPE_ENUM
    +  "string",    // CPPTYPE_STRING
    +  "message",   // CPPTYPE_MESSAGE
    +};
    +
    +const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
    +  "ERROR",     // 0 is reserved for errors
    +
    +  "optional",  // LABEL_OPTIONAL
    +  "required",  // LABEL_REQUIRED
    +  "repeated",  // LABEL_REPEATED
    +};
    +
    +static const char * const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
    +
    +#ifndef _MSC_VER  // MSVC doesn't need these and won't even accept them.
    +const int FieldDescriptor::kMaxNumber;
    +const int FieldDescriptor::kFirstReservedNumber;
    +const int FieldDescriptor::kLastReservedNumber;
    +#endif
    +
    +namespace {
    +
    +string ToCamelCase(const string& input) {
    +  bool capitalize_next = false;
    +  string result;
    +  result.reserve(input.size());
    +
    +  for (int i = 0; i < input.size(); i++) {
    +    if (input[i] == '_') {
    +      capitalize_next = true;
    +    } else if (capitalize_next) {
    +      // Note:  I distrust ctype.h due to locales.
    +      if ('a' <= input[i] && input[i] <= 'z') {
    +        result.push_back(input[i] - 'a' + 'A');
    +      } else {
    +        result.push_back(input[i]);
    +      }
    +      capitalize_next = false;
    +    } else {
    +      result.push_back(input[i]);
    +    }
    +  }
    +
    +  // Lower-case the first letter.
    +  if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') {
    +    result[0] = result[0] - 'A' + 'a';
    +  }
    +
    +  return result;
    +}
    +
    +// A DescriptorPool contains a bunch of hash_maps to implement the
    +// various Find*By*() methods.  Since hashtable lookups are O(1), it's
    +// most efficient to construct a fixed set of large hash_maps used by
    +// all objects in the pool rather than construct one or more small
    +// hash_maps for each object.
    +//
    +// The keys to these hash_maps are (parent, name) or (parent, number)
    +// pairs.  Unfortunately STL doesn't provide hash functions for pair<>,
    +// so we must invent our own.
    +//
    +// TODO(kenton):  Use StringPiece rather than const char* in keys?  It would
    +//   be a lot cleaner but we'd just have to convert it back to const char*
    +//   for the open source release.
    +
    +typedef pair PointerStringPair;
    +
    +struct PointerStringPairEqual {
    +  inline bool operator()(const PointerStringPair& a,
    +                         const PointerStringPair& b) const {
    +    return a.first == b.first && strcmp(a.second, b.second) == 0;
    +  }
    +};
    +
    +template
    +struct PointerIntegerPairHash {
    +  size_t operator()(const PairType& p) const {
    +    // FIXME(kenton):  What is the best way to compute this hash?  I have
    +    // no idea!  This seems a bit better than an XOR.
    +    return reinterpret_cast(p.first) * ((1 << 16) - 1) + p.second;
    +  }
    +
    +#ifdef _MSC_VER
    +  // Used only by MSVC and platforms where hash_map is not available.
    +  static const size_t bucket_size = 4;
    +  static const size_t min_buckets = 8;
    +#endif
    +  inline bool operator()(const PairType& a, const PairType& b) const {
    +    return a.first < b.first ||
    +          (a.first == b.first && a.second < b.second);
    +  }
    +};
    +
    +typedef pair DescriptorIntPair;
    +typedef pair EnumIntPair;
    +
    +struct PointerStringPairHash {
    +  size_t operator()(const PointerStringPair& p) const {
    +    // FIXME(kenton):  What is the best way to compute this hash?  I have
    +    // no idea!  This seems a bit better than an XOR.
    +    hash cstring_hash;
    +    return reinterpret_cast(p.first) * ((1 << 16) - 1) +
    +           cstring_hash(p.second);
    +  }
    +
    +#ifdef _MSC_VER
    +  // Used only by MSVC and platforms where hash_map is not available.
    +  static const size_t bucket_size = 4;
    +  static const size_t min_buckets = 8;
    +#endif
    +  inline bool operator()(const PointerStringPair& a,
    +                         const PointerStringPair& b) const {
    +    if (a.first < b.first) return true;
    +    if (a.first > b.first) return false;
    +    return strcmp(a.second, b.second) < 0;
    +  }
    +};
    +
    +
    +struct Symbol {
    +  enum Type {
    +    NULL_SYMBOL, MESSAGE, FIELD, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD,
    +    PACKAGE
    +  };
    +  Type type;
    +  union {
    +    const Descriptor* descriptor;
    +    const FieldDescriptor* field_descriptor;
    +    const OneofDescriptor* oneof_descriptor;
    +    const EnumDescriptor* enum_descriptor;
    +    const EnumValueDescriptor* enum_value_descriptor;
    +    const ServiceDescriptor* service_descriptor;
    +    const MethodDescriptor* method_descriptor;
    +    const FileDescriptor* package_file_descriptor;
    +  };
    +
    +  inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; }
    +  inline bool IsNull() const { return type == NULL_SYMBOL; }
    +  inline bool IsType() const {
    +    return type == MESSAGE || type == ENUM;
    +  }
    +  inline bool IsAggregate() const {
    +    return type == MESSAGE || type == PACKAGE
    +        || type == ENUM || type == SERVICE;
    +  }
    +
    +#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD)  \
    +  inline explicit Symbol(const TYPE* value) {    \
    +    type = TYPE_CONSTANT;                        \
    +    this->FIELD = value;                         \
    +  }
    +
    +  CONSTRUCTOR(Descriptor         , MESSAGE   , descriptor             )
    +  CONSTRUCTOR(FieldDescriptor    , FIELD     , field_descriptor       )
    +  CONSTRUCTOR(OneofDescriptor    , ONEOF     , oneof_descriptor       )
    +  CONSTRUCTOR(EnumDescriptor     , ENUM      , enum_descriptor        )
    +  CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor  )
    +  CONSTRUCTOR(ServiceDescriptor  , SERVICE   , service_descriptor     )
    +  CONSTRUCTOR(MethodDescriptor   , METHOD    , method_descriptor      )
    +  CONSTRUCTOR(FileDescriptor     , PACKAGE   , package_file_descriptor)
    +#undef CONSTRUCTOR
    +
    +  const FileDescriptor* GetFile() const {
    +    switch (type) {
    +      case NULL_SYMBOL: return NULL;
    +      case MESSAGE    : return descriptor           ->file();
    +      case FIELD      : return field_descriptor     ->file();
    +      case ONEOF      : return oneof_descriptor     ->containing_type()->file();
    +      case ENUM       : return enum_descriptor      ->file();
    +      case ENUM_VALUE : return enum_value_descriptor->type()->file();
    +      case SERVICE    : return service_descriptor   ->file();
    +      case METHOD     : return method_descriptor    ->service()->file();
    +      case PACKAGE    : return package_file_descriptor;
    +    }
    +    return NULL;
    +  }
    +};
    +
    +const Symbol kNullSymbol;
    +
    +typedef hash_map, streq>
    +  SymbolsByNameMap;
    +typedef hash_map
    +  SymbolsByParentMap;
    +typedef hash_map, streq>
    +  FilesByNameMap;
    +typedef hash_map
    +  FieldsByNameMap;
    +typedef hash_map >
    +  FieldsByNumberMap;
    +typedef hash_map >
    +  EnumValuesByNumberMap;
    +// This is a map rather than a hash_map, since we use it to iterate
    +// through all the extensions that extend a given Descriptor, and an
    +// ordered data structure that implements lower_bound is convenient
    +// for that.
    +typedef map
    +  ExtensionsGroupedByDescriptorMap;
    +typedef hash_map LocationsByPathMap;
    +}  // anonymous namespace
    +
    +// ===================================================================
    +// DescriptorPool::Tables
    +
    +class DescriptorPool::Tables {
    + public:
    +  Tables();
    +  ~Tables();
    +
    +  // Record the current state of the tables to the stack of checkpoints.
    +  // Each call to AddCheckpoint() must be paired with exactly one call to either
    +  // ClearLastCheckpoint() or RollbackToLastCheckpoint().
    +  //
    +  // This is used when building files, since some kinds of validation errors
    +  // cannot be detected until the file's descriptors have already been added to
    +  // the tables.
    +  //
    +  // This supports recursive checkpoints, since building a file may trigger
    +  // recursive building of other files. Note that recursive checkpoints are not
    +  // normally necessary; explicit dependencies are built prior to checkpointing.
    +  // So although we recursively build transitive imports, there is at most one
    +  // checkpoint in the stack during dependency building.
    +  //
    +  // Recursive checkpoints only arise during cross-linking of the descriptors.
    +  // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and
    +  // friends. If the pending file references an unknown symbol
    +  // (e.g., it is not defined in the pending file's explicit dependencies), and
    +  // the pool is using a fallback database, and that database contains a file
    +  // defining that symbol, and that file has not yet been built by the pool,
    +  // the pool builds the file during cross-linking, leading to another
    +  // checkpoint.
    +  void AddCheckpoint();
    +
    +  // Mark the last checkpoint as having cleared successfully, removing it from
    +  // the stack. If the stack is empty, all pending symbols will be committed.
    +  //
    +  // Note that this does not guarantee that the symbols added since the last
    +  // checkpoint won't be rolled back: if a checkpoint gets rolled back,
    +  // everything past that point gets rolled back, including symbols added after
    +  // checkpoints that were pushed onto the stack after it and marked as cleared.
    +  void ClearLastCheckpoint();
    +
    +  // Roll back the Tables to the state of the checkpoint at the top of the
    +  // stack, removing everything that was added after that point.
    +  void RollbackToLastCheckpoint();
    +
    +  // The stack of files which are currently being built.  Used to detect
    +  // cyclic dependencies when loading files from a DescriptorDatabase.  Not
    +  // used when fallback_database_ == NULL.
    +  vector pending_files_;
    +
    +  // A set of files which we have tried to load from the fallback database
    +  // and encountered errors.  We will not attempt to load them again during
    +  // execution of the current public API call, but for compatibility with
    +  // legacy clients, this is cleared at the beginning of each public API call.
    +  // Not used when fallback_database_ == NULL.
    +  hash_set known_bad_files_;
    +
    +  // A set of symbols which we have tried to load from the fallback database
    +  // and encountered errors. We will not attempt to load them again during
    +  // execution of the current public API call, but for compatibility with
    +  // legacy clients, this is cleared at the beginning of each public API call.
    +  hash_set known_bad_symbols_;
    +
    +  // The set of descriptors for which we've already loaded the full
    +  // set of extensions numbers from fallback_database_.
    +  hash_set extensions_loaded_from_db_;
    +
    +  // -----------------------------------------------------------------
    +  // Finding items.
    +
    +  // Find symbols.  This returns a null Symbol (symbol.IsNull() is true)
    +  // if not found.
    +  inline Symbol FindSymbol(const string& key) const;
    +
    +  // This implements the body of DescriptorPool::Find*ByName().  It should
    +  // really be a private method of DescriptorPool, but that would require
    +  // declaring Symbol in descriptor.h, which would drag all kinds of other
    +  // stuff into the header.  Yay C++.
    +  Symbol FindByNameHelper(
    +    const DescriptorPool* pool, const string& name);
    +
    +  // These return NULL if not found.
    +  inline const FileDescriptor* FindFile(const string& key) const;
    +  inline const FieldDescriptor* FindExtension(const Descriptor* extendee,
    +                                              int number);
    +  inline void FindAllExtensions(const Descriptor* extendee,
    +                                vector* out) const;
    +
    +  // -----------------------------------------------------------------
    +  // Adding items.
    +
    +  // These add items to the corresponding tables.  They return false if
    +  // the key already exists in the table.  For AddSymbol(), the string passed
    +  // in must be one that was constructed using AllocateString(), as it will
    +  // be used as a key in the symbols_by_name_ map without copying.
    +  bool AddSymbol(const string& full_name, Symbol symbol);
    +  bool AddFile(const FileDescriptor* file);
    +  bool AddExtension(const FieldDescriptor* field);
    +
    +  // -----------------------------------------------------------------
    +  // Allocating memory.
    +
    +  // Allocate an object which will be reclaimed when the pool is
    +  // destroyed.  Note that the object's destructor will never be called,
    +  // so its fields must be plain old data (primitive data types and
    +  // pointers).  All of the descriptor types are such objects.
    +  template Type* Allocate();
    +
    +  // Allocate an array of objects which will be reclaimed when the
    +  // pool in destroyed.  Again, destructors are never called.
    +  template Type* AllocateArray(int count);
    +
    +  // Allocate a string which will be destroyed when the pool is destroyed.
    +  // The string is initialized to the given value for convenience.
    +  string* AllocateString(const string& value);
    +
    +  // Allocate a protocol message object.  Some older versions of GCC have
    +  // trouble understanding explicit template instantiations in some cases, so
    +  // in those cases we have to pass a dummy pointer of the right type as the
    +  // parameter instead of specifying the type explicitly.
    +  template Type* AllocateMessage(Type* dummy = NULL);
    +
    +  // Allocate a FileDescriptorTables object.
    +  FileDescriptorTables* AllocateFileTables();
    +
    + private:
    +  vector strings_;    // All strings in the pool.
    +  vector messages_;  // All messages in the pool.
    +  vector file_tables_;  // All file tables in the pool.
    +  vector allocations_;  // All other memory allocated in the pool.
    +
    +  SymbolsByNameMap      symbols_by_name_;
    +  FilesByNameMap        files_by_name_;
    +  ExtensionsGroupedByDescriptorMap extensions_;
    +
    +  struct CheckPoint {
    +    explicit CheckPoint(const Tables* tables)
    +      : strings_before_checkpoint(tables->strings_.size()),
    +        messages_before_checkpoint(tables->messages_.size()),
    +        file_tables_before_checkpoint(tables->file_tables_.size()),
    +        allocations_before_checkpoint(tables->allocations_.size()),
    +        pending_symbols_before_checkpoint(
    +            tables->symbols_after_checkpoint_.size()),
    +        pending_files_before_checkpoint(
    +            tables->files_after_checkpoint_.size()),
    +        pending_extensions_before_checkpoint(
    +            tables->extensions_after_checkpoint_.size()) {
    +    }
    +    int strings_before_checkpoint;
    +    int messages_before_checkpoint;
    +    int file_tables_before_checkpoint;
    +    int allocations_before_checkpoint;
    +    int pending_symbols_before_checkpoint;
    +    int pending_files_before_checkpoint;
    +    int pending_extensions_before_checkpoint;
    +  };
    +  vector checkpoints_;
    +  vector symbols_after_checkpoint_;
    +  vector files_after_checkpoint_;
    +  vector extensions_after_checkpoint_;
    +
    +  // Allocate some bytes which will be reclaimed when the pool is
    +  // destroyed.
    +  void* AllocateBytes(int size);
    +};
    +
    +// Contains tables specific to a particular file.  These tables are not
    +// modified once the file has been constructed, so they need not be
    +// protected by a mutex.  This makes operations that depend only on the
    +// contents of a single file -- e.g. Descriptor::FindFieldByName() --
    +// lock-free.
    +//
    +// For historical reasons, the definitions of the methods of
    +// FileDescriptorTables and DescriptorPool::Tables are interleaved below.
    +// These used to be a single class.
    +class FileDescriptorTables {
    + public:
    +  FileDescriptorTables();
    +  ~FileDescriptorTables();
    +
    +  // Empty table, used with placeholder files.
    +  static const FileDescriptorTables kEmpty;
    +
    +  // -----------------------------------------------------------------
    +  // Finding items.
    +
    +  // Find symbols.  These return a null Symbol (symbol.IsNull() is true)
    +  // if not found.
    +  inline Symbol FindNestedSymbol(const void* parent,
    +                                 const string& name) const;
    +  inline Symbol FindNestedSymbolOfType(const void* parent,
    +                                       const string& name,
    +                                       const Symbol::Type type) const;
    +
    +  // These return NULL if not found.
    +  inline const FieldDescriptor* FindFieldByNumber(
    +    const Descriptor* parent, int number) const;
    +  inline const FieldDescriptor* FindFieldByLowercaseName(
    +    const void* parent, const string& lowercase_name) const;
    +  inline const FieldDescriptor* FindFieldByCamelcaseName(
    +    const void* parent, const string& camelcase_name) const;
    +  inline const EnumValueDescriptor* FindEnumValueByNumber(
    +    const EnumDescriptor* parent, int number) const;
    +
    +  // -----------------------------------------------------------------
    +  // Adding items.
    +
    +  // These add items to the corresponding tables.  They return false if
    +  // the key already exists in the table.  For AddAliasUnderParent(), the
    +  // string passed in must be one that was constructed using AllocateString(),
    +  // as it will be used as a key in the symbols_by_parent_ map without copying.
    +  bool AddAliasUnderParent(const void* parent, const string& name,
    +                           Symbol symbol);
    +  bool AddFieldByNumber(const FieldDescriptor* field);
    +  bool AddEnumValueByNumber(const EnumValueDescriptor* value);
    +
    +  // Adds the field to the lowercase_name and camelcase_name maps.  Never
    +  // fails because we allow duplicates; the first field by the name wins.
    +  void AddFieldByStylizedNames(const FieldDescriptor* field);
    +
    +  // Populates p->first->locations_by_path_ from p->second.
    +  // Unusual signature dictated by GoogleOnceDynamic.
    +  static void BuildLocationsByPath(
    +      pair* p);
    +
    +  // Returns the location denoted by the specified path through info,
    +  // or NULL if not found.
    +  // The value of info must be that of the corresponding FileDescriptor.
    +  // (Conceptually a pure function, but stateful as an optimisation.)
    +  const SourceCodeInfo_Location* GetSourceLocation(
    +      const vector& path, const SourceCodeInfo* info) const;
    +
    + private:
    +  SymbolsByParentMap    symbols_by_parent_;
    +  FieldsByNameMap       fields_by_lowercase_name_;
    +  FieldsByNameMap       fields_by_camelcase_name_;
    +  FieldsByNumberMap     fields_by_number_;       // Not including extensions.
    +  EnumValuesByNumberMap enum_values_by_number_;
    +
    +  // Populated on first request to save space, hence constness games.
    +  mutable GoogleOnceDynamic locations_by_path_once_;
    +  mutable LocationsByPathMap locations_by_path_;
    +};
    +
    +DescriptorPool::Tables::Tables()
    +    // Start some hash_map and hash_set objects with a small # of buckets
    +    : known_bad_files_(3),
    +      known_bad_symbols_(3),
    +      extensions_loaded_from_db_(3),
    +      symbols_by_name_(3),
    +      files_by_name_(3) {}
    +
    +
    +DescriptorPool::Tables::~Tables() {
    +  GOOGLE_DCHECK(checkpoints_.empty());
    +  // Note that the deletion order is important, since the destructors of some
    +  // messages may refer to objects in allocations_.
    +  STLDeleteElements(&messages_);
    +  for (int i = 0; i < allocations_.size(); i++) {
    +    operator delete(allocations_[i]);
    +  }
    +  STLDeleteElements(&strings_);
    +  STLDeleteElements(&file_tables_);
    +}
    +
    +FileDescriptorTables::FileDescriptorTables()
    +    // Initialize all the hash tables to start out with a small # of buckets
    +    : symbols_by_parent_(3),
    +      fields_by_lowercase_name_(3),
    +      fields_by_camelcase_name_(3),
    +      fields_by_number_(3),
    +      enum_values_by_number_(3) {
    +}
    +
    +FileDescriptorTables::~FileDescriptorTables() {}
    +
    +const FileDescriptorTables FileDescriptorTables::kEmpty;
    +
    +void DescriptorPool::Tables::AddCheckpoint() {
    +  checkpoints_.push_back(CheckPoint(this));
    +}
    +
    +void DescriptorPool::Tables::ClearLastCheckpoint() {
    +  GOOGLE_DCHECK(!checkpoints_.empty());
    +  checkpoints_.pop_back();
    +  if (checkpoints_.empty()) {
    +    // All checkpoints have been cleared: we can now commit all of the pending
    +    // data.
    +    symbols_after_checkpoint_.clear();
    +    files_after_checkpoint_.clear();
    +    extensions_after_checkpoint_.clear();
    +  }
    +}
    +
    +void DescriptorPool::Tables::RollbackToLastCheckpoint() {
    +  GOOGLE_DCHECK(!checkpoints_.empty());
    +  const CheckPoint& checkpoint = checkpoints_.back();
    +
    +  for (int i = checkpoint.pending_symbols_before_checkpoint;
    +       i < symbols_after_checkpoint_.size();
    +       i++) {
    +    symbols_by_name_.erase(symbols_after_checkpoint_[i]);
    +  }
    +  for (int i = checkpoint.pending_files_before_checkpoint;
    +       i < files_after_checkpoint_.size();
    +       i++) {
    +    files_by_name_.erase(files_after_checkpoint_[i]);
    +  }
    +  for (int i = checkpoint.pending_extensions_before_checkpoint;
    +       i < extensions_after_checkpoint_.size();
    +       i++) {
    +    extensions_.erase(extensions_after_checkpoint_[i]);
    +  }
    +
    +  symbols_after_checkpoint_.resize(
    +      checkpoint.pending_symbols_before_checkpoint);
    +  files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint);
    +  extensions_after_checkpoint_.resize(
    +      checkpoint.pending_extensions_before_checkpoint);
    +
    +  STLDeleteContainerPointers(
    +      strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end());
    +  STLDeleteContainerPointers(
    +      messages_.begin() + checkpoint.messages_before_checkpoint,
    +      messages_.end());
    +  STLDeleteContainerPointers(
    +      file_tables_.begin() + checkpoint.file_tables_before_checkpoint,
    +      file_tables_.end());
    +  for (int i = checkpoint.allocations_before_checkpoint;
    +       i < allocations_.size();
    +       i++) {
    +    operator delete(allocations_[i]);
    +  }
    +
    +  strings_.resize(checkpoint.strings_before_checkpoint);
    +  messages_.resize(checkpoint.messages_before_checkpoint);
    +  file_tables_.resize(checkpoint.file_tables_before_checkpoint);
    +  allocations_.resize(checkpoint.allocations_before_checkpoint);
    +  checkpoints_.pop_back();
    +}
    +
    +// -------------------------------------------------------------------
    +
    +inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const {
    +  const Symbol* result = FindOrNull(symbols_by_name_, key.c_str());
    +  if (result == NULL) {
    +    return kNullSymbol;
    +  } else {
    +    return *result;
    +  }
    +}
    +
    +inline Symbol FileDescriptorTables::FindNestedSymbol(
    +    const void* parent, const string& name) const {
    +  const Symbol* result =
    +    FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str()));
    +  if (result == NULL) {
    +    return kNullSymbol;
    +  } else {
    +    return *result;
    +  }
    +}
    +
    +inline Symbol FileDescriptorTables::FindNestedSymbolOfType(
    +    const void* parent, const string& name, const Symbol::Type type) const {
    +  Symbol result = FindNestedSymbol(parent, name);
    +  if (result.type != type) return kNullSymbol;
    +  return result;
    +}
    +
    +Symbol DescriptorPool::Tables::FindByNameHelper(
    +    const DescriptorPool* pool, const string& name) {
    +  MutexLockMaybe lock(pool->mutex_);
    +  known_bad_symbols_.clear();
    +  known_bad_files_.clear();
    +  Symbol result = FindSymbol(name);
    +
    +  if (result.IsNull() && pool->underlay_ != NULL) {
    +    // Symbol not found; check the underlay.
    +    result =
    +      pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
    +  }
    +
    +  if (result.IsNull()) {
    +    // Symbol still not found, so check fallback database.
    +    if (pool->TryFindSymbolInFallbackDatabase(name)) {
    +      result = FindSymbol(name);
    +    }
    +  }
    +
    +  return result;
    +}
    +
    +inline const FileDescriptor* DescriptorPool::Tables::FindFile(
    +    const string& key) const {
    +  return FindPtrOrNull(files_by_name_, key.c_str());
    +}
    +
    +inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
    +    const Descriptor* parent, int number) const {
    +  return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
    +}
    +
    +inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
    +    const void* parent, const string& lowercase_name) const {
    +  return FindPtrOrNull(fields_by_lowercase_name_,
    +                       PointerStringPair(parent, lowercase_name.c_str()));
    +}
    +
    +inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
    +    const void* parent, const string& camelcase_name) const {
    +  return FindPtrOrNull(fields_by_camelcase_name_,
    +                       PointerStringPair(parent, camelcase_name.c_str()));
    +}
    +
    +inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
    +    const EnumDescriptor* parent, int number) const {
    +  return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
    +}
    +
    +inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
    +    const Descriptor* extendee, int number) {
    +  return FindPtrOrNull(extensions_, make_pair(extendee, number));
    +}
    +
    +inline void DescriptorPool::Tables::FindAllExtensions(
    +    const Descriptor* extendee, vector* out) const {
    +  ExtensionsGroupedByDescriptorMap::const_iterator it =
    +      extensions_.lower_bound(make_pair(extendee, 0));
    +  for (; it != extensions_.end() && it->first.first == extendee; ++it) {
    +    out->push_back(it->second);
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +
    +bool DescriptorPool::Tables::AddSymbol(
    +    const string& full_name, Symbol symbol) {
    +  if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) {
    +    symbols_after_checkpoint_.push_back(full_name.c_str());
    +    return true;
    +  } else {
    +    return false;
    +  }
    +}
    +
    +bool FileDescriptorTables::AddAliasUnderParent(
    +    const void* parent, const string& name, Symbol symbol) {
    +  PointerStringPair by_parent_key(parent, name.c_str());
    +  return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol);
    +}
    +
    +bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) {
    +  if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) {
    +    files_after_checkpoint_.push_back(file->name().c_str());
    +    return true;
    +  } else {
    +    return false;
    +  }
    +}
    +
    +void FileDescriptorTables::AddFieldByStylizedNames(
    +    const FieldDescriptor* field) {
    +  const void* parent;
    +  if (field->is_extension()) {
    +    if (field->extension_scope() == NULL) {
    +      parent = field->file();
    +    } else {
    +      parent = field->extension_scope();
    +    }
    +  } else {
    +    parent = field->containing_type();
    +  }
    +
    +  PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
    +  InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field);
    +
    +  PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
    +  InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field);
    +}
    +
    +bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) {
    +  DescriptorIntPair key(field->containing_type(), field->number());
    +  return InsertIfNotPresent(&fields_by_number_, key, field);
    +}
    +
    +bool FileDescriptorTables::AddEnumValueByNumber(
    +    const EnumValueDescriptor* value) {
    +  EnumIntPair key(value->type(), value->number());
    +  return InsertIfNotPresent(&enum_values_by_number_, key, value);
    +}
    +
    +bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) {
    +  DescriptorIntPair key(field->containing_type(), field->number());
    +  if (InsertIfNotPresent(&extensions_, key, field)) {
    +    extensions_after_checkpoint_.push_back(key);
    +    return true;
    +  } else {
    +    return false;
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +
    +template
    +Type* DescriptorPool::Tables::Allocate() {
    +  return reinterpret_cast(AllocateBytes(sizeof(Type)));
    +}
    +
    +template
    +Type* DescriptorPool::Tables::AllocateArray(int count) {
    +  return reinterpret_cast(AllocateBytes(sizeof(Type) * count));
    +}
    +
    +string* DescriptorPool::Tables::AllocateString(const string& value) {
    +  string* result = new string(value);
    +  strings_.push_back(result);
    +  return result;
    +}
    +
    +template
    +Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) {
    +  Type* result = new Type;
    +  messages_.push_back(result);
    +  return result;
    +}
    +
    +FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() {
    +  FileDescriptorTables* result = new FileDescriptorTables;
    +  file_tables_.push_back(result);
    +  return result;
    +}
    +
    +void* DescriptorPool::Tables::AllocateBytes(int size) {
    +  // TODO(kenton):  Would it be worthwhile to implement this in some more
    +  // sophisticated way?  Probably not for the open source release, but for
    +  // internal use we could easily plug in one of our existing memory pool
    +  // allocators...
    +  if (size == 0) return NULL;
    +
    +  void* result = operator new(size);
    +  allocations_.push_back(result);
    +  return result;
    +}
    +
    +void FileDescriptorTables::BuildLocationsByPath(
    +    pair* p) {
    +  for (int i = 0, len = p->second->location_size(); i < len; ++i) {
    +    const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
    +    p->first->locations_by_path_[Join(loc->path(), ",")] = loc;
    +  }
    +}
    +
    +const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation(
    +    const vector& path, const SourceCodeInfo* info) const {
    +  pair p(
    +      make_pair(this, info));
    +  locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p);
    +  return FindPtrOrNull(locations_by_path_, Join(path, ","));
    +}
    +
    +// ===================================================================
    +// DescriptorPool
    +
    +DescriptorPool::ErrorCollector::~ErrorCollector() {}
    +
    +DescriptorPool::DescriptorPool()
    +  : mutex_(NULL),
    +    fallback_database_(NULL),
    +    default_error_collector_(NULL),
    +    underlay_(NULL),
    +    tables_(new Tables),
    +    enforce_dependencies_(true),
    +    allow_unknown_(false),
    +    enforce_weak_(false) {}
    +
    +DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
    +                               ErrorCollector* error_collector)
    +  : mutex_(new Mutex),
    +    fallback_database_(fallback_database),
    +    default_error_collector_(error_collector),
    +    underlay_(NULL),
    +    tables_(new Tables),
    +    enforce_dependencies_(true),
    +    allow_unknown_(false),
    +    enforce_weak_(false) {
    +}
    +
    +DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
    +  : mutex_(NULL),
    +    fallback_database_(NULL),
    +    default_error_collector_(NULL),
    +    underlay_(underlay),
    +    tables_(new Tables),
    +    enforce_dependencies_(true),
    +    allow_unknown_(false),
    +    enforce_weak_(false) {}
    +
    +DescriptorPool::~DescriptorPool() {
    +  if (mutex_ != NULL) delete mutex_;
    +}
    +
    +// DescriptorPool::BuildFile() defined later.
    +// DescriptorPool::BuildFileCollectingErrors() defined later.
    +
    +void DescriptorPool::InternalDontEnforceDependencies() {
    +  enforce_dependencies_ = false;
    +}
    +
    +void DescriptorPool::AddUnusedImportTrackFile(const string& file_name) {
    +  unused_import_track_files_.insert(file_name);
    +}
    +
    +void DescriptorPool::ClearUnusedImportTrackFiles() {
    +  unused_import_track_files_.clear();
    +}
    +
    +bool DescriptorPool::InternalIsFileLoaded(const string& filename) const {
    +  MutexLockMaybe lock(mutex_);
    +  return tables_->FindFile(filename) != NULL;
    +}
    +
    +// generated_pool ====================================================
    +
    +namespace {
    +
    +
    +EncodedDescriptorDatabase* generated_database_ = NULL;
    +DescriptorPool* generated_pool_ = NULL;
    +GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_);
    +
    +void DeleteGeneratedPool() {
    +  delete generated_database_;
    +  generated_database_ = NULL;
    +  delete generated_pool_;
    +  generated_pool_ = NULL;
    +}
    +
    +static void InitGeneratedPool() {
    +  generated_database_ = new EncodedDescriptorDatabase;
    +  generated_pool_ = new DescriptorPool(generated_database_);
    +
    +  internal::OnShutdown(&DeleteGeneratedPool);
    +}
    +
    +inline void InitGeneratedPoolOnce() {
    +  ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool);
    +}
    +
    +}  // anonymous namespace
    +
    +const DescriptorPool* DescriptorPool::generated_pool() {
    +  InitGeneratedPoolOnce();
    +  return generated_pool_;
    +}
    +
    +DescriptorPool* DescriptorPool::internal_generated_pool() {
    +  InitGeneratedPoolOnce();
    +  return generated_pool_;
    +}
    +
    +void DescriptorPool::InternalAddGeneratedFile(
    +    const void* encoded_file_descriptor, int size) {
    +  // So, this function is called in the process of initializing the
    +  // descriptors for generated proto classes.  Each generated .pb.cc file
    +  // has an internal procedure called AddDescriptors() which is called at
    +  // process startup, and that function calls this one in order to register
    +  // the raw bytes of the FileDescriptorProto representing the file.
    +  //
    +  // We do not actually construct the descriptor objects right away.  We just
    +  // hang on to the bytes until they are actually needed.  We actually construct
    +  // the descriptor the first time one of the following things happens:
    +  // * Someone calls a method like descriptor(), GetDescriptor(), or
    +  //   GetReflection() on the generated types, which requires returning the
    +  //   descriptor or an object based on it.
    +  // * Someone looks up the descriptor in DescriptorPool::generated_pool().
    +  //
    +  // Once one of these happens, the DescriptorPool actually parses the
    +  // FileDescriptorProto and generates a FileDescriptor (and all its children)
    +  // based on it.
    +  //
    +  // Note that FileDescriptorProto is itself a generated protocol message.
    +  // Therefore, when we parse one, we have to be very careful to avoid using
    +  // any descriptor-based operations, since this might cause infinite recursion
    +  // or deadlock.
    +  InitGeneratedPoolOnce();
    +  GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size));
    +}
    +
    +
    +// Find*By* methods ==================================================
    +
    +// TODO(kenton):  There's a lot of repeated code here, but I'm not sure if
    +//   there's any good way to factor it out.  Think about this some time when
    +//   there's nothing more important to do (read: never).
    +
    +const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
    +  MutexLockMaybe lock(mutex_);
    +  tables_->known_bad_symbols_.clear();
    +  tables_->known_bad_files_.clear();
    +  const FileDescriptor* result = tables_->FindFile(name);
    +  if (result != NULL) return result;
    +  if (underlay_ != NULL) {
    +    result = underlay_->FindFileByName(name);
    +    if (result != NULL) return result;
    +  }
    +  if (TryFindFileInFallbackDatabase(name)) {
    +    result = tables_->FindFile(name);
    +    if (result != NULL) return result;
    +  }
    +  return NULL;
    +}
    +
    +const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
    +    const string& symbol_name) const {
    +  MutexLockMaybe lock(mutex_);
    +  tables_->known_bad_symbols_.clear();
    +  tables_->known_bad_files_.clear();
    +  Symbol result = tables_->FindSymbol(symbol_name);
    +  if (!result.IsNull()) return result.GetFile();
    +  if (underlay_ != NULL) {
    +    const FileDescriptor* file_result =
    +      underlay_->FindFileContainingSymbol(symbol_name);
    +    if (file_result != NULL) return file_result;
    +  }
    +  if (TryFindSymbolInFallbackDatabase(symbol_name)) {
    +    result = tables_->FindSymbol(symbol_name);
    +    if (!result.IsNull()) return result.GetFile();
    +  }
    +  return NULL;
    +}
    +
    +const Descriptor* DescriptorPool::FindMessageTypeByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL;
    +}
    +
    +const FieldDescriptor* DescriptorPool::FindFieldByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  if (result.type == Symbol::FIELD &&
    +      !result.field_descriptor->is_extension()) {
    +    return result.field_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const FieldDescriptor* DescriptorPool::FindExtensionByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  if (result.type == Symbol::FIELD &&
    +      result.field_descriptor->is_extension()) {
    +    return result.field_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const OneofDescriptor* DescriptorPool::FindOneofByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : NULL;
    +}
    +
    +const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL;
    +}
    +
    +const EnumValueDescriptor* DescriptorPool::FindEnumValueByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  return (result.type == Symbol::ENUM_VALUE) ?
    +    result.enum_value_descriptor : NULL;
    +}
    +
    +const ServiceDescriptor* DescriptorPool::FindServiceByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL;
    +}
    +
    +const MethodDescriptor* DescriptorPool::FindMethodByName(
    +    const string& name) const {
    +  Symbol result = tables_->FindByNameHelper(this, name);
    +  return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL;
    +}
    +
    +const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
    +    const Descriptor* extendee, int number) const {
    +  MutexLockMaybe lock(mutex_);
    +  tables_->known_bad_symbols_.clear();
    +  tables_->known_bad_files_.clear();
    +  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
    +  if (result != NULL) {
    +    return result;
    +  }
    +  if (underlay_ != NULL) {
    +    result = underlay_->FindExtensionByNumber(extendee, number);
    +    if (result != NULL) return result;
    +  }
    +  if (TryFindExtensionInFallbackDatabase(extendee, number)) {
    +    result = tables_->FindExtension(extendee, number);
    +    if (result != NULL) {
    +      return result;
    +    }
    +  }
    +  return NULL;
    +}
    +
    +void DescriptorPool::FindAllExtensions(
    +    const Descriptor* extendee, vector* out) const {
    +  MutexLockMaybe lock(mutex_);
    +  tables_->known_bad_symbols_.clear();
    +  tables_->known_bad_files_.clear();
    +
    +  // Initialize tables_->extensions_ from the fallback database first
    +  // (but do this only once per descriptor).
    +  if (fallback_database_ != NULL &&
    +      tables_->extensions_loaded_from_db_.count(extendee) == 0) {
    +    vector numbers;
    +    if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
    +                                                    &numbers)) {
    +      for (int i = 0; i < numbers.size(); ++i) {
    +        int number = numbers[i];
    +        if (tables_->FindExtension(extendee, number) == NULL) {
    +          TryFindExtensionInFallbackDatabase(extendee, number);
    +        }
    +      }
    +      tables_->extensions_loaded_from_db_.insert(extendee);
    +    }
    +  }
    +
    +  tables_->FindAllExtensions(extendee, out);
    +  if (underlay_ != NULL) {
    +    underlay_->FindAllExtensions(extendee, out);
    +  }
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +const FieldDescriptor*
    +Descriptor::FindFieldByNumber(int key) const {
    +  const FieldDescriptor* result =
    +    file()->tables_->FindFieldByNumber(this, key);
    +  if (result == NULL || result->is_extension()) {
    +    return NULL;
    +  } else {
    +    return result;
    +  }
    +}
    +
    +const FieldDescriptor*
    +Descriptor::FindFieldByLowercaseName(const string& key) const {
    +  const FieldDescriptor* result =
    +    file()->tables_->FindFieldByLowercaseName(this, key);
    +  if (result == NULL || result->is_extension()) {
    +    return NULL;
    +  } else {
    +    return result;
    +  }
    +}
    +
    +const FieldDescriptor*
    +Descriptor::FindFieldByCamelcaseName(const string& key) const {
    +  const FieldDescriptor* result =
    +    file()->tables_->FindFieldByCamelcaseName(this, key);
    +  if (result == NULL || result->is_extension()) {
    +    return NULL;
    +  } else {
    +    return result;
    +  }
    +}
    +
    +const FieldDescriptor*
    +Descriptor::FindFieldByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
    +  if (!result.IsNull() && !result.field_descriptor->is_extension()) {
    +    return result.field_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const OneofDescriptor*
    +Descriptor::FindOneofByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF);
    +  if (!result.IsNull()) {
    +    return result.oneof_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const FieldDescriptor*
    +Descriptor::FindExtensionByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
    +  if (!result.IsNull() && result.field_descriptor->is_extension()) {
    +    return result.field_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const FieldDescriptor*
    +Descriptor::FindExtensionByLowercaseName(const string& key) const {
    +  const FieldDescriptor* result =
    +    file()->tables_->FindFieldByLowercaseName(this, key);
    +  if (result == NULL || !result->is_extension()) {
    +    return NULL;
    +  } else {
    +    return result;
    +  }
    +}
    +
    +const FieldDescriptor*
    +Descriptor::FindExtensionByCamelcaseName(const string& key) const {
    +  const FieldDescriptor* result =
    +    file()->tables_->FindFieldByCamelcaseName(this, key);
    +  if (result == NULL || !result->is_extension()) {
    +    return NULL;
    +  } else {
    +    return result;
    +  }
    +}
    +
    +const Descriptor*
    +Descriptor::FindNestedTypeByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
    +  if (!result.IsNull()) {
    +    return result.descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const EnumDescriptor*
    +Descriptor::FindEnumTypeByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
    +  if (!result.IsNull()) {
    +    return result.enum_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const EnumValueDescriptor*
    +Descriptor::FindEnumValueByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
    +  if (!result.IsNull()) {
    +    return result.enum_value_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const EnumValueDescriptor*
    +EnumDescriptor::FindValueByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
    +  if (!result.IsNull()) {
    +    return result.enum_value_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const EnumValueDescriptor*
    +EnumDescriptor::FindValueByNumber(int key) const {
    +  return file()->tables_->FindEnumValueByNumber(this, key);
    +}
    +
    +const MethodDescriptor*
    +ServiceDescriptor::FindMethodByName(const string& key) const {
    +  Symbol result =
    +    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD);
    +  if (!result.IsNull()) {
    +    return result.method_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const Descriptor*
    +FileDescriptor::FindMessageTypeByName(const string& key) const {
    +  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
    +  if (!result.IsNull()) {
    +    return result.descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const EnumDescriptor*
    +FileDescriptor::FindEnumTypeByName(const string& key) const {
    +  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
    +  if (!result.IsNull()) {
    +    return result.enum_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const EnumValueDescriptor*
    +FileDescriptor::FindEnumValueByName(const string& key) const {
    +  Symbol result =
    +    tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
    +  if (!result.IsNull()) {
    +    return result.enum_value_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const ServiceDescriptor*
    +FileDescriptor::FindServiceByName(const string& key) const {
    +  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE);
    +  if (!result.IsNull()) {
    +    return result.service_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const FieldDescriptor*
    +FileDescriptor::FindExtensionByName(const string& key) const {
    +  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
    +  if (!result.IsNull() && result.field_descriptor->is_extension()) {
    +    return result.field_descriptor;
    +  } else {
    +    return NULL;
    +  }
    +}
    +
    +const FieldDescriptor*
    +FileDescriptor::FindExtensionByLowercaseName(const string& key) const {
    +  const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key);
    +  if (result == NULL || !result->is_extension()) {
    +    return NULL;
    +  } else {
    +    return result;
    +  }
    +}
    +
    +const FieldDescriptor*
    +FileDescriptor::FindExtensionByCamelcaseName(const string& key) const {
    +  const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key);
    +  if (result == NULL || !result->is_extension()) {
    +    return NULL;
    +  } else {
    +    return result;
    +  }
    +}
    +
    +const Descriptor::ExtensionRange*
    +Descriptor::FindExtensionRangeContainingNumber(int number) const {
    +  // Linear search should be fine because we don't expect a message to have
    +  // more than a couple extension ranges.
    +  for (int i = 0; i < extension_range_count(); i++) {
    +    if (number >= extension_range(i)->start &&
    +        number <  extension_range(i)->end) {
    +      return extension_range(i);
    +    }
    +  }
    +  return NULL;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const {
    +  if (fallback_database_ == NULL) return false;
    +
    +  if (tables_->known_bad_files_.count(name) > 0) return false;
    +
    +  FileDescriptorProto file_proto;
    +  if (!fallback_database_->FindFileByName(name, &file_proto) ||
    +      BuildFileFromDatabase(file_proto) == NULL) {
    +    tables_->known_bad_files_.insert(name);
    +    return false;
    +  }
    +  return true;
    +}
    +
    +bool DescriptorPool::IsSubSymbolOfBuiltType(const string& name) const {
    +  string prefix = name;
    +  for (;;) {
    +    string::size_type dot_pos = prefix.find_last_of('.');
    +    if (dot_pos == string::npos) {
    +      break;
    +    }
    +    prefix = prefix.substr(0, dot_pos);
    +    Symbol symbol = tables_->FindSymbol(prefix);
    +    // If the symbol type is anything other than PACKAGE, then its complete
    +    // definition is already known.
    +    if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) {
    +      return true;
    +    }
    +  }
    +  if (underlay_ != NULL) {
    +    // Check to see if any prefix of this symbol exists in the underlay.
    +    return underlay_->IsSubSymbolOfBuiltType(name);
    +  }
    +  return false;
    +}
    +
    +bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const {
    +  if (fallback_database_ == NULL) return false;
    +
    +  if (tables_->known_bad_symbols_.count(name) > 0) return false;
    +
    +  FileDescriptorProto file_proto;
    +  if (// We skip looking in the fallback database if the name is a sub-symbol
    +      // of any descriptor that already exists in the descriptor pool (except
    +      // for package descriptors).  This is valid because all symbols except
    +      // for packages are defined in a single file, so if the symbol exists
    +      // then we should already have its definition.
    +      //
    +      // The other reason to do this is to support "overriding" type
    +      // definitions by merging two databases that define the same type.  (Yes,
    +      // people do this.)  The main difficulty with making this work is that
    +      // FindFileContainingSymbol() is allowed to return both false positives
    +      // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false
    +      // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase).
    +      // When two such databases are merged, looking up a non-existent
    +      // sub-symbol of a type that already exists in the descriptor pool can
    +      // result in an attempt to load multiple definitions of the same type.
    +      // The check below avoids this.
    +      IsSubSymbolOfBuiltType(name)
    +
    +      // Look up file containing this symbol in fallback database.
    +      || !fallback_database_->FindFileContainingSymbol(name, &file_proto)
    +
    +      // Check if we've already built this file. If so, it apparently doesn't
    +      // contain the symbol we're looking for.  Some DescriptorDatabases
    +      // return false positives.
    +      || tables_->FindFile(file_proto.name()) != NULL
    +
    +      // Build the file.
    +      || BuildFileFromDatabase(file_proto) == NULL) {
    +    tables_->known_bad_symbols_.insert(name);
    +    return false;
    +  }
    +
    +  return true;
    +}
    +
    +bool DescriptorPool::TryFindExtensionInFallbackDatabase(
    +    const Descriptor* containing_type, int field_number) const {
    +  if (fallback_database_ == NULL) return false;
    +
    +  FileDescriptorProto file_proto;
    +  if (!fallback_database_->FindFileContainingExtension(
    +        containing_type->full_name(), field_number, &file_proto)) {
    +    return false;
    +  }
    +
    +  if (tables_->FindFile(file_proto.name()) != NULL) {
    +    // We've already loaded this file, and it apparently doesn't contain the
    +    // extension we're looking for.  Some DescriptorDatabases return false
    +    // positives.
    +    return false;
    +  }
    +
    +  if (BuildFileFromDatabase(file_proto) == NULL) {
    +    return false;
    +  }
    +
    +  return true;
    +}
    +
    +// ===================================================================
    +
    +string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
    +  GOOGLE_CHECK(has_default_value()) << "No default value";
    +  switch (cpp_type()) {
    +    case CPPTYPE_INT32:
    +      return SimpleItoa(default_value_int32());
    +      break;
    +    case CPPTYPE_INT64:
    +      return SimpleItoa(default_value_int64());
    +      break;
    +    case CPPTYPE_UINT32:
    +      return SimpleItoa(default_value_uint32());
    +      break;
    +    case CPPTYPE_UINT64:
    +      return SimpleItoa(default_value_uint64());
    +      break;
    +    case CPPTYPE_FLOAT:
    +      return SimpleFtoa(default_value_float());
    +      break;
    +    case CPPTYPE_DOUBLE:
    +      return SimpleDtoa(default_value_double());
    +      break;
    +    case CPPTYPE_BOOL:
    +      return default_value_bool() ? "true" : "false";
    +      break;
    +    case CPPTYPE_STRING:
    +      if (quote_string_type) {
    +        return "\"" + CEscape(default_value_string()) + "\"";
    +      } else {
    +        if (type() == TYPE_BYTES) {
    +          return CEscape(default_value_string());
    +        } else {
    +          return default_value_string();
    +        }
    +      }
    +      break;
    +    case CPPTYPE_ENUM:
    +      return default_value_enum()->name();
    +      break;
    +    case CPPTYPE_MESSAGE:
    +      GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
    +      break;
    +  }
    +  GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string";
    +  return "";
    +}
    +
    +// CopyTo methods ====================================================
    +
    +void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
    +  proto->set_name(name());
    +  if (!package().empty()) proto->set_package(package());
    +
    +  for (int i = 0; i < dependency_count(); i++) {
    +    proto->add_dependency(dependency(i)->name());
    +  }
    +
    +  for (int i = 0; i < public_dependency_count(); i++) {
    +    proto->add_public_dependency(public_dependencies_[i]);
    +  }
    +
    +  for (int i = 0; i < weak_dependency_count(); i++) {
    +    proto->add_weak_dependency(weak_dependencies_[i]);
    +  }
    +
    +  for (int i = 0; i < message_type_count(); i++) {
    +    message_type(i)->CopyTo(proto->add_message_type());
    +  }
    +  for (int i = 0; i < enum_type_count(); i++) {
    +    enum_type(i)->CopyTo(proto->add_enum_type());
    +  }
    +  for (int i = 0; i < service_count(); i++) {
    +    service(i)->CopyTo(proto->add_service());
    +  }
    +  for (int i = 0; i < extension_count(); i++) {
    +    extension(i)->CopyTo(proto->add_extension());
    +  }
    +
    +  if (&options() != &FileOptions::default_instance()) {
    +    proto->mutable_options()->CopyFrom(options());
    +  }
    +}
    +
    +void FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const {
    +  if (source_code_info_ != &SourceCodeInfo::default_instance()) {
    +    proto->mutable_source_code_info()->CopyFrom(*source_code_info_);
    +  }
    +}
    +
    +void Descriptor::CopyTo(DescriptorProto* proto) const {
    +  proto->set_name(name());
    +
    +  for (int i = 0; i < field_count(); i++) {
    +    field(i)->CopyTo(proto->add_field());
    +  }
    +  for (int i = 0; i < oneof_decl_count(); i++) {
    +    oneof_decl(i)->CopyTo(proto->add_oneof_decl());
    +  }
    +  for (int i = 0; i < nested_type_count(); i++) {
    +    nested_type(i)->CopyTo(proto->add_nested_type());
    +  }
    +  for (int i = 0; i < enum_type_count(); i++) {
    +    enum_type(i)->CopyTo(proto->add_enum_type());
    +  }
    +  for (int i = 0; i < extension_range_count(); i++) {
    +    DescriptorProto::ExtensionRange* range = proto->add_extension_range();
    +    range->set_start(extension_range(i)->start);
    +    range->set_end(extension_range(i)->end);
    +  }
    +  for (int i = 0; i < extension_count(); i++) {
    +    extension(i)->CopyTo(proto->add_extension());
    +  }
    +
    +  if (&options() != &MessageOptions::default_instance()) {
    +    proto->mutable_options()->CopyFrom(options());
    +  }
    +}
    +
    +void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
    +  proto->set_name(name());
    +  proto->set_number(number());
    +
    +  // Some compilers do not allow static_cast directly between two enum types,
    +  // so we must cast to int first.
    +  proto->set_label(static_cast(
    +                     implicit_cast(label())));
    +  proto->set_type(static_cast(
    +                    implicit_cast(type())));
    +
    +  if (is_extension()) {
    +    if (!containing_type()->is_unqualified_placeholder_) {
    +      proto->set_extendee(".");
    +    }
    +    proto->mutable_extendee()->append(containing_type()->full_name());
    +  }
    +
    +  if (cpp_type() == CPPTYPE_MESSAGE) {
    +    if (message_type()->is_placeholder_) {
    +      // We don't actually know if the type is a message type.  It could be
    +      // an enum.
    +      proto->clear_type();
    +    }
    +
    +    if (!message_type()->is_unqualified_placeholder_) {
    +      proto->set_type_name(".");
    +    }
    +    proto->mutable_type_name()->append(message_type()->full_name());
    +  } else if (cpp_type() == CPPTYPE_ENUM) {
    +    if (!enum_type()->is_unqualified_placeholder_) {
    +      proto->set_type_name(".");
    +    }
    +    proto->mutable_type_name()->append(enum_type()->full_name());
    +  }
    +
    +  if (has_default_value()) {
    +    proto->set_default_value(DefaultValueAsString(false));
    +  }
    +
    +  if (containing_oneof() != NULL && !is_extension()) {
    +    proto->set_oneof_index(containing_oneof()->index());
    +  }
    +
    +  if (&options() != &FieldOptions::default_instance()) {
    +    proto->mutable_options()->CopyFrom(options());
    +  }
    +}
    +
    +void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const {
    +  proto->set_name(name());
    +}
    +
    +void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
    +  proto->set_name(name());
    +
    +  for (int i = 0; i < value_count(); i++) {
    +    value(i)->CopyTo(proto->add_value());
    +  }
    +
    +  if (&options() != &EnumOptions::default_instance()) {
    +    proto->mutable_options()->CopyFrom(options());
    +  }
    +}
    +
    +void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const {
    +  proto->set_name(name());
    +  proto->set_number(number());
    +
    +  if (&options() != &EnumValueOptions::default_instance()) {
    +    proto->mutable_options()->CopyFrom(options());
    +  }
    +}
    +
    +void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const {
    +  proto->set_name(name());
    +
    +  for (int i = 0; i < method_count(); i++) {
    +    method(i)->CopyTo(proto->add_method());
    +  }
    +
    +  if (&options() != &ServiceOptions::default_instance()) {
    +    proto->mutable_options()->CopyFrom(options());
    +  }
    +}
    +
    +void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
    +  proto->set_name(name());
    +
    +  if (!input_type()->is_unqualified_placeholder_) {
    +    proto->set_input_type(".");
    +  }
    +  proto->mutable_input_type()->append(input_type()->full_name());
    +
    +  if (!output_type()->is_unqualified_placeholder_) {
    +    proto->set_output_type(".");
    +  }
    +  proto->mutable_output_type()->append(output_type()->full_name());
    +
    +  if (&options() != &MethodOptions::default_instance()) {
    +    proto->mutable_options()->CopyFrom(options());
    +  }
    +}
    +
    +// DebugString methods ===============================================
    +
    +namespace {
    +
    +// Used by each of the option formatters.
    +bool RetrieveOptions(int depth,
    +                     const Message &options,
    +                     vector *option_entries) {
    +  option_entries->clear();
    +  const Reflection* reflection = options.GetReflection();
    +  vector fields;
    +  reflection->ListFields(options, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    int count = 1;
    +    bool repeated = false;
    +    if (fields[i]->is_repeated()) {
    +      count = reflection->FieldSize(options, fields[i]);
    +      repeated = true;
    +    }
    +    for (int j = 0; j < count; j++) {
    +      string fieldval;
    +      if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +        string tmp;
    +        TextFormat::Printer printer;
    +        printer.SetInitialIndentLevel(depth + 1);
    +        printer.PrintFieldValueToString(options, fields[i],
    +                                        repeated ? j : -1, &tmp);
    +        fieldval.append("{\n");
    +        fieldval.append(tmp);
    +        fieldval.append(depth * 2, ' ');
    +        fieldval.append("}");
    +      } else {
    +        TextFormat::PrintFieldValueToString(options, fields[i],
    +                                            repeated ? j : -1, &fieldval);
    +      }
    +      string name;
    +      if (fields[i]->is_extension()) {
    +        name = "(." + fields[i]->full_name() + ")";
    +      } else {
    +        name = fields[i]->name();
    +      }
    +      option_entries->push_back(name + " = " + fieldval);
    +    }
    +  }
    +  return !option_entries->empty();
    +}
    +
    +// Formats options that all appear together in brackets. Does not include
    +// brackets.
    +bool FormatBracketedOptions(int depth, const Message &options, string *output) {
    +  vector all_options;
    +  if (RetrieveOptions(depth, options, &all_options)) {
    +    output->append(Join(all_options, ", "));
    +  }
    +  return !all_options.empty();
    +}
    +
    +// Formats options one per line
    +bool FormatLineOptions(int depth, const Message &options, string *output) {
    +  string prefix(depth * 2, ' ');
    +  vector all_options;
    +  if (RetrieveOptions(depth, options, &all_options)) {
    +    for (int i = 0; i < all_options.size(); i++) {
    +      strings::SubstituteAndAppend(output, "$0option $1;\n",
    +                                   prefix, all_options[i]);
    +    }
    +  }
    +  return !all_options.empty();
    +}
    +
    +}  // anonymous namespace
    +
    +string FileDescriptor::DebugString() const {
    +  string contents = "syntax = \"proto2\";\n\n";
    +
    +  set public_dependencies;
    +  set weak_dependencies;
    +  public_dependencies.insert(public_dependencies_,
    +                             public_dependencies_ + public_dependency_count_);
    +  weak_dependencies.insert(weak_dependencies_,
    +                           weak_dependencies_ + weak_dependency_count_);
    +
    +  for (int i = 0; i < dependency_count(); i++) {
    +    if (public_dependencies.count(i) > 0) {
    +      strings::SubstituteAndAppend(&contents, "import public \"$0\";\n",
    +                                   dependency(i)->name());
    +    } else if (weak_dependencies.count(i) > 0) {
    +      strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n",
    +                                   dependency(i)->name());
    +    } else {
    +      strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
    +                                   dependency(i)->name());
    +    }
    +  }
    +
    +  if (!package().empty()) {
    +    strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
    +  }
    +
    +  if (FormatLineOptions(0, options(), &contents)) {
    +    contents.append("\n");  // add some space if we had options
    +  }
    +
    +  for (int i = 0; i < enum_type_count(); i++) {
    +    enum_type(i)->DebugString(0, &contents);
    +    contents.append("\n");
    +  }
    +
    +  // Find all the 'group' type extensions; we will not output their nested
    +  // definitions (those will be done with their group field descriptor).
    +  set groups;
    +  for (int i = 0; i < extension_count(); i++) {
    +    if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
    +      groups.insert(extension(i)->message_type());
    +    }
    +  }
    +
    +  for (int i = 0; i < message_type_count(); i++) {
    +    if (groups.count(message_type(i)) == 0) {
    +      strings::SubstituteAndAppend(&contents, "message $0",
    +                                   message_type(i)->name());
    +      message_type(i)->DebugString(0, &contents);
    +      contents.append("\n");
    +    }
    +  }
    +
    +  for (int i = 0; i < service_count(); i++) {
    +    service(i)->DebugString(&contents);
    +    contents.append("\n");
    +  }
    +
    +  const Descriptor* containing_type = NULL;
    +  for (int i = 0; i < extension_count(); i++) {
    +    if (extension(i)->containing_type() != containing_type) {
    +      if (i > 0) contents.append("}\n\n");
    +      containing_type = extension(i)->containing_type();
    +      strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
    +                                   containing_type->full_name());
    +    }
    +    extension(i)->DebugString(1, FieldDescriptor::PRINT_LABEL, &contents);
    +  }
    +  if (extension_count() > 0) contents.append("}\n\n");
    +
    +  return contents;
    +}
    +
    +string Descriptor::DebugString() const {
    +  string contents;
    +  strings::SubstituteAndAppend(&contents, "message $0", name());
    +  DebugString(0, &contents);
    +  return contents;
    +}
    +
    +void Descriptor::DebugString(int depth, string *contents) const {
    +  string prefix(depth * 2, ' ');
    +  ++depth;
    +  contents->append(" {\n");
    +
    +  FormatLineOptions(depth, options(), contents);
    +
    +  // Find all the 'group' types for fields and extensions; we will not output
    +  // their nested definitions (those will be done with their group field
    +  // descriptor).
    +  set groups;
    +  for (int i = 0; i < field_count(); i++) {
    +    if (field(i)->type() == FieldDescriptor::TYPE_GROUP) {
    +      groups.insert(field(i)->message_type());
    +    }
    +  }
    +  for (int i = 0; i < extension_count(); i++) {
    +    if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
    +      groups.insert(extension(i)->message_type());
    +    }
    +  }
    +
    +  for (int i = 0; i < nested_type_count(); i++) {
    +    if (groups.count(nested_type(i)) == 0) {
    +      strings::SubstituteAndAppend(contents, "$0  message $1",
    +                                   prefix, nested_type(i)->name());
    +      nested_type(i)->DebugString(depth, contents);
    +    }
    +  }
    +  for (int i = 0; i < enum_type_count(); i++) {
    +    enum_type(i)->DebugString(depth, contents);
    +  }
    +  for (int i = 0; i < field_count(); i++) {
    +    if (field(i)->containing_oneof() == NULL) {
    +      field(i)->DebugString(depth, FieldDescriptor::PRINT_LABEL, contents);
    +    } else if (field(i)->containing_oneof()->field(0) == field(i)) {
    +      // This is the first field in this oneof, so print the whole oneof.
    +      field(i)->containing_oneof()->DebugString(depth, contents);
    +    }
    +  }
    +
    +  for (int i = 0; i < extension_range_count(); i++) {
    +    strings::SubstituteAndAppend(contents, "$0  extensions $1 to $2;\n",
    +                                 prefix,
    +                                 extension_range(i)->start,
    +                                 extension_range(i)->end - 1);
    +  }
    +
    +  // Group extensions by what they extend, so they can be printed out together.
    +  const Descriptor* containing_type = NULL;
    +  for (int i = 0; i < extension_count(); i++) {
    +    if (extension(i)->containing_type() != containing_type) {
    +      if (i > 0) strings::SubstituteAndAppend(contents, "$0  }\n", prefix);
    +      containing_type = extension(i)->containing_type();
    +      strings::SubstituteAndAppend(contents, "$0  extend .$1 {\n",
    +                                   prefix, containing_type->full_name());
    +    }
    +    extension(i)->DebugString(
    +        depth + 1, FieldDescriptor::PRINT_LABEL, contents);
    +  }
    +  if (extension_count() > 0)
    +    strings::SubstituteAndAppend(contents, "$0  }\n", prefix);
    +
    +  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
    +}
    +
    +string FieldDescriptor::DebugString() const {
    +  string contents;
    +  int depth = 0;
    +  if (is_extension()) {
    +    strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
    +                                 containing_type()->full_name());
    +    depth = 1;
    +  }
    +  DebugString(depth, PRINT_LABEL, &contents);
    +  if (is_extension()) {
    +    contents.append("}\n");
    +  }
    +  return contents;
    +}
    +
    +void FieldDescriptor::DebugString(int depth,
    +                                  PrintLabelFlag print_label_flag,
    +                                  string *contents) const {
    +  string prefix(depth * 2, ' ');
    +  string field_type;
    +  switch (type()) {
    +    case TYPE_MESSAGE:
    +      field_type = "." + message_type()->full_name();
    +      break;
    +    case TYPE_ENUM:
    +      field_type = "." + enum_type()->full_name();
    +      break;
    +    default:
    +      field_type = kTypeToName[type()];
    +  }
    +
    +  string label;
    +  if (print_label_flag == PRINT_LABEL) {
    +    label = kLabelToName[this->label()];
    +    label.push_back(' ');
    +  }
    +
    +  strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4",
    +                               prefix,
    +                               label,
    +                               field_type,
    +                               type() == TYPE_GROUP ? message_type()->name() :
    +                                                      name(),
    +                               number());
    +
    +  bool bracketed = false;
    +  if (has_default_value()) {
    +    bracketed = true;
    +    strings::SubstituteAndAppend(contents, " [default = $0",
    +                                 DefaultValueAsString(true));
    +  }
    +
    +  string formatted_options;
    +  if (FormatBracketedOptions(depth, options(), &formatted_options)) {
    +    contents->append(bracketed ? ", " : " [");
    +    bracketed = true;
    +    contents->append(formatted_options);
    +  }
    +
    +  if (bracketed) {
    +    contents->append("]");
    +  }
    +
    +  if (type() == TYPE_GROUP) {
    +    message_type()->DebugString(depth, contents);
    +  } else {
    +    contents->append(";\n");
    +  }
    +}
    +
    +string OneofDescriptor::DebugString() const {
    +  string contents;
    +  DebugString(0, &contents);
    +  return contents;
    +}
    +
    +void OneofDescriptor::DebugString(int depth, string* contents) const {
    +  string prefix(depth * 2, ' ');
    +  ++depth;
    +  strings::SubstituteAndAppend(
    +      contents, "$0 oneof $1 {\n", prefix, name());
    +  for (int i = 0; i < field_count(); i++) {
    +    field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents);
    +  }
    +  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
    +}
    +
    +string EnumDescriptor::DebugString() const {
    +  string contents;
    +  DebugString(0, &contents);
    +  return contents;
    +}
    +
    +void EnumDescriptor::DebugString(int depth, string *contents) const {
    +  string prefix(depth * 2, ' ');
    +  ++depth;
    +  strings::SubstituteAndAppend(contents, "$0enum $1 {\n",
    +                               prefix, name());
    +
    +  FormatLineOptions(depth, options(), contents);
    +
    +  for (int i = 0; i < value_count(); i++) {
    +    value(i)->DebugString(depth, contents);
    +  }
    +  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
    +}
    +
    +string EnumValueDescriptor::DebugString() const {
    +  string contents;
    +  DebugString(0, &contents);
    +  return contents;
    +}
    +
    +void EnumValueDescriptor::DebugString(int depth, string *contents) const {
    +  string prefix(depth * 2, ' ');
    +  strings::SubstituteAndAppend(contents, "$0$1 = $2",
    +                               prefix, name(), number());
    +
    +  string formatted_options;
    +  if (FormatBracketedOptions(depth, options(), &formatted_options)) {
    +    strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
    +  }
    +  contents->append(";\n");
    +}
    +
    +string ServiceDescriptor::DebugString() const {
    +  string contents;
    +  DebugString(&contents);
    +  return contents;
    +}
    +
    +void ServiceDescriptor::DebugString(string *contents) const {
    +  strings::SubstituteAndAppend(contents, "service $0 {\n", name());
    +
    +  FormatLineOptions(1, options(), contents);
    +
    +  for (int i = 0; i < method_count(); i++) {
    +    method(i)->DebugString(1, contents);
    +  }
    +
    +  contents->append("}\n");
    +}
    +
    +string MethodDescriptor::DebugString() const {
    +  string contents;
    +  DebugString(0, &contents);
    +  return contents;
    +}
    +
    +void MethodDescriptor::DebugString(int depth, string *contents) const {
    +  string prefix(depth * 2, ' ');
    +  ++depth;
    +  strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)",
    +                               prefix, name(),
    +                               input_type()->full_name(),
    +                               output_type()->full_name());
    +
    +  string formatted_options;
    +  if (FormatLineOptions(depth, options(), &formatted_options)) {
    +    strings::SubstituteAndAppend(contents, " {\n$0$1}\n",
    +                                 formatted_options, prefix);
    +  } else {
    +    contents->append(";\n");
    +  }
    +}
    +
    +
    +// Location methods ===============================================
    +
    +bool FileDescriptor::GetSourceLocation(const vector& path,
    +                                       SourceLocation* out_location) const {
    +  GOOGLE_CHECK_NOTNULL(out_location);
    +  if (source_code_info_) {
    +    if (const SourceCodeInfo_Location* loc =
    +        tables_->GetSourceLocation(path, source_code_info_)) {
    +      const RepeatedField& span = loc->span();
    +      if (span.size() == 3 || span.size() == 4) {
    +        out_location->start_line   = span.Get(0);
    +        out_location->start_column = span.Get(1);
    +        out_location->end_line     = span.Get(span.size() == 3 ? 0 : 2);
    +        out_location->end_column   = span.Get(span.size() - 1);
    +
    +        out_location->leading_comments = loc->leading_comments();
    +        out_location->trailing_comments = loc->trailing_comments();
    +        return true;
    +      }
    +    }
    +  }
    +  return false;
    +}
    +
    +bool FieldDescriptor::is_packed() const {
    +  return is_packable() && (options_ != NULL) && options_->packed();
    +}
    +
    +bool Descriptor::GetSourceLocation(SourceLocation* out_location) const {
    +  vector path;
    +  GetLocationPath(&path);
    +  return file()->GetSourceLocation(path, out_location);
    +}
    +
    +bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const {
    +  vector path;
    +  GetLocationPath(&path);
    +  return file()->GetSourceLocation(path, out_location);
    +}
    +
    +bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const {
    +  vector path;
    +  GetLocationPath(&path);
    +  return containing_type()->file()->GetSourceLocation(path, out_location);
    +}
    +
    +bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const {
    +  vector path;
    +  GetLocationPath(&path);
    +  return file()->GetSourceLocation(path, out_location);
    +}
    +
    +bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const {
    +  vector path;
    +  GetLocationPath(&path);
    +  return service()->file()->GetSourceLocation(path, out_location);
    +}
    +
    +bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const {
    +  vector path;
    +  GetLocationPath(&path);
    +  return file()->GetSourceLocation(path, out_location);
    +}
    +
    +bool EnumValueDescriptor::GetSourceLocation(
    +    SourceLocation* out_location) const {
    +  vector path;
    +  GetLocationPath(&path);
    +  return type()->file()->GetSourceLocation(path, out_location);
    +}
    +
    +void Descriptor::GetLocationPath(vector* output) const {
    +  if (containing_type()) {
    +    containing_type()->GetLocationPath(output);
    +    output->push_back(DescriptorProto::kNestedTypeFieldNumber);
    +    output->push_back(index());
    +  } else {
    +    output->push_back(FileDescriptorProto::kMessageTypeFieldNumber);
    +    output->push_back(index());
    +  }
    +}
    +
    +void FieldDescriptor::GetLocationPath(vector* output) const {
    +  if (is_extension()) {
    +    if (extension_scope() == NULL) {
    +      output->push_back(FileDescriptorProto::kExtensionFieldNumber);
    +      output->push_back(index());
    +    } else {
    +      extension_scope()->GetLocationPath(output);
    +      output->push_back(DescriptorProto::kExtensionFieldNumber);
    +      output->push_back(index());
    +    }
    +  } else {
    +    containing_type()->GetLocationPath(output);
    +    output->push_back(DescriptorProto::kFieldFieldNumber);
    +    output->push_back(index());
    +  }
    +}
    +
    +void OneofDescriptor::GetLocationPath(vector* output) const {
    +  containing_type()->GetLocationPath(output);
    +  output->push_back(DescriptorProto::kOneofDeclFieldNumber);
    +  output->push_back(index());
    +}
    +
    +void EnumDescriptor::GetLocationPath(vector* output) const {
    +  if (containing_type()) {
    +    containing_type()->GetLocationPath(output);
    +    output->push_back(DescriptorProto::kEnumTypeFieldNumber);
    +    output->push_back(index());
    +  } else {
    +    output->push_back(FileDescriptorProto::kEnumTypeFieldNumber);
    +    output->push_back(index());
    +  }
    +}
    +
    +void EnumValueDescriptor::GetLocationPath(vector* output) const {
    +  type()->GetLocationPath(output);
    +  output->push_back(EnumDescriptorProto::kValueFieldNumber);
    +  output->push_back(index());
    +}
    +
    +void ServiceDescriptor::GetLocationPath(vector* output) const {
    +  output->push_back(FileDescriptorProto::kServiceFieldNumber);
    +  output->push_back(index());
    +}
    +
    +void MethodDescriptor::GetLocationPath(vector* output) const {
    +  service()->GetLocationPath(output);
    +  output->push_back(ServiceDescriptorProto::kMethodFieldNumber);
    +  output->push_back(index());
    +}
    +
    +// ===================================================================
    +
    +namespace {
    +
    +// Represents an options message to interpret. Extension names in the option
    +// name are respolved relative to name_scope. element_name and orig_opt are
    +// used only for error reporting (since the parser records locations against
    +// pointers in the original options, not the mutable copy). The Message must be
    +// one of the Options messages in descriptor.proto.
    +struct OptionsToInterpret {
    +  OptionsToInterpret(const string& ns,
    +                     const string& el,
    +                     const Message* orig_opt,
    +                     Message* opt)
    +      : name_scope(ns),
    +        element_name(el),
    +        original_options(orig_opt),
    +        options(opt) {
    +  }
    +  string name_scope;
    +  string element_name;
    +  const Message* original_options;
    +  Message* options;
    +};
    +
    +}  // namespace
    +
    +class DescriptorBuilder {
    + public:
    +  DescriptorBuilder(const DescriptorPool* pool,
    +                    DescriptorPool::Tables* tables,
    +                    DescriptorPool::ErrorCollector* error_collector);
    +  ~DescriptorBuilder();
    +
    +  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
    +
    + private:
    +  friend class OptionInterpreter;
    +
    +  const DescriptorPool* pool_;
    +  DescriptorPool::Tables* tables_;  // for convenience
    +  DescriptorPool::ErrorCollector* error_collector_;
    +
    +  // As we build descriptors we store copies of the options messages in
    +  // them. We put pointers to those copies in this vector, as we build, so we
    +  // can later (after cross-linking) interpret those options.
    +  vector options_to_interpret_;
    +
    +  bool had_errors_;
    +  string filename_;
    +  FileDescriptor* file_;
    +  FileDescriptorTables* file_tables_;
    +  set dependencies_;
    +
    +  // unused_dependency_ is used to record the unused imported files.
    +  // Note: public import is not considered.
    +  set unused_dependency_;
    +
    +  // If LookupSymbol() finds a symbol that is in a file which is not a declared
    +  // dependency of this file, it will fail, but will set
    +  // possible_undeclared_dependency_ to point at that file.  This is only used
    +  // by AddNotDefinedError() to report a more useful error message.
    +  // possible_undeclared_dependency_name_ is the name of the symbol that was
    +  // actually found in possible_undeclared_dependency_, which may be a parent
    +  // of the symbol actually looked for.
    +  const FileDescriptor* possible_undeclared_dependency_;
    +  string possible_undeclared_dependency_name_;
    +
    +  // If LookupSymbol() could resolve a symbol which is not defined,
    +  // record the resolved name.  This is only used by AddNotDefinedError()
    +  // to report a more useful error message.
    +  string undefine_resolved_name_;
    +
    +  void AddError(const string& element_name,
    +                const Message& descriptor,
    +                DescriptorPool::ErrorCollector::ErrorLocation location,
    +                const string& error);
    +  void AddError(const string& element_name,
    +                const Message& descriptor,
    +                DescriptorPool::ErrorCollector::ErrorLocation location,
    +                const char* error);
    +  void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here);
    +  void AddTwiceListedError(const FileDescriptorProto& proto, int index);
    +  void AddImportError(const FileDescriptorProto& proto, int index);
    +
    +  // Adds an error indicating that undefined_symbol was not defined.  Must
    +  // only be called after LookupSymbol() fails.
    +  void AddNotDefinedError(
    +    const string& element_name,
    +    const Message& descriptor,
    +    DescriptorPool::ErrorCollector::ErrorLocation location,
    +    const string& undefined_symbol);
    +
    +  void AddWarning(const string& element_name, const Message& descriptor,
    +                  DescriptorPool::ErrorCollector::ErrorLocation location,
    +                  const string& error);
    +
    +  // Silly helper which determines if the given file is in the given package.
    +  // I.e., either file->package() == package_name or file->package() is a
    +  // nested package within package_name.
    +  bool IsInPackage(const FileDescriptor* file, const string& package_name);
    +
    +  // Helper function which finds all public dependencies of the given file, and
    +  // stores the them in the dependencies_ set in the builder.
    +  void RecordPublicDependencies(const FileDescriptor* file);
    +
    +  // Like tables_->FindSymbol(), but additionally:
    +  // - Search the pool's underlay if not found in tables_.
    +  // - Insure that the resulting Symbol is from one of the file's declared
    +  //   dependencies.
    +  Symbol FindSymbol(const string& name);
    +
    +  // Like FindSymbol() but does not require that the symbol is in one of the
    +  // file's declared dependencies.
    +  Symbol FindSymbolNotEnforcingDeps(const string& name);
    +
    +  // This implements the body of FindSymbolNotEnforcingDeps().
    +  Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
    +                                          const string& name);
    +
    +  // Like FindSymbol(), but looks up the name relative to some other symbol
    +  // name.  This first searches siblings of relative_to, then siblings of its
    +  // parents, etc.  For example, LookupSymbol("foo.bar", "baz.qux.corge") makes
    +  // the following calls, returning the first non-null result:
    +  // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"),
    +  // FindSymbol("foo.bar").  If AllowUnknownDependencies() has been called
    +  // on the DescriptorPool, this will generate a placeholder type if
    +  // the name is not found (unless the name itself is malformed).  The
    +  // placeholder_type parameter indicates what kind of placeholder should be
    +  // constructed in this case.  The resolve_mode parameter determines whether
    +  // any symbol is returned, or only symbols that are types.  Note, however,
    +  // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
    +  // if it believes that's all it could refer to.  The caller should always
    +  // check that it receives the type of symbol it was expecting.
    +  enum PlaceholderType {
    +    PLACEHOLDER_MESSAGE,
    +    PLACEHOLDER_ENUM,
    +    PLACEHOLDER_EXTENDABLE_MESSAGE
    +  };
    +  enum ResolveMode {
    +    LOOKUP_ALL, LOOKUP_TYPES
    +  };
    +  Symbol LookupSymbol(const string& name, const string& relative_to,
    +                      PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE,
    +                      ResolveMode resolve_mode = LOOKUP_ALL);
    +
    +  // Like LookupSymbol() but will not return a placeholder even if
    +  // AllowUnknownDependencies() has been used.
    +  Symbol LookupSymbolNoPlaceholder(const string& name,
    +                                   const string& relative_to,
    +                                   ResolveMode resolve_mode = LOOKUP_ALL);
    +
    +  // Creates a placeholder type suitable for return from LookupSymbol().  May
    +  // return kNullSymbol if the name is not a valid type name.
    +  Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type);
    +
    +  // Creates a placeholder file.  Never returns NULL.  This is used when an
    +  // import is not found and AllowUnknownDependencies() is enabled.
    +  const FileDescriptor* NewPlaceholderFile(const string& name);
    +
    +  // Calls tables_->AddSymbol() and records an error if it fails.  Returns
    +  // true if successful or false if failed, though most callers can ignore
    +  // the return value since an error has already been recorded.
    +  bool AddSymbol(const string& full_name,
    +                 const void* parent, const string& name,
    +                 const Message& proto, Symbol symbol);
    +
    +  // Like AddSymbol(), but succeeds if the symbol is already defined as long
    +  // as the existing definition is also a package (because it's OK to define
    +  // the same package in two different files).  Also adds all parents of the
    +  // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add
    +  // "foo.bar" and "foo" to the table).
    +  void AddPackage(const string& name, const Message& proto,
    +                  const FileDescriptor* file);
    +
    +  // Checks that the symbol name contains only alphanumeric characters and
    +  // underscores.  Records an error otherwise.
    +  void ValidateSymbolName(const string& name, const string& full_name,
    +                          const Message& proto);
    +
    +  // Like ValidateSymbolName(), but the name is allowed to contain periods and
    +  // an error is indicated by returning false (not recording the error).
    +  bool ValidateQualifiedName(const string& name);
    +
    +  // Used by BUILD_ARRAY macro (below) to avoid having to have the type
    +  // specified as a macro parameter.
    +  template 
    +  inline void AllocateArray(int size, Type** output) {
    +    *output = tables_->AllocateArray(size);
    +  }
    +
    +  // Allocates a copy of orig_options in tables_ and stores it in the
    +  // descriptor. Remembers its uninterpreted options, to be interpreted
    +  // later. DescriptorT must be one of the Descriptor messages from
    +  // descriptor.proto.
    +  template void AllocateOptions(
    +      const typename DescriptorT::OptionsType& orig_options,
    +      DescriptorT* descriptor);
    +  // Specialization for FileOptions.
    +  void AllocateOptions(const FileOptions& orig_options,
    +                       FileDescriptor* descriptor);
    +
    +  // Implementation for AllocateOptions(). Don't call this directly.
    +  template void AllocateOptionsImpl(
    +      const string& name_scope,
    +      const string& element_name,
    +      const typename DescriptorT::OptionsType& orig_options,
    +      DescriptorT* descriptor);
    +
    +  // These methods all have the same signature for the sake of the BUILD_ARRAY
    +  // macro, below.
    +  void BuildMessage(const DescriptorProto& proto,
    +                    const Descriptor* parent,
    +                    Descriptor* result);
    +  void BuildFieldOrExtension(const FieldDescriptorProto& proto,
    +                             const Descriptor* parent,
    +                             FieldDescriptor* result,
    +                             bool is_extension);
    +  void BuildField(const FieldDescriptorProto& proto,
    +                  const Descriptor* parent,
    +                  FieldDescriptor* result) {
    +    BuildFieldOrExtension(proto, parent, result, false);
    +  }
    +  void BuildExtension(const FieldDescriptorProto& proto,
    +                      const Descriptor* parent,
    +                      FieldDescriptor* result) {
    +    BuildFieldOrExtension(proto, parent, result, true);
    +  }
    +  void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
    +                           const Descriptor* parent,
    +                           Descriptor::ExtensionRange* result);
    +  void BuildOneof(const OneofDescriptorProto& proto,
    +                  Descriptor* parent,
    +                  OneofDescriptor* result);
    +  void BuildEnum(const EnumDescriptorProto& proto,
    +                 const Descriptor* parent,
    +                 EnumDescriptor* result);
    +  void BuildEnumValue(const EnumValueDescriptorProto& proto,
    +                      const EnumDescriptor* parent,
    +                      EnumValueDescriptor* result);
    +  void BuildService(const ServiceDescriptorProto& proto,
    +                    const void* dummy,
    +                    ServiceDescriptor* result);
    +  void BuildMethod(const MethodDescriptorProto& proto,
    +                   const ServiceDescriptor* parent,
    +                   MethodDescriptor* result);
    +
    +  void LogUnusedDependency(const FileDescriptor* result);
    +
    +  // Must be run only after building.
    +  //
    +  // NOTE: Options will not be available during cross-linking, as they
    +  // have not yet been interpreted. Defer any handling of options to the
    +  // Validate*Options methods.
    +  void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
    +  void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
    +  void CrossLinkField(FieldDescriptor* field,
    +                      const FieldDescriptorProto& proto);
    +  void CrossLinkEnum(EnumDescriptor* enum_type,
    +                     const EnumDescriptorProto& proto);
    +  void CrossLinkEnumValue(EnumValueDescriptor* enum_value,
    +                          const EnumValueDescriptorProto& proto);
    +  void CrossLinkService(ServiceDescriptor* service,
    +                        const ServiceDescriptorProto& proto);
    +  void CrossLinkMethod(MethodDescriptor* method,
    +                       const MethodDescriptorProto& proto);
    +
    +  // Must be run only after cross-linking.
    +  void InterpretOptions();
    +
    +  // A helper class for interpreting options.
    +  class OptionInterpreter {
    +   public:
    +    // Creates an interpreter that operates in the context of the pool of the
    +    // specified builder, which must not be NULL. We don't take ownership of the
    +    // builder.
    +    explicit OptionInterpreter(DescriptorBuilder* builder);
    +
    +    ~OptionInterpreter();
    +
    +    // Interprets the uninterpreted options in the specified Options message.
    +    // On error, calls AddError() on the underlying builder and returns false.
    +    // Otherwise returns true.
    +    bool InterpretOptions(OptionsToInterpret* options_to_interpret);
    +
    +    class AggregateOptionFinder;
    +
    +   private:
    +    // Interprets uninterpreted_option_ on the specified message, which
    +    // must be the mutable copy of the original options message to which
    +    // uninterpreted_option_ belongs.
    +    bool InterpretSingleOption(Message* options);
    +
    +    // Adds the uninterpreted_option to the given options message verbatim.
    +    // Used when AllowUnknownDependencies() is in effect and we can't find
    +    // the option's definition.
    +    void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option,
    +                                Message* options);
    +
    +    // A recursive helper function that drills into the intermediate fields
    +    // in unknown_fields to check if field innermost_field is set on the
    +    // innermost message. Returns false and sets an error if so.
    +    bool ExamineIfOptionIsSet(
    +        vector::const_iterator intermediate_fields_iter,
    +        vector::const_iterator intermediate_fields_end,
    +        const FieldDescriptor* innermost_field, const string& debug_msg_name,
    +        const UnknownFieldSet& unknown_fields);
    +
    +    // Validates the value for the option field of the currently interpreted
    +    // option and then sets it on the unknown_field.
    +    bool SetOptionValue(const FieldDescriptor* option_field,
    +                        UnknownFieldSet* unknown_fields);
    +
    +    // Parses an aggregate value for a CPPTYPE_MESSAGE option and
    +    // saves it into *unknown_fields.
    +    bool SetAggregateOption(const FieldDescriptor* option_field,
    +                            UnknownFieldSet* unknown_fields);
    +
    +    // Convenience functions to set an int field the right way, depending on
    +    // its wire type (a single int CppType can represent multiple wire types).
    +    void SetInt32(int number, int32 value, FieldDescriptor::Type type,
    +                  UnknownFieldSet* unknown_fields);
    +    void SetInt64(int number, int64 value, FieldDescriptor::Type type,
    +                  UnknownFieldSet* unknown_fields);
    +    void SetUInt32(int number, uint32 value, FieldDescriptor::Type type,
    +                   UnknownFieldSet* unknown_fields);
    +    void SetUInt64(int number, uint64 value, FieldDescriptor::Type type,
    +                   UnknownFieldSet* unknown_fields);
    +
    +    // A helper function that adds an error at the specified location of the
    +    // option we're currently interpreting, and returns false.
    +    bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location,
    +                        const string& msg) {
    +      builder_->AddError(options_to_interpret_->element_name,
    +                         *uninterpreted_option_, location, msg);
    +      return false;
    +    }
    +
    +    // A helper function that adds an error at the location of the option name
    +    // and returns false.
    +    bool AddNameError(const string& msg) {
    +      return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg);
    +    }
    +
    +    // A helper function that adds an error at the location of the option name
    +    // and returns false.
    +    bool AddValueError(const string& msg) {
    +      return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg);
    +    }
    +
    +    // We interpret against this builder's pool. Is never NULL. We don't own
    +    // this pointer.
    +    DescriptorBuilder* builder_;
    +
    +    // The options we're currently interpreting, or NULL if we're not in a call
    +    // to InterpretOptions.
    +    const OptionsToInterpret* options_to_interpret_;
    +
    +    // The option we're currently interpreting within options_to_interpret_, or
    +    // NULL if we're not in a call to InterpretOptions(). This points to a
    +    // submessage of the original option, not the mutable copy. Therefore we
    +    // can use it to find locations recorded by the parser.
    +    const UninterpretedOption* uninterpreted_option_;
    +
    +    // Factory used to create the dynamic messages we need to parse
    +    // any aggregate option values we encounter.
    +    DynamicMessageFactory dynamic_factory_;
    +
    +    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter);
    +  };
    +
    +  // Work-around for broken compilers:  According to the C++ standard,
    +  // OptionInterpreter should have access to the private members of any class
    +  // which has declared DescriptorBuilder as a friend.  Unfortunately some old
    +  // versions of GCC and other compilers do not implement this correctly.  So,
    +  // we have to have these intermediate methods to provide access.  We also
    +  // redundantly declare OptionInterpreter a friend just to make things extra
    +  // clear for these bad compilers.
    +  friend class OptionInterpreter;
    +  friend class OptionInterpreter::AggregateOptionFinder;
    +
    +  static inline bool get_allow_unknown(const DescriptorPool* pool) {
    +    return pool->allow_unknown_;
    +  }
    +  static inline bool get_enforce_weak(const DescriptorPool* pool) {
    +    return pool->enforce_weak_;
    +  }
    +  static inline bool get_is_placeholder(const Descriptor* descriptor) {
    +    return descriptor->is_placeholder_;
    +  }
    +  static inline void assert_mutex_held(const DescriptorPool* pool) {
    +    if (pool->mutex_ != NULL) {
    +      pool->mutex_->AssertHeld();
    +    }
    +  }
    +
    +  // Must be run only after options have been interpreted.
    +  //
    +  // NOTE: Validation code must only reference the options in the mutable
    +  // descriptors, which are the ones that have been interpreted. The const
    +  // proto references are passed in only so they can be provided to calls to
    +  // AddError(). Do not look at their options, which have not been interpreted.
    +  void ValidateFileOptions(FileDescriptor* file,
    +                           const FileDescriptorProto& proto);
    +  void ValidateMessageOptions(Descriptor* message,
    +                              const DescriptorProto& proto);
    +  void ValidateFieldOptions(FieldDescriptor* field,
    +                            const FieldDescriptorProto& proto);
    +  void ValidateEnumOptions(EnumDescriptor* enm,
    +                           const EnumDescriptorProto& proto);
    +  void ValidateEnumValueOptions(EnumValueDescriptor* enum_value,
    +                                const EnumValueDescriptorProto& proto);
    +  void ValidateServiceOptions(ServiceDescriptor* service,
    +                              const ServiceDescriptorProto& proto);
    +  void ValidateMethodOptions(MethodDescriptor* method,
    +                             const MethodDescriptorProto& proto);
    +
    +  void ValidateMapKey(FieldDescriptor* field,
    +                      const FieldDescriptorProto& proto);
    +
    +};
    +
    +const FileDescriptor* DescriptorPool::BuildFile(
    +    const FileDescriptorProto& proto) {
    +  GOOGLE_CHECK(fallback_database_ == NULL)
    +    << "Cannot call BuildFile on a DescriptorPool that uses a "
    +       "DescriptorDatabase.  You must instead find a way to get your file "
    +       "into the underlying database.";
    +  GOOGLE_CHECK(mutex_ == NULL);   // Implied by the above GOOGLE_CHECK.
    +  tables_->known_bad_symbols_.clear();
    +  tables_->known_bad_files_.clear();
    +  return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto);
    +}
    +
    +const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
    +    const FileDescriptorProto& proto,
    +    ErrorCollector* error_collector) {
    +  GOOGLE_CHECK(fallback_database_ == NULL)
    +    << "Cannot call BuildFile on a DescriptorPool that uses a "
    +       "DescriptorDatabase.  You must instead find a way to get your file "
    +       "into the underlying database.";
    +  GOOGLE_CHECK(mutex_ == NULL);   // Implied by the above GOOGLE_CHECK.
    +  tables_->known_bad_symbols_.clear();
    +  tables_->known_bad_files_.clear();
    +  return DescriptorBuilder(this, tables_.get(),
    +                           error_collector).BuildFile(proto);
    +}
    +
    +const FileDescriptor* DescriptorPool::BuildFileFromDatabase(
    +    const FileDescriptorProto& proto) const {
    +  mutex_->AssertHeld();
    +  if (tables_->known_bad_files_.count(proto.name()) > 0) {
    +    return NULL;
    +  }
    +  const FileDescriptor* result =
    +      DescriptorBuilder(this, tables_.get(),
    +                        default_error_collector_).BuildFile(proto);
    +  if (result == NULL) {
    +    tables_->known_bad_files_.insert(proto.name());
    +  }
    +  return result;
    +}
    +
    +DescriptorBuilder::DescriptorBuilder(
    +    const DescriptorPool* pool,
    +    DescriptorPool::Tables* tables,
    +    DescriptorPool::ErrorCollector* error_collector)
    +  : pool_(pool),
    +    tables_(tables),
    +    error_collector_(error_collector),
    +    had_errors_(false),
    +    possible_undeclared_dependency_(NULL),
    +    undefine_resolved_name_("") {}
    +
    +DescriptorBuilder::~DescriptorBuilder() {}
    +
    +void DescriptorBuilder::AddError(
    +    const string& element_name,
    +    const Message& descriptor,
    +    DescriptorPool::ErrorCollector::ErrorLocation location,
    +    const string& error) {
    +  if (error_collector_ == NULL) {
    +    if (!had_errors_) {
    +      GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_
    +                 << "\":";
    +    }
    +    GOOGLE_LOG(ERROR) << "  " << element_name << ": " << error;
    +  } else {
    +    error_collector_->AddError(filename_, element_name,
    +                               &descriptor, location, error);
    +  }
    +  had_errors_ = true;
    +}
    +
    +void DescriptorBuilder::AddError(
    +    const string& element_name,
    +    const Message& descriptor,
    +    DescriptorPool::ErrorCollector::ErrorLocation location,
    +    const char* error) {
    +  AddError(element_name, descriptor, location, string(error));
    +}
    +
    +void DescriptorBuilder::AddNotDefinedError(
    +    const string& element_name,
    +    const Message& descriptor,
    +    DescriptorPool::ErrorCollector::ErrorLocation location,
    +    const string& undefined_symbol) {
    +  if (possible_undeclared_dependency_ == NULL &&
    +      undefine_resolved_name_.empty()) {
    +    AddError(element_name, descriptor, location,
    +             "\"" + undefined_symbol + "\" is not defined.");
    +  } else {
    +    if (possible_undeclared_dependency_ != NULL) {
    +      AddError(element_name, descriptor, location,
    +               "\"" + possible_undeclared_dependency_name_ +
    +               "\" seems to be defined in \"" +
    +               possible_undeclared_dependency_->name() + "\", which is not "
    +               "imported by \"" + filename_ + "\".  To use it here, please "
    +               "add the necessary import.");
    +    }
    +    if (!undefine_resolved_name_.empty()) {
    +      AddError(element_name, descriptor, location,
    +               "\"" + undefined_symbol + "\" is resolved to \"" +
    +               undefine_resolved_name_ + "\", which is not defined. "
    +               "The innermost scope is searched first in name resolution. "
    +               "Consider using a leading '.'(i.e., \"."
    +               + undefined_symbol +
    +               "\") to start from the outermost scope.");
    +    }
    +  }
    +}
    +
    +void DescriptorBuilder::AddWarning(
    +    const string& element_name, const Message& descriptor,
    +    DescriptorPool::ErrorCollector::ErrorLocation location,
    +    const string& error) {
    +  if (error_collector_ == NULL) {
    +    GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error;
    +  } else {
    +    error_collector_->AddWarning(filename_, element_name, &descriptor, location,
    +                                 error);
    +  }
    +}
    +
    +bool DescriptorBuilder::IsInPackage(const FileDescriptor* file,
    +                                    const string& package_name) {
    +  return HasPrefixString(file->package(), package_name) &&
    +           (file->package().size() == package_name.size() ||
    +            file->package()[package_name.size()] == '.');
    +}
    +
    +void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) {
    +  if (file == NULL || !dependencies_.insert(file).second) return;
    +  for (int i = 0; file != NULL && i < file->public_dependency_count(); i++) {
    +    RecordPublicDependencies(file->public_dependency(i));
    +  }
    +}
    +
    +Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper(
    +    const DescriptorPool* pool, const string& name) {
    +  // If we are looking at an underlay, we must lock its mutex_, since we are
    +  // accessing the underlay's tables_ directly.
    +  MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_);
    +
    +  Symbol result = pool->tables_->FindSymbol(name);
    +  if (result.IsNull() && pool->underlay_ != NULL) {
    +    // Symbol not found; check the underlay.
    +    result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name);
    +  }
    +
    +  if (result.IsNull()) {
    +    // In theory, we shouldn't need to check fallback_database_ because the
    +    // symbol should be in one of its file's direct dependencies, and we have
    +    // already loaded those by the time we get here.  But we check anyway so
    +    // that we can generate better error message when dependencies are missing
    +    // (i.e., "missing dependency" rather than "type is not defined").
    +    if (pool->TryFindSymbolInFallbackDatabase(name)) {
    +      result = pool->tables_->FindSymbol(name);
    +    }
    +  }
    +
    +  return result;
    +}
    +
    +Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) {
    +  return FindSymbolNotEnforcingDepsHelper(pool_, name);
    +}
    +
    +Symbol DescriptorBuilder::FindSymbol(const string& name) {
    +  Symbol result = FindSymbolNotEnforcingDeps(name);
    +
    +  if (result.IsNull()) return result;
    +
    +  if (!pool_->enforce_dependencies_) {
    +    // Hack for CompilerUpgrader.
    +    return result;
    +  }
    +
    +  // Only find symbols which were defined in this file or one of its
    +  // dependencies.
    +  const FileDescriptor* file = result.GetFile();
    +  if (file == file_ || dependencies_.count(file) > 0) {
    +    unused_dependency_.erase(file);
    +    return result;
    +  }
    +
    +  if (result.type == Symbol::PACKAGE) {
    +    // Arg, this is overcomplicated.  The symbol is a package name.  It could
    +    // be that the package was defined in multiple files.  result.GetFile()
    +    // returns the first file we saw that used this package.  We've determined
    +    // that that file is not a direct dependency of the file we are currently
    +    // building, but it could be that some other file which *is* a direct
    +    // dependency also defines the same package.  We can't really rule out this
    +    // symbol unless none of the dependencies define it.
    +    if (IsInPackage(file_, name)) return result;
    +    for (set::const_iterator it = dependencies_.begin();
    +         it != dependencies_.end(); ++it) {
    +      // Note:  A dependency may be NULL if it was not found or had errors.
    +      if (*it != NULL && IsInPackage(*it, name)) return result;
    +    }
    +  }
    +
    +  possible_undeclared_dependency_ = file;
    +  possible_undeclared_dependency_name_ = name;
    +  return kNullSymbol;
    +}
    +
    +Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
    +    const string& name, const string& relative_to, ResolveMode resolve_mode) {
    +  possible_undeclared_dependency_ = NULL;
    +  undefine_resolved_name_.clear();
    +
    +  if (name.size() > 0 && name[0] == '.') {
    +    // Fully-qualified name.
    +    return FindSymbol(name.substr(1));
    +  }
    +
    +  // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
    +  // defined in multiple parent scopes, we only want to find "Bar.baz" in the
    +  // innermost one.  E.g., the following should produce an error:
    +  //   message Bar { message Baz {} }
    +  //   message Foo {
    +  //     message Bar {
    +  //     }
    +  //     optional Bar.Baz baz = 1;
    +  //   }
    +  // So, we look for just "Foo" first, then look for "Bar.baz" within it if
    +  // found.
    +  string::size_type name_dot_pos = name.find_first_of('.');
    +  string first_part_of_name;
    +  if (name_dot_pos == string::npos) {
    +    first_part_of_name = name;
    +  } else {
    +    first_part_of_name = name.substr(0, name_dot_pos);
    +  }
    +
    +  string scope_to_try(relative_to);
    +
    +  while (true) {
    +    // Chop off the last component of the scope.
    +    string::size_type dot_pos = scope_to_try.find_last_of('.');
    +    if (dot_pos == string::npos) {
    +      return FindSymbol(name);
    +    } else {
    +      scope_to_try.erase(dot_pos);
    +    }
    +
    +    // Append ".first_part_of_name" and try to find.
    +    string::size_type old_size = scope_to_try.size();
    +    scope_to_try.append(1, '.');
    +    scope_to_try.append(first_part_of_name);
    +    Symbol result = FindSymbol(scope_to_try);
    +    if (!result.IsNull()) {
    +      if (first_part_of_name.size() < name.size()) {
    +        // name is a compound symbol, of which we only found the first part.
    +        // Now try to look up the rest of it.
    +        if (result.IsAggregate()) {
    +          scope_to_try.append(name, first_part_of_name.size(),
    +                              name.size() - first_part_of_name.size());
    +          result = FindSymbol(scope_to_try);
    +          if (result.IsNull()) {
    +            undefine_resolved_name_ = scope_to_try;
    +          }
    +          return result;
    +        } else {
    +          // We found a symbol but it's not an aggregate.  Continue the loop.
    +        }
    +      } else {
    +        if (resolve_mode == LOOKUP_TYPES && !result.IsType()) {
    +          // We found a symbol but it's not a type.  Continue the loop.
    +        } else {
    +          return result;
    +        }
    +      }
    +    }
    +
    +    // Not found.  Remove the name so we can try again.
    +    scope_to_try.erase(old_size);
    +  }
    +}
    +
    +Symbol DescriptorBuilder::LookupSymbol(
    +    const string& name, const string& relative_to,
    +    PlaceholderType placeholder_type, ResolveMode resolve_mode) {
    +  Symbol result = LookupSymbolNoPlaceholder(
    +      name, relative_to, resolve_mode);
    +  if (result.IsNull() && pool_->allow_unknown_) {
    +    // Not found, but AllowUnknownDependencies() is enabled.  Return a
    +    // placeholder instead.
    +    result = NewPlaceholder(name, placeholder_type);
    +  }
    +  return result;
    +}
    +
    +Symbol DescriptorBuilder::NewPlaceholder(const string& name,
    +                                         PlaceholderType placeholder_type) {
    +  // Compute names.
    +  const string* placeholder_full_name;
    +  const string* placeholder_name;
    +  const string* placeholder_package;
    +
    +  if (!ValidateQualifiedName(name)) return kNullSymbol;
    +  if (name[0] == '.') {
    +    // Fully-qualified.
    +    placeholder_full_name = tables_->AllocateString(name.substr(1));
    +  } else {
    +    placeholder_full_name = tables_->AllocateString(name);
    +  }
    +
    +  string::size_type dotpos = placeholder_full_name->find_last_of('.');
    +  if (dotpos != string::npos) {
    +    placeholder_package = tables_->AllocateString(
    +      placeholder_full_name->substr(0, dotpos));
    +    placeholder_name = tables_->AllocateString(
    +      placeholder_full_name->substr(dotpos + 1));
    +  } else {
    +    placeholder_package = &internal::GetEmptyString();
    +    placeholder_name = placeholder_full_name;
    +  }
    +
    +  // Create the placeholders.
    +  FileDescriptor* placeholder_file = tables_->Allocate();
    +  memset(placeholder_file, 0, sizeof(*placeholder_file));
    +
    +  placeholder_file->source_code_info_ = &SourceCodeInfo::default_instance();
    +
    +  placeholder_file->name_ =
    +    tables_->AllocateString(*placeholder_full_name + ".placeholder.proto");
    +  placeholder_file->package_ = placeholder_package;
    +  placeholder_file->pool_ = pool_;
    +  placeholder_file->options_ = &FileOptions::default_instance();
    +  placeholder_file->tables_ = &FileDescriptorTables::kEmpty;
    +  placeholder_file->is_placeholder_ = true;
    +  // All other fields are zero or NULL.
    +
    +  if (placeholder_type == PLACEHOLDER_ENUM) {
    +    placeholder_file->enum_type_count_ = 1;
    +    placeholder_file->enum_types_ =
    +      tables_->AllocateArray(1);
    +
    +    EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0];
    +    memset(placeholder_enum, 0, sizeof(*placeholder_enum));
    +
    +    placeholder_enum->full_name_ = placeholder_full_name;
    +    placeholder_enum->name_ = placeholder_name;
    +    placeholder_enum->file_ = placeholder_file;
    +    placeholder_enum->options_ = &EnumOptions::default_instance();
    +    placeholder_enum->is_placeholder_ = true;
    +    placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
    +
    +    // Enums must have at least one value.
    +    placeholder_enum->value_count_ = 1;
    +    placeholder_enum->values_ = tables_->AllocateArray(1);
    +
    +    EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
    +    memset(placeholder_value, 0, sizeof(*placeholder_value));
    +
    +    placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE");
    +    // Note that enum value names are siblings of their type, not children.
    +    placeholder_value->full_name_ =
    +      placeholder_package->empty() ? placeholder_value->name_ :
    +        tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE");
    +
    +    placeholder_value->number_ = 0;
    +    placeholder_value->type_ = placeholder_enum;
    +    placeholder_value->options_ = &EnumValueOptions::default_instance();
    +
    +    return Symbol(placeholder_enum);
    +  } else {
    +    placeholder_file->message_type_count_ = 1;
    +    placeholder_file->message_types_ =
    +      tables_->AllocateArray(1);
    +
    +    Descriptor* placeholder_message = &placeholder_file->message_types_[0];
    +    memset(placeholder_message, 0, sizeof(*placeholder_message));
    +
    +    placeholder_message->full_name_ = placeholder_full_name;
    +    placeholder_message->name_ = placeholder_name;
    +    placeholder_message->file_ = placeholder_file;
    +    placeholder_message->options_ = &MessageOptions::default_instance();
    +    placeholder_message->is_placeholder_ = true;
    +    placeholder_message->is_unqualified_placeholder_ = (name[0] != '.');
    +
    +    if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
    +      placeholder_message->extension_range_count_ = 1;
    +      placeholder_message->extension_ranges_ =
    +        tables_->AllocateArray(1);
    +      placeholder_message->extension_ranges_->start = 1;
    +      // kMaxNumber + 1 because ExtensionRange::end is exclusive.
    +      placeholder_message->extension_ranges_->end =
    +        FieldDescriptor::kMaxNumber + 1;
    +    }
    +
    +    return Symbol(placeholder_message);
    +  }
    +}
    +
    +const FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
    +    const string& name) {
    +  FileDescriptor* placeholder = tables_->Allocate();
    +  memset(placeholder, 0, sizeof(*placeholder));
    +
    +  placeholder->name_ = tables_->AllocateString(name);
    +  placeholder->package_ = &internal::GetEmptyString();
    +  placeholder->pool_ = pool_;
    +  placeholder->options_ = &FileOptions::default_instance();
    +  placeholder->tables_ = &FileDescriptorTables::kEmpty;
    +  placeholder->is_placeholder_ = true;
    +  // All other fields are zero or NULL.
    +
    +  return placeholder;
    +}
    +
    +bool DescriptorBuilder::AddSymbol(
    +    const string& full_name, const void* parent, const string& name,
    +    const Message& proto, Symbol symbol) {
    +  // If the caller passed NULL for the parent, the symbol is at file scope.
    +  // Use its file as the parent instead.
    +  if (parent == NULL) parent = file_;
    +
    +  if (tables_->AddSymbol(full_name, symbol)) {
    +    if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) {
    +      GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in "
    +                     "symbols_by_name_, but was defined in symbols_by_parent_; "
    +                     "this shouldn't be possible.";
    +      return false;
    +    }
    +    return true;
    +  } else {
    +    const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile();
    +    if (other_file == file_) {
    +      string::size_type dot_pos = full_name.find_last_of('.');
    +      if (dot_pos == string::npos) {
    +        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
    +                 "\"" + full_name + "\" is already defined.");
    +      } else {
    +        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
    +                 "\"" + full_name.substr(dot_pos + 1) +
    +                 "\" is already defined in \"" +
    +                 full_name.substr(0, dot_pos) + "\".");
    +      }
    +    } else {
    +      // Symbol seems to have been defined in a different file.
    +      AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
    +               "\"" + full_name + "\" is already defined in file \"" +
    +               other_file->name() + "\".");
    +    }
    +    return false;
    +  }
    +}
    +
    +void DescriptorBuilder::AddPackage(
    +    const string& name, const Message& proto, const FileDescriptor* file) {
    +  if (tables_->AddSymbol(name, Symbol(file))) {
    +    // Success.  Also add parent package, if any.
    +    string::size_type dot_pos = name.find_last_of('.');
    +    if (dot_pos == string::npos) {
    +      // No parents.
    +      ValidateSymbolName(name, name, proto);
    +    } else {
    +      // Has parent.
    +      string* parent_name = tables_->AllocateString(name.substr(0, dot_pos));
    +      AddPackage(*parent_name, proto, file);
    +      ValidateSymbolName(name.substr(dot_pos + 1), name, proto);
    +    }
    +  } else {
    +    Symbol existing_symbol = tables_->FindSymbol(name);
    +    // It's OK to redefine a package.
    +    if (existing_symbol.type != Symbol::PACKAGE) {
    +      // Symbol seems to have been defined in a different file.
    +      AddError(name, proto, DescriptorPool::ErrorCollector::NAME,
    +               "\"" + name + "\" is already defined (as something other than "
    +               "a package) in file \"" + existing_symbol.GetFile()->name() +
    +               "\".");
    +    }
    +  }
    +}
    +
    +void DescriptorBuilder::ValidateSymbolName(
    +    const string& name, const string& full_name, const Message& proto) {
    +  if (name.empty()) {
    +    AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
    +             "Missing name.");
    +  } else {
    +    for (int i = 0; i < name.size(); i++) {
    +      // I don't trust isalnum() due to locales.  :(
    +      if ((name[i] < 'a' || 'z' < name[i]) &&
    +          (name[i] < 'A' || 'Z' < name[i]) &&
    +          (name[i] < '0' || '9' < name[i]) &&
    +          (name[i] != '_')) {
    +        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
    +                 "\"" + name + "\" is not a valid identifier.");
    +      }
    +    }
    +  }
    +}
    +
    +bool DescriptorBuilder::ValidateQualifiedName(const string& name) {
    +  bool last_was_period = false;
    +
    +  for (int i = 0; i < name.size(); i++) {
    +    // I don't trust isalnum() due to locales.  :(
    +    if (('a' <= name[i] && name[i] <= 'z') ||
    +        ('A' <= name[i] && name[i] <= 'Z') ||
    +        ('0' <= name[i] && name[i] <= '9') ||
    +        (name[i] == '_')) {
    +      last_was_period = false;
    +    } else if (name[i] == '.') {
    +      if (last_was_period) return false;
    +      last_was_period = true;
    +    } else {
    +      return false;
    +    }
    +  }
    +
    +  return !name.empty() && !last_was_period;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// This generic implementation is good for all descriptors except
    +// FileDescriptor.
    +template void DescriptorBuilder::AllocateOptions(
    +    const typename DescriptorT::OptionsType& orig_options,
    +    DescriptorT* descriptor) {
    +  AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(),
    +                      orig_options, descriptor);
    +}
    +
    +// We specialize for FileDescriptor.
    +void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options,
    +                                        FileDescriptor* descriptor) {
    +  // We add the dummy token so that LookupSymbol does the right thing.
    +  AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(),
    +                      orig_options, descriptor);
    +}
    +
    +template void DescriptorBuilder::AllocateOptionsImpl(
    +    const string& name_scope,
    +    const string& element_name,
    +    const typename DescriptorT::OptionsType& orig_options,
    +    DescriptorT* descriptor) {
    +  // We need to use a dummy pointer to work around a bug in older versions of
    +  // GCC.  Otherwise, the following two lines could be replaced with:
    +  //   typename DescriptorT::OptionsType* options =
    +  //       tables_->AllocateMessage();
    +  typename DescriptorT::OptionsType* const dummy = NULL;
    +  typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
    +  // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
    +  // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the
    +  // reflection based method, which requires the Descriptor. However, we are in
    +  // the middle of building the descriptors, thus the deadlock.
    +  options->ParseFromString(orig_options.SerializeAsString());
    +  descriptor->options_ = options;
    +
    +  // Don't add to options_to_interpret_ unless there were uninterpreted
    +  // options.  This not only avoids unnecessary work, but prevents a
    +  // bootstrapping problem when building descriptors for descriptor.proto.
    +  // descriptor.proto does not contain any uninterpreted options, but
    +  // attempting to interpret options anyway will cause
    +  // OptionsType::GetDescriptor() to be called which may then deadlock since
    +  // we're still trying to build it.
    +  if (options->uninterpreted_option_size() > 0) {
    +    options_to_interpret_.push_back(
    +        OptionsToInterpret(name_scope, element_name, &orig_options, options));
    +  }
    +}
    +
    +
    +// A common pattern:  We want to convert a repeated field in the descriptor
    +// to an array of values, calling some method to build each value.
    +#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT)             \
    +  OUTPUT->NAME##_count_ = INPUT.NAME##_size();                       \
    +  AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_);             \
    +  for (int i = 0; i < INPUT.NAME##_size(); i++) {                    \
    +    METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i);             \
    +  }
    +
    +void DescriptorBuilder::AddRecursiveImportError(
    +    const FileDescriptorProto& proto, int from_here) {
    +  string error_message("File recursively imports itself: ");
    +  for (int i = from_here; i < tables_->pending_files_.size(); i++) {
    +    error_message.append(tables_->pending_files_[i]);
    +    error_message.append(" -> ");
    +  }
    +  error_message.append(proto.name());
    +
    +  AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
    +           error_message);
    +}
    +
    +void DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto,
    +                                            int index) {
    +  AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
    +           "Import \"" + proto.dependency(index) + "\" was listed twice.");
    +}
    +
    +void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto,
    +                                       int index) {
    +  string message;
    +  if (pool_->fallback_database_ == NULL) {
    +    message = "Import \"" + proto.dependency(index) +
    +              "\" has not been loaded.";
    +  } else {
    +    message = "Import \"" + proto.dependency(index) +
    +              "\" was not found or had errors.";
    +  }
    +  AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, message);
    +}
    +
    +static bool ExistingFileMatchesProto(const FileDescriptor* existing_file,
    +                                     const FileDescriptorProto& proto) {
    +  FileDescriptorProto existing_proto;
    +  existing_file->CopyTo(&existing_proto);
    +  return existing_proto.SerializeAsString() == proto.SerializeAsString();
    +}
    +
    +const FileDescriptor* DescriptorBuilder::BuildFile(
    +    const FileDescriptorProto& proto) {
    +  filename_ = proto.name();
    +
    +  // Check if the file already exists and is identical to the one being built.
    +  // Note:  This only works if the input is canonical -- that is, it
    +  //   fully-qualifies all type names, has no UninterpretedOptions, etc.
    +  //   This is fine, because this idempotency "feature" really only exists to
    +  //   accomodate one hack in the proto1->proto2 migration layer.
    +  const FileDescriptor* existing_file = tables_->FindFile(filename_);
    +  if (existing_file != NULL) {
    +    // File already in pool.  Compare the existing one to the input.
    +    if (ExistingFileMatchesProto(existing_file, proto)) {
    +      // They're identical.  Return the existing descriptor.
    +      return existing_file;
    +    }
    +
    +    // Not a match.  The error will be detected and handled later.
    +  }
    +
    +  // Check to see if this file is already on the pending files list.
    +  // TODO(kenton):  Allow recursive imports?  It may not work with some
    +  //   (most?) programming languages.  E.g., in C++, a forward declaration
    +  //   of a type is not sufficient to allow it to be used even in a
    +  //   generated header file due to inlining.  This could perhaps be
    +  //   worked around using tricks involving inserting #include statements
    +  //   mid-file, but that's pretty ugly, and I'm pretty sure there are
    +  //   some languages out there that do not allow recursive dependencies
    +  //   at all.
    +  for (int i = 0; i < tables_->pending_files_.size(); i++) {
    +    if (tables_->pending_files_[i] == proto.name()) {
    +      AddRecursiveImportError(proto, i);
    +      return NULL;
    +    }
    +  }
    +
    +  // If we have a fallback_database_, attempt to load all dependencies now,
    +  // before checkpointing tables_.  This avoids confusion with recursive
    +  // checkpoints.
    +  if (pool_->fallback_database_ != NULL) {
    +    tables_->pending_files_.push_back(proto.name());
    +    for (int i = 0; i < proto.dependency_size(); i++) {
    +      if (tables_->FindFile(proto.dependency(i)) == NULL &&
    +          (pool_->underlay_ == NULL ||
    +           pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) {
    +        // We don't care what this returns since we'll find out below anyway.
    +        pool_->TryFindFileInFallbackDatabase(proto.dependency(i));
    +      }
    +    }
    +    tables_->pending_files_.pop_back();
    +  }
    +
    +  // Checkpoint the tables so that we can roll back if something goes wrong.
    +  tables_->AddCheckpoint();
    +
    +  FileDescriptor* result = tables_->Allocate();
    +  file_ = result;
    +
    +  result->is_placeholder_ = false;
    +  if (proto.has_source_code_info()) {
    +    SourceCodeInfo *info = tables_->AllocateMessage();
    +    info->CopyFrom(proto.source_code_info());
    +    result->source_code_info_ = info;
    +  } else {
    +    result->source_code_info_ = &SourceCodeInfo::default_instance();
    +  }
    +
    +  file_tables_ = tables_->AllocateFileTables();
    +  file_->tables_ = file_tables_;
    +
    +  if (!proto.has_name()) {
    +    AddError("", proto, DescriptorPool::ErrorCollector::OTHER,
    +             "Missing field: FileDescriptorProto.name.");
    +  }
    +
    +  result->name_ = tables_->AllocateString(proto.name());
    +  if (proto.has_package()) {
    +    result->package_ = tables_->AllocateString(proto.package());
    +  } else {
    +    // We cannot rely on proto.package() returning a valid string if
    +    // proto.has_package() is false, because we might be running at static
    +    // initialization time, in which case default values have not yet been
    +    // initialized.
    +    result->package_ = tables_->AllocateString("");
    +  }
    +  result->pool_ = pool_;
    +
    +  // Add to tables.
    +  if (!tables_->AddFile(result)) {
    +    AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
    +             "A file with this name is already in the pool.");
    +    // Bail out early so that if this is actually the exact same file, we
    +    // don't end up reporting that every single symbol is already defined.
    +    tables_->RollbackToLastCheckpoint();
    +    return NULL;
    +  }
    +  if (!result->package().empty()) {
    +    AddPackage(result->package(), proto, result);
    +  }
    +
    +  // Make sure all dependencies are loaded.
    +  set seen_dependencies;
    +  result->dependency_count_ = proto.dependency_size();
    +  result->dependencies_ =
    +    tables_->AllocateArray(proto.dependency_size());
    +  unused_dependency_.clear();
    +  set weak_deps;
    +  for (int i = 0; i < proto.weak_dependency_size(); ++i) {
    +    weak_deps.insert(proto.weak_dependency(i));
    +  }
    +  for (int i = 0; i < proto.dependency_size(); i++) {
    +    if (!seen_dependencies.insert(proto.dependency(i)).second) {
    +      AddTwiceListedError(proto, i);
    +    }
    +
    +    const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
    +    if (dependency == NULL && pool_->underlay_ != NULL) {
    +      dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
    +    }
    +
    +    if (dependency == NULL) {
    +      if (pool_->allow_unknown_ ||
    +          (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
    +        dependency = NewPlaceholderFile(proto.dependency(i));
    +      } else {
    +        AddImportError(proto, i);
    +      }
    +    } else {
    +      // Add to unused_dependency_ to track unused imported files.
    +      // Note: do not track unused imported files for public import.
    +      if (pool_->enforce_dependencies_ &&
    +          (pool_->unused_import_track_files_.find(proto.name()) !=
    +           pool_->unused_import_track_files_.end()) &&
    +          (dependency->public_dependency_count() == 0)) {
    +        unused_dependency_.insert(dependency);
    +      }
    +    }
    +
    +    result->dependencies_[i] = dependency;
    +  }
    +
    +  // Check public dependencies.
    +  int public_dependency_count = 0;
    +  result->public_dependencies_ = tables_->AllocateArray(
    +      proto.public_dependency_size());
    +  for (int i = 0; i < proto.public_dependency_size(); i++) {
    +    // Only put valid public dependency indexes.
    +    int index = proto.public_dependency(i);
    +    if (index >= 0 && index < proto.dependency_size()) {
    +      result->public_dependencies_[public_dependency_count++] = index;
    +      // Do not track unused imported files for public import.
    +      unused_dependency_.erase(result->dependency(index));
    +    } else {
    +      AddError(proto.name(), proto,
    +               DescriptorPool::ErrorCollector::OTHER,
    +               "Invalid public dependency index.");
    +    }
    +  }
    +  result->public_dependency_count_ = public_dependency_count;
    +
    +  // Build dependency set
    +  dependencies_.clear();
    +  for (int i = 0; i < result->dependency_count(); i++) {
    +    RecordPublicDependencies(result->dependency(i));
    +  }
    +
    +  // Check weak dependencies.
    +  int weak_dependency_count = 0;
    +  result->weak_dependencies_ = tables_->AllocateArray(
    +      proto.weak_dependency_size());
    +  for (int i = 0; i < proto.weak_dependency_size(); i++) {
    +    int index = proto.weak_dependency(i);
    +    if (index >= 0 && index < proto.dependency_size()) {
    +      result->weak_dependencies_[weak_dependency_count++] = index;
    +    } else {
    +      AddError(proto.name(), proto,
    +               DescriptorPool::ErrorCollector::OTHER,
    +               "Invalid weak dependency index.");
    +    }
    +  }
    +  result->weak_dependency_count_ = weak_dependency_count;
    +
    +  // Convert children.
    +  BUILD_ARRAY(proto, result, message_type, BuildMessage  , NULL);
    +  BUILD_ARRAY(proto, result, enum_type   , BuildEnum     , NULL);
    +  BUILD_ARRAY(proto, result, service     , BuildService  , NULL);
    +  BUILD_ARRAY(proto, result, extension   , BuildExtension, NULL);
    +
    +  // Copy options.
    +  if (!proto.has_options()) {
    +    result->options_ = NULL;  // Will set to default_instance later.
    +  } else {
    +    AllocateOptions(proto.options(), result);
    +  }
    +
    +  // Note that the following steps must occur in exactly the specified order.
    +
    +  // Cross-link.
    +  CrossLinkFile(result, proto);
    +
    +  // Interpret any remaining uninterpreted options gathered into
    +  // options_to_interpret_ during descriptor building.  Cross-linking has made
    +  // extension options known, so all interpretations should now succeed.
    +  if (!had_errors_) {
    +    OptionInterpreter option_interpreter(this);
    +    for (vector::iterator iter =
    +             options_to_interpret_.begin();
    +         iter != options_to_interpret_.end(); ++iter) {
    +      option_interpreter.InterpretOptions(&(*iter));
    +    }
    +    options_to_interpret_.clear();
    +  }
    +
    +  // Validate options.
    +  if (!had_errors_) {
    +    ValidateFileOptions(result, proto);
    +  }
    +
    +
    +  if (!unused_dependency_.empty()) {
    +    LogUnusedDependency(result);
    +  }
    +
    +  if (had_errors_) {
    +    tables_->RollbackToLastCheckpoint();
    +    return NULL;
    +  } else {
    +    tables_->ClearLastCheckpoint();
    +    return result;
    +  }
    +}
    +
    +void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
    +                                     const Descriptor* parent,
    +                                     Descriptor* result) {
    +  const string& scope = (parent == NULL) ?
    +    file_->package() : parent->full_name();
    +  string* full_name = tables_->AllocateString(scope);
    +  if (!full_name->empty()) full_name->append(1, '.');
    +  full_name->append(proto.name());
    +
    +  ValidateSymbolName(proto.name(), *full_name, proto);
    +
    +  result->name_            = tables_->AllocateString(proto.name());
    +  result->full_name_       = full_name;
    +  result->file_            = file_;
    +  result->containing_type_ = parent;
    +  result->is_placeholder_  = false;
    +  result->is_unqualified_placeholder_ = false;
    +
    +  // Build oneofs first so that fields and extension ranges can refer to them.
    +  BUILD_ARRAY(proto, result, oneof_decl     , BuildOneof         , result);
    +  BUILD_ARRAY(proto, result, field          , BuildField         , result);
    +  BUILD_ARRAY(proto, result, nested_type    , BuildMessage       , result);
    +  BUILD_ARRAY(proto, result, enum_type      , BuildEnum          , result);
    +  BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
    +  BUILD_ARRAY(proto, result, extension      , BuildExtension     , result);
    +
    +  // Copy options.
    +  if (!proto.has_options()) {
    +    result->options_ = NULL;  // Will set to default_instance later.
    +  } else {
    +    AllocateOptions(proto.options(), result);
    +  }
    +
    +  AddSymbol(result->full_name(), parent, result->name(),
    +            proto, Symbol(result));
    +
    +  // Check that no fields have numbers in extension ranges.
    +  for (int i = 0; i < result->field_count(); i++) {
    +    const FieldDescriptor* field = result->field(i);
    +    for (int j = 0; j < result->extension_range_count(); j++) {
    +      const Descriptor::ExtensionRange* range = result->extension_range(j);
    +      if (range->start <= field->number() && field->number() < range->end) {
    +        AddError(field->full_name(), proto.extension_range(j),
    +                 DescriptorPool::ErrorCollector::NUMBER,
    +                 strings::Substitute(
    +                   "Extension range $0 to $1 includes field \"$2\" ($3).",
    +                   range->start, range->end - 1,
    +                   field->name(), field->number()));
    +      }
    +    }
    +  }
    +
    +  // Check that extension ranges don't overlap.
    +  for (int i = 0; i < result->extension_range_count(); i++) {
    +    const Descriptor::ExtensionRange* range1 = result->extension_range(i);
    +    for (int j = i + 1; j < result->extension_range_count(); j++) {
    +      const Descriptor::ExtensionRange* range2 = result->extension_range(j);
    +      if (range1->end > range2->start && range2->end > range1->start) {
    +        AddError(result->full_name(), proto.extension_range(j),
    +                 DescriptorPool::ErrorCollector::NUMBER,
    +                 strings::Substitute("Extension range $0 to $1 overlaps with "
    +                                     "already-defined range $2 to $3.",
    +                                     range2->start, range2->end - 1,
    +                                     range1->start, range1->end - 1));
    +      }
    +    }
    +  }
    +}
    +
    +void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
    +                                              const Descriptor* parent,
    +                                              FieldDescriptor* result,
    +                                              bool is_extension) {
    +  const string& scope = (parent == NULL) ?
    +    file_->package() : parent->full_name();
    +  string* full_name = tables_->AllocateString(scope);
    +  if (!full_name->empty()) full_name->append(1, '.');
    +  full_name->append(proto.name());
    +
    +  ValidateSymbolName(proto.name(), *full_name, proto);
    +
    +  result->name_         = tables_->AllocateString(proto.name());
    +  result->full_name_    = full_name;
    +  result->file_         = file_;
    +  result->number_       = proto.number();
    +  result->is_extension_ = is_extension;
    +
    +  // If .proto files follow the style guide then the name should already be
    +  // lower-cased.  If that's the case we can just reuse the string we already
    +  // allocated rather than allocate a new one.
    +  string lowercase_name(proto.name());
    +  LowerString(&lowercase_name);
    +  if (lowercase_name == proto.name()) {
    +    result->lowercase_name_ = result->name_;
    +  } else {
    +    result->lowercase_name_ = tables_->AllocateString(lowercase_name);
    +  }
    +
    +  // Don't bother with the above optimization for camel-case names since
    +  // .proto files that follow the guide shouldn't be using names in this
    +  // format, so the optimization wouldn't help much.
    +  result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name()));
    +
    +  // Some compilers do not allow static_cast directly between two enum types,
    +  // so we must cast to int first.
    +  result->type_  = static_cast(
    +                     implicit_cast(proto.type()));
    +  result->label_ = static_cast(
    +                     implicit_cast(proto.label()));
    +
    +  // An extension cannot have a required field (b/13365836).
    +  if (result->is_extension_ &&
    +      result->label_ == FieldDescriptor::LABEL_REQUIRED) {
    +    AddError(result->full_name(), proto,
    +             // Error location `TYPE`: we would really like to indicate
    +             // `LABEL`, but the `ErrorLocation` enum has no entry for this, and
    +             // we don't necessarily know about all implementations of the
    +             // `ErrorCollector` interface to extend them to handle the new
    +             // error location type properly.
    +             DescriptorPool::ErrorCollector::TYPE,
    +             "Message extensions cannot have required fields.");
    +  }
    +
    +  // Some of these may be filled in when cross-linking.
    +  result->containing_type_ = NULL;
    +  result->extension_scope_ = NULL;
    +  result->experimental_map_key_ = NULL;
    +  result->message_type_ = NULL;
    +  result->enum_type_ = NULL;
    +
    +  result->has_default_value_ = proto.has_default_value();
    +  if (proto.has_default_value() && result->is_repeated()) {
    +    AddError(result->full_name(), proto,
    +             DescriptorPool::ErrorCollector::DEFAULT_VALUE,
    +             "Repeated fields can't have default values.");
    +  }
    +
    +  if (proto.has_type()) {
    +    if (proto.has_default_value()) {
    +      char* end_pos = NULL;
    +      switch (result->cpp_type()) {
    +        case FieldDescriptor::CPPTYPE_INT32:
    +          result->default_value_int32_ =
    +            strtol(proto.default_value().c_str(), &end_pos, 0);
    +          break;
    +        case FieldDescriptor::CPPTYPE_INT64:
    +          result->default_value_int64_ =
    +            strto64(proto.default_value().c_str(), &end_pos, 0);
    +          break;
    +        case FieldDescriptor::CPPTYPE_UINT32:
    +          result->default_value_uint32_ =
    +            strtoul(proto.default_value().c_str(), &end_pos, 0);
    +          break;
    +        case FieldDescriptor::CPPTYPE_UINT64:
    +          result->default_value_uint64_ =
    +            strtou64(proto.default_value().c_str(), &end_pos, 0);
    +          break;
    +        case FieldDescriptor::CPPTYPE_FLOAT:
    +          if (proto.default_value() == "inf") {
    +            result->default_value_float_ = numeric_limits::infinity();
    +          } else if (proto.default_value() == "-inf") {
    +            result->default_value_float_ = -numeric_limits::infinity();
    +          } else if (proto.default_value() == "nan") {
    +            result->default_value_float_ = numeric_limits::quiet_NaN();
    +          } else  {
    +            result->default_value_float_ =
    +              io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
    +          }
    +          break;
    +        case FieldDescriptor::CPPTYPE_DOUBLE:
    +          if (proto.default_value() == "inf") {
    +            result->default_value_double_ = numeric_limits::infinity();
    +          } else if (proto.default_value() == "-inf") {
    +            result->default_value_double_ = -numeric_limits::infinity();
    +          } else if (proto.default_value() == "nan") {
    +            result->default_value_double_ = numeric_limits::quiet_NaN();
    +          } else  {
    +            result->default_value_double_ =
    +                io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
    +          }
    +          break;
    +        case FieldDescriptor::CPPTYPE_BOOL:
    +          if (proto.default_value() == "true") {
    +            result->default_value_bool_ = true;
    +          } else if (proto.default_value() == "false") {
    +            result->default_value_bool_ = false;
    +          } else {
    +            AddError(result->full_name(), proto,
    +                     DescriptorPool::ErrorCollector::DEFAULT_VALUE,
    +                     "Boolean default must be true or false.");
    +          }
    +          break;
    +        case FieldDescriptor::CPPTYPE_ENUM:
    +          // This will be filled in when cross-linking.
    +          result->default_value_enum_ = NULL;
    +          break;
    +        case FieldDescriptor::CPPTYPE_STRING:
    +          if (result->type() == FieldDescriptor::TYPE_BYTES) {
    +            result->default_value_string_ = tables_->AllocateString(
    +              UnescapeCEscapeString(proto.default_value()));
    +          } else {
    +            result->default_value_string_ =
    +                tables_->AllocateString(proto.default_value());
    +          }
    +          break;
    +        case FieldDescriptor::CPPTYPE_MESSAGE:
    +          AddError(result->full_name(), proto,
    +                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
    +                   "Messages can't have default values.");
    +          result->has_default_value_ = false;
    +          break;
    +      }
    +
    +      if (end_pos != NULL) {
    +        // end_pos is only set non-NULL by the parsers for numeric types, above.
    +        // This checks that the default was non-empty and had no extra junk
    +        // after the end of the number.
    +        if (proto.default_value().empty() || *end_pos != '\0') {
    +          AddError(result->full_name(), proto,
    +                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
    +                   "Couldn't parse default value \"" + proto.default_value() +
    +                   "\".");
    +        }
    +      }
    +    } else {
    +      // No explicit default value
    +      switch (result->cpp_type()) {
    +        case FieldDescriptor::CPPTYPE_INT32:
    +          result->default_value_int32_ = 0;
    +          break;
    +        case FieldDescriptor::CPPTYPE_INT64:
    +          result->default_value_int64_ = 0;
    +          break;
    +        case FieldDescriptor::CPPTYPE_UINT32:
    +          result->default_value_uint32_ = 0;
    +          break;
    +        case FieldDescriptor::CPPTYPE_UINT64:
    +          result->default_value_uint64_ = 0;
    +          break;
    +        case FieldDescriptor::CPPTYPE_FLOAT:
    +          result->default_value_float_ = 0.0f;
    +          break;
    +        case FieldDescriptor::CPPTYPE_DOUBLE:
    +          result->default_value_double_ = 0.0;
    +          break;
    +        case FieldDescriptor::CPPTYPE_BOOL:
    +          result->default_value_bool_ = false;
    +          break;
    +        case FieldDescriptor::CPPTYPE_ENUM:
    +          // This will be filled in when cross-linking.
    +          result->default_value_enum_ = NULL;
    +          break;
    +        case FieldDescriptor::CPPTYPE_STRING:
    +          result->default_value_string_ = &internal::GetEmptyString();
    +          break;
    +        case FieldDescriptor::CPPTYPE_MESSAGE:
    +          break;
    +      }
    +    }
    +  }
    +
    +  if (result->number() <= 0) {
    +    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
    +             "Field numbers must be positive integers.");
    +  } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) {
    +    // Only validate that the number is within the valid field range if it is
    +    // not an extension. Since extension numbers are validated with the
    +    // extendee's valid set of extension numbers, and those are in turn
    +    // validated against the max allowed number, the check is unnecessary for
    +    // extension fields.
    +    // This avoids cross-linking issues that arise when attempting to check if
    +    // the extendee is a message_set_wire_format message, which has a higher max
    +    // on extension numbers.
    +    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
    +             strings::Substitute("Field numbers cannot be greater than $0.",
    +                                 FieldDescriptor::kMaxNumber));
    +  } else if (result->number() >= FieldDescriptor::kFirstReservedNumber &&
    +             result->number() <= FieldDescriptor::kLastReservedNumber) {
    +    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
    +             strings::Substitute(
    +               "Field numbers $0 through $1 are reserved for the protocol "
    +               "buffer library implementation.",
    +               FieldDescriptor::kFirstReservedNumber,
    +               FieldDescriptor::kLastReservedNumber));
    +  }
    +
    +  if (is_extension) {
    +    if (!proto.has_extendee()) {
    +      AddError(result->full_name(), proto,
    +               DescriptorPool::ErrorCollector::EXTENDEE,
    +               "FieldDescriptorProto.extendee not set for extension field.");
    +    }
    +
    +    result->extension_scope_ = parent;
    +
    +    if (proto.has_oneof_index()) {
    +      AddError(result->full_name(), proto,
    +               DescriptorPool::ErrorCollector::OTHER,
    +               "FieldDescriptorProto.oneof_index should not be set for "
    +               "extensions.");
    +    }
    +
    +    // Fill in later (maybe).
    +    result->containing_oneof_ = NULL;
    +  } else {
    +    if (proto.has_extendee()) {
    +      AddError(result->full_name(), proto,
    +               DescriptorPool::ErrorCollector::EXTENDEE,
    +               "FieldDescriptorProto.extendee set for non-extension field.");
    +    }
    +
    +    result->containing_type_ = parent;
    +
    +    if (proto.has_oneof_index()) {
    +      if (proto.oneof_index() < 0 ||
    +          proto.oneof_index() >= parent->oneof_decl_count()) {
    +        AddError(result->full_name(), proto,
    +                 DescriptorPool::ErrorCollector::OTHER,
    +                 strings::Substitute("FieldDescriptorProto.oneof_index $0 is "
    +                                     "out of range for type \"$1\".",
    +                                     proto.oneof_index(),
    +                                     parent->name()));
    +        result->containing_oneof_ = NULL;
    +      } else {
    +        result->containing_oneof_ = parent->oneof_decl(proto.oneof_index());
    +      }
    +    } else {
    +      result->containing_oneof_ = NULL;
    +    }
    +  }
    +
    +  // Copy options.
    +  if (!proto.has_options()) {
    +    result->options_ = NULL;  // Will set to default_instance later.
    +  } else {
    +    AllocateOptions(proto.options(), result);
    +  }
    +
    +  AddSymbol(result->full_name(), parent, result->name(),
    +            proto, Symbol(result));
    +}
    +
    +void DescriptorBuilder::BuildExtensionRange(
    +    const DescriptorProto::ExtensionRange& proto,
    +    const Descriptor* parent,
    +    Descriptor::ExtensionRange* result) {
    +  result->start = proto.start();
    +  result->end = proto.end();
    +  if (result->start <= 0) {
    +    AddError(parent->full_name(), proto,
    +             DescriptorPool::ErrorCollector::NUMBER,
    +             "Extension numbers must be positive integers.");
    +  }
    +
    +  // Checking of the upper bound of the extension range is deferred until after
    +  // options interpreting. This allows messages with message_set_wire_format to
    +  // have extensions beyond FieldDescriptor::kMaxNumber, since the extension
    +  // numbers are actually used as int32s in the message_set_wire_format.
    +
    +  if (result->start >= result->end) {
    +    AddError(parent->full_name(), proto,
    +             DescriptorPool::ErrorCollector::NUMBER,
    +             "Extension range end number must be greater than start number.");
    +  }
    +}
    +
    +void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto,
    +                                   Descriptor* parent,
    +                                   OneofDescriptor* result) {
    +  string* full_name = tables_->AllocateString(parent->full_name());
    +  full_name->append(1, '.');
    +  full_name->append(proto.name());
    +
    +  ValidateSymbolName(proto.name(), *full_name, proto);
    +
    +  result->name_ = tables_->AllocateString(proto.name());
    +  result->full_name_ = full_name;
    +
    +  result->containing_type_ = parent;
    +
    +  // We need to fill these in later.
    +  result->field_count_ = 0;
    +  result->fields_ = NULL;
    +
    +  AddSymbol(result->full_name(), parent, result->name(),
    +            proto, Symbol(result));
    +}
    +
    +void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
    +                                  const Descriptor* parent,
    +                                  EnumDescriptor* result) {
    +  const string& scope = (parent == NULL) ?
    +    file_->package() : parent->full_name();
    +  string* full_name = tables_->AllocateString(scope);
    +  if (!full_name->empty()) full_name->append(1, '.');
    +  full_name->append(proto.name());
    +
    +  ValidateSymbolName(proto.name(), *full_name, proto);
    +
    +  result->name_            = tables_->AllocateString(proto.name());
    +  result->full_name_       = full_name;
    +  result->file_            = file_;
    +  result->containing_type_ = parent;
    +  result->is_placeholder_  = false;
    +  result->is_unqualified_placeholder_ = false;
    +
    +  if (proto.value_size() == 0) {
    +    // We cannot allow enums with no values because this would mean there
    +    // would be no valid default value for fields of this type.
    +    AddError(result->full_name(), proto,
    +             DescriptorPool::ErrorCollector::NAME,
    +             "Enums must contain at least one value.");
    +  }
    +
    +  BUILD_ARRAY(proto, result, value, BuildEnumValue, result);
    +
    +  // Copy options.
    +  if (!proto.has_options()) {
    +    result->options_ = NULL;  // Will set to default_instance later.
    +  } else {
    +    AllocateOptions(proto.options(), result);
    +  }
    +
    +  AddSymbol(result->full_name(), parent, result->name(),
    +            proto, Symbol(result));
    +}
    +
    +void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto,
    +                                       const EnumDescriptor* parent,
    +                                       EnumValueDescriptor* result) {
    +  result->name_   = tables_->AllocateString(proto.name());
    +  result->number_ = proto.number();
    +  result->type_   = parent;
    +
    +  // Note:  full_name for enum values is a sibling to the parent's name, not a
    +  //   child of it.
    +  string* full_name = tables_->AllocateString(*parent->full_name_);
    +  full_name->resize(full_name->size() - parent->name_->size());
    +  full_name->append(*result->name_);
    +  result->full_name_ = full_name;
    +
    +  ValidateSymbolName(proto.name(), *full_name, proto);
    +
    +  // Copy options.
    +  if (!proto.has_options()) {
    +    result->options_ = NULL;  // Will set to default_instance later.
    +  } else {
    +    AllocateOptions(proto.options(), result);
    +  }
    +
    +  // Again, enum values are weird because we makes them appear as siblings
    +  // of the enum type instead of children of it.  So, we use
    +  // parent->containing_type() as the value's parent.
    +  bool added_to_outer_scope =
    +    AddSymbol(result->full_name(), parent->containing_type(), result->name(),
    +              proto, Symbol(result));
    +
    +  // However, we also want to be able to search for values within a single
    +  // enum type, so we add it as a child of the enum type itself, too.
    +  // Note:  This could fail, but if it does, the error has already been
    +  //   reported by the above AddSymbol() call, so we ignore the return code.
    +  bool added_to_inner_scope =
    +    file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result));
    +
    +  if (added_to_inner_scope && !added_to_outer_scope) {
    +    // This value did not conflict with any values defined in the same enum,
    +    // but it did conflict with some other symbol defined in the enum type's
    +    // scope.  Let's print an additional error to explain this.
    +    string outer_scope;
    +    if (parent->containing_type() == NULL) {
    +      outer_scope = file_->package();
    +    } else {
    +      outer_scope = parent->containing_type()->full_name();
    +    }
    +
    +    if (outer_scope.empty()) {
    +      outer_scope = "the global scope";
    +    } else {
    +      outer_scope = "\"" + outer_scope + "\"";
    +    }
    +
    +    AddError(result->full_name(), proto,
    +             DescriptorPool::ErrorCollector::NAME,
    +             "Note that enum values use C++ scoping rules, meaning that "
    +             "enum values are siblings of their type, not children of it.  "
    +             "Therefore, \"" + result->name() + "\" must be unique within "
    +             + outer_scope + ", not just within \"" + parent->name() + "\".");
    +  }
    +
    +  // An enum is allowed to define two numbers that refer to the same value.
    +  // FindValueByNumber() should return the first such value, so we simply
    +  // ignore AddEnumValueByNumber()'s return code.
    +  file_tables_->AddEnumValueByNumber(result);
    +}
    +
    +void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto,
    +                                     const void* /* dummy */,
    +                                     ServiceDescriptor* result) {
    +  string* full_name = tables_->AllocateString(file_->package());
    +  if (!full_name->empty()) full_name->append(1, '.');
    +  full_name->append(proto.name());
    +
    +  ValidateSymbolName(proto.name(), *full_name, proto);
    +
    +  result->name_      = tables_->AllocateString(proto.name());
    +  result->full_name_ = full_name;
    +  result->file_      = file_;
    +
    +  BUILD_ARRAY(proto, result, method, BuildMethod, result);
    +
    +  // Copy options.
    +  if (!proto.has_options()) {
    +    result->options_ = NULL;  // Will set to default_instance later.
    +  } else {
    +    AllocateOptions(proto.options(), result);
    +  }
    +
    +  AddSymbol(result->full_name(), NULL, result->name(),
    +            proto, Symbol(result));
    +}
    +
    +void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
    +                                    const ServiceDescriptor* parent,
    +                                    MethodDescriptor* result) {
    +  result->name_    = tables_->AllocateString(proto.name());
    +  result->service_ = parent;
    +
    +  string* full_name = tables_->AllocateString(parent->full_name());
    +  full_name->append(1, '.');
    +  full_name->append(*result->name_);
    +  result->full_name_ = full_name;
    +
    +  ValidateSymbolName(proto.name(), *full_name, proto);
    +
    +  // These will be filled in when cross-linking.
    +  result->input_type_ = NULL;
    +  result->output_type_ = NULL;
    +
    +  // Copy options.
    +  if (!proto.has_options()) {
    +    result->options_ = NULL;  // Will set to default_instance later.
    +  } else {
    +    AllocateOptions(proto.options(), result);
    +  }
    +
    +  AddSymbol(result->full_name(), parent, result->name(),
    +            proto, Symbol(result));
    +}
    +
    +#undef BUILD_ARRAY
    +
    +// -------------------------------------------------------------------
    +
    +void DescriptorBuilder::CrossLinkFile(
    +    FileDescriptor* file, const FileDescriptorProto& proto) {
    +  if (file->options_ == NULL) {
    +    file->options_ = &FileOptions::default_instance();
    +  }
    +
    +  for (int i = 0; i < file->message_type_count(); i++) {
    +    CrossLinkMessage(&file->message_types_[i], proto.message_type(i));
    +  }
    +
    +  for (int i = 0; i < file->extension_count(); i++) {
    +    CrossLinkField(&file->extensions_[i], proto.extension(i));
    +  }
    +
    +  for (int i = 0; i < file->enum_type_count(); i++) {
    +    CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i));
    +  }
    +
    +  for (int i = 0; i < file->service_count(); i++) {
    +    CrossLinkService(&file->services_[i], proto.service(i));
    +  }
    +}
    +
    +void DescriptorBuilder::CrossLinkMessage(
    +    Descriptor* message, const DescriptorProto& proto) {
    +  if (message->options_ == NULL) {
    +    message->options_ = &MessageOptions::default_instance();
    +  }
    +
    +  for (int i = 0; i < message->nested_type_count(); i++) {
    +    CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i));
    +  }
    +
    +  for (int i = 0; i < message->enum_type_count(); i++) {
    +    CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i));
    +  }
    +
    +  for (int i = 0; i < message->field_count(); i++) {
    +    CrossLinkField(&message->fields_[i], proto.field(i));
    +  }
    +
    +  for (int i = 0; i < message->extension_count(); i++) {
    +    CrossLinkField(&message->extensions_[i], proto.extension(i));
    +  }
    +
    +  // Set up field array for each oneof.
    +
    +  // First count the number of fields per oneof.
    +  for (int i = 0; i < message->field_count(); i++) {
    +    const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
    +    if (oneof_decl != NULL) {
    +      // Must go through oneof_decls_ array to get a non-const version of the
    +      // OneofDescriptor.
    +      ++message->oneof_decls_[oneof_decl->index()].field_count_;
    +    }
    +  }
    +
    +  // Then allocate the arrays.
    +  for (int i = 0; i < message->oneof_decl_count(); i++) {
    +    OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
    +
    +    if (oneof_decl->field_count() == 0) {
    +      AddError(message->full_name() + "." + oneof_decl->name(),
    +               proto.oneof_decl(i),
    +               DescriptorPool::ErrorCollector::NAME,
    +               "Oneof must have at least one field.");
    +    }
    +
    +    oneof_decl->fields_ =
    +      tables_->AllocateArray(oneof_decl->field_count_);
    +    oneof_decl->field_count_ = 0;
    +  }
    +
    +  // Then fill them in.
    +  for (int i = 0; i < message->field_count(); i++) {
    +    const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
    +    if (oneof_decl != NULL) {
    +      OneofDescriptor* mutable_oneof_decl =
    +          &message->oneof_decls_[oneof_decl->index()];
    +      message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_;
    +      mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] =
    +          message->field(i);
    +    }
    +  }
    +}
    +
    +void DescriptorBuilder::CrossLinkField(
    +    FieldDescriptor* field, const FieldDescriptorProto& proto) {
    +  if (field->options_ == NULL) {
    +    field->options_ = &FieldOptions::default_instance();
    +  }
    +
    +  if (proto.has_extendee()) {
    +    Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(),
    +                                   PLACEHOLDER_EXTENDABLE_MESSAGE);
    +    if (extendee.IsNull()) {
    +      AddNotDefinedError(field->full_name(), proto,
    +                         DescriptorPool::ErrorCollector::EXTENDEE,
    +                         proto.extendee());
    +      return;
    +    } else if (extendee.type != Symbol::MESSAGE) {
    +      AddError(field->full_name(), proto,
    +               DescriptorPool::ErrorCollector::EXTENDEE,
    +               "\"" + proto.extendee() + "\" is not a message type.");
    +      return;
    +    }
    +    field->containing_type_ = extendee.descriptor;
    +
    +    const Descriptor::ExtensionRange* extension_range = field->containing_type()
    +        ->FindExtensionRangeContainingNumber(field->number());
    +
    +    if (extension_range == NULL) {
    +      AddError(field->full_name(), proto,
    +               DescriptorPool::ErrorCollector::NUMBER,
    +               strings::Substitute("\"$0\" does not declare $1 as an "
    +                                   "extension number.",
    +                                   field->containing_type()->full_name(),
    +                                   field->number()));
    +    }
    +  }
    +
    +  if (field->containing_oneof() != NULL) {
    +    if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
    +      // Note that this error will never happen when parsing .proto files.
    +      // It can only happen if you manually construct a FileDescriptorProto
    +      // that is incorrect.
    +      AddError(field->full_name(), proto,
    +               DescriptorPool::ErrorCollector::NAME,
    +               "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
    +    }
    +  }
    +
    +  if (proto.has_type_name()) {
    +    // Assume we are expecting a message type unless the proto contains some
    +    // evidence that it expects an enum type.  This only makes a difference if
    +    // we end up creating a placeholder.
    +    bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) ||
    +                          proto.has_default_value();
    +
    +    Symbol type =
    +      LookupSymbol(proto.type_name(), field->full_name(),
    +                   expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE,
    +                   LOOKUP_TYPES);
    +
    +    // If the type is a weak type, we change the type to a google.protobuf.Empty field.
    +    if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) {
    +      type = FindSymbol(kNonLinkedWeakMessageReplacementName);
    +    }
    +
    +    if (type.IsNull()) {
    +      AddNotDefinedError(field->full_name(), proto,
    +                         DescriptorPool::ErrorCollector::TYPE,
    +                         proto.type_name());
    +      return;
    +    }
    +
    +    if (!proto.has_type()) {
    +      // Choose field type based on symbol.
    +      if (type.type == Symbol::MESSAGE) {
    +        field->type_ = FieldDescriptor::TYPE_MESSAGE;
    +      } else if (type.type == Symbol::ENUM) {
    +        field->type_ = FieldDescriptor::TYPE_ENUM;
    +      } else {
    +        AddError(field->full_name(), proto,
    +                 DescriptorPool::ErrorCollector::TYPE,
    +                 "\"" + proto.type_name() + "\" is not a type.");
    +        return;
    +      }
    +    }
    +
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      if (type.type != Symbol::MESSAGE) {
    +        AddError(field->full_name(), proto,
    +                 DescriptorPool::ErrorCollector::TYPE,
    +                 "\"" + proto.type_name() + "\" is not a message type.");
    +        return;
    +      }
    +      field->message_type_ = type.descriptor;
    +
    +      if (field->has_default_value()) {
    +        AddError(field->full_name(), proto,
    +                 DescriptorPool::ErrorCollector::DEFAULT_VALUE,
    +                 "Messages can't have default values.");
    +      }
    +    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
    +      if (type.type != Symbol::ENUM) {
    +        AddError(field->full_name(), proto,
    +                 DescriptorPool::ErrorCollector::TYPE,
    +                 "\"" + proto.type_name() + "\" is not an enum type.");
    +        return;
    +      }
    +      field->enum_type_ = type.enum_descriptor;
    +
    +      if (field->enum_type()->is_placeholder_) {
    +        // We can't look up default values for placeholder types.  We'll have
    +        // to just drop them.
    +        field->has_default_value_ = false;
    +      }
    +
    +      if (field->has_default_value()) {
    +        // Ensure that the default value is an identifier. Parser cannot always
    +        // verify this because it does not have complete type information.
    +        // N.B. that this check yields better error messages but is not
    +        // necessary for correctness (an enum symbol must be a valid identifier
    +        // anyway), only for better errors.
    +        if (!io::Tokenizer::IsIdentifier(proto.default_value())) {
    +          AddError(field->full_name(), proto,
    +                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
    +                   "Default value for an enum field must be an identifier.");
    +        } else {
    +          // We can't just use field->enum_type()->FindValueByName() here
    +          // because that locks the pool's mutex, which we have already locked
    +          // at this point.
    +          Symbol default_value =
    +            LookupSymbolNoPlaceholder(proto.default_value(),
    +                                      field->enum_type()->full_name());
    +
    +          if (default_value.type == Symbol::ENUM_VALUE &&
    +              default_value.enum_value_descriptor->type() ==
    +              field->enum_type()) {
    +            field->default_value_enum_ = default_value.enum_value_descriptor;
    +          } else {
    +            AddError(field->full_name(), proto,
    +                     DescriptorPool::ErrorCollector::DEFAULT_VALUE,
    +                     "Enum type \"" + field->enum_type()->full_name() +
    +                     "\" has no value named \"" + proto.default_value() +
    +                     "\".");
    +          }
    +        }
    +      } else if (field->enum_type()->value_count() > 0) {
    +        // All enums must have at least one value, or we would have reported
    +        // an error elsewhere.  We use the first defined value as the default
    +        // if a default is not explicitly defined.
    +        field->default_value_enum_ = field->enum_type()->value(0);
    +      }
    +    } else {
    +      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +               "Field with primitive type has type_name.");
    +    }
    +  } else {
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
    +        field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
    +      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +               "Field with message or enum type missing type_name.");
    +    }
    +  }
    +
    +  // Add the field to the fields-by-number table.
    +  // Note:  We have to do this *after* cross-linking because extensions do not
    +  //   know their containing type until now.
    +  if (!file_tables_->AddFieldByNumber(field)) {
    +    const FieldDescriptor* conflicting_field =
    +      file_tables_->FindFieldByNumber(field->containing_type(),
    +                                      field->number());
    +    if (field->is_extension()) {
    +      AddError(field->full_name(), proto,
    +               DescriptorPool::ErrorCollector::NUMBER,
    +               strings::Substitute("Extension number $0 has already been used "
    +                                   "in \"$1\" by extension \"$2\".",
    +                                   field->number(),
    +                                   field->containing_type()->full_name(),
    +                                   conflicting_field->full_name()));
    +    } else {
    +      AddError(field->full_name(), proto,
    +               DescriptorPool::ErrorCollector::NUMBER,
    +               strings::Substitute("Field number $0 has already been used in "
    +                                   "\"$1\" by field \"$2\".",
    +                                   field->number(),
    +                                   field->containing_type()->full_name(),
    +                                   conflicting_field->name()));
    +    }
    +  } else {
    +    if (field->is_extension()) {
    +      if (!tables_->AddExtension(field)) {
    +        const FieldDescriptor* conflicting_field =
    +            tables_->FindExtension(field->containing_type(), field->number());
    +        string error_msg = strings::Substitute(
    +            "Extension number $0 has already been used in \"$1\" by extension "
    +            "\"$2\" defined in $3.",
    +            field->number(),
    +            field->containing_type()->full_name(),
    +            conflicting_field->full_name(),
    +            conflicting_field->file()->name());
    +        // Conflicting extension numbers should be an error. However, before
    +        // turning this into an error we need to fix all existing broken
    +        // protos first.
    +        // TODO(xiaofeng): Change this to an error.
    +        AddWarning(field->full_name(), proto,
    +                   DescriptorPool::ErrorCollector::NUMBER, error_msg);
    +      }
    +    }
    +  }
    +
    +  // Add the field to the lowercase-name and camelcase-name tables.
    +  file_tables_->AddFieldByStylizedNames(field);
    +}
    +
    +void DescriptorBuilder::CrossLinkEnum(
    +    EnumDescriptor* enum_type, const EnumDescriptorProto& proto) {
    +  if (enum_type->options_ == NULL) {
    +    enum_type->options_ = &EnumOptions::default_instance();
    +  }
    +
    +  for (int i = 0; i < enum_type->value_count(); i++) {
    +    CrossLinkEnumValue(&enum_type->values_[i], proto.value(i));
    +  }
    +}
    +
    +void DescriptorBuilder::CrossLinkEnumValue(
    +    EnumValueDescriptor* enum_value,
    +    const EnumValueDescriptorProto& /* proto */) {
    +  if (enum_value->options_ == NULL) {
    +    enum_value->options_ = &EnumValueOptions::default_instance();
    +  }
    +}
    +
    +void DescriptorBuilder::CrossLinkService(
    +    ServiceDescriptor* service, const ServiceDescriptorProto& proto) {
    +  if (service->options_ == NULL) {
    +    service->options_ = &ServiceOptions::default_instance();
    +  }
    +
    +  for (int i = 0; i < service->method_count(); i++) {
    +    CrossLinkMethod(&service->methods_[i], proto.method(i));
    +  }
    +}
    +
    +void DescriptorBuilder::CrossLinkMethod(
    +    MethodDescriptor* method, const MethodDescriptorProto& proto) {
    +  if (method->options_ == NULL) {
    +    method->options_ = &MethodOptions::default_instance();
    +  }
    +
    +  Symbol input_type = LookupSymbol(proto.input_type(), method->full_name());
    +  if (input_type.IsNull()) {
    +    AddNotDefinedError(method->full_name(), proto,
    +                       DescriptorPool::ErrorCollector::INPUT_TYPE,
    +                       proto.input_type());
    +  } else if (input_type.type != Symbol::MESSAGE) {
    +    AddError(method->full_name(), proto,
    +             DescriptorPool::ErrorCollector::INPUT_TYPE,
    +             "\"" + proto.input_type() + "\" is not a message type.");
    +  } else {
    +    method->input_type_ = input_type.descriptor;
    +  }
    +
    +  Symbol output_type = LookupSymbol(proto.output_type(), method->full_name());
    +  if (output_type.IsNull()) {
    +    AddNotDefinedError(method->full_name(), proto,
    +                       DescriptorPool::ErrorCollector::OUTPUT_TYPE,
    +                       proto.output_type());
    +  } else if (output_type.type != Symbol::MESSAGE) {
    +    AddError(method->full_name(), proto,
    +             DescriptorPool::ErrorCollector::OUTPUT_TYPE,
    +             "\"" + proto.output_type() + "\" is not a message type.");
    +  } else {
    +    method->output_type_ = output_type.descriptor;
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +
    +#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type)  \
    +  for (int i = 0; i < descriptor->array_name##_count(); ++i) {     \
    +    Validate##type##Options(descriptor->array_name##s_ + i,        \
    +                            proto.array_name(i));                  \
    +  }
    +
    +// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to
    +// avoid problems that exist at init time.
    +static bool IsLite(const FileDescriptor* file) {
    +  // TODO(kenton):  I don't even remember how many of these conditions are
    +  //   actually possible.  I'm just being super-safe.
    +  return file != NULL &&
    +         &file->options() != &FileOptions::default_instance() &&
    +         file->options().optimize_for() == FileOptions::LITE_RUNTIME;
    +}
    +
    +void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file,
    +                                            const FileDescriptorProto& proto) {
    +  VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message);
    +  VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum);
    +  VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service);
    +  VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field);
    +
    +  // Lite files can only be imported by other Lite files.
    +  if (!IsLite(file)) {
    +    for (int i = 0; i < file->dependency_count(); i++) {
    +      if (IsLite(file->dependency(i))) {
    +        AddError(
    +          file->name(), proto,
    +          DescriptorPool::ErrorCollector::OTHER,
    +          "Files that do not use optimize_for = LITE_RUNTIME cannot import "
    +          "files which do use this option.  This file is not lite, but it "
    +          "imports \"" + file->dependency(i)->name() + "\" which is.");
    +        break;
    +      }
    +    }
    +  }
    +}
    +
    +
    +void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
    +                                               const DescriptorProto& proto) {
    +  VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field);
    +  VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message);
    +  VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum);
    +  VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field);
    +
    +  const int64 max_extension_range =
    +      static_cast(message->options().message_set_wire_format() ?
    +                         kint32max :
    +                         FieldDescriptor::kMaxNumber);
    +  for (int i = 0; i < message->extension_range_count(); ++i) {
    +    if (message->extension_range(i)->end > max_extension_range + 1) {
    +      AddError(
    +          message->full_name(), proto.extension_range(i),
    +          DescriptorPool::ErrorCollector::NUMBER,
    +          strings::Substitute("Extension numbers cannot be greater than $0.",
    +                              max_extension_range));
    +    }
    +  }
    +}
    +
    +void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
    +    const FieldDescriptorProto& proto) {
    +  if (field->options().has_experimental_map_key()) {
    +    ValidateMapKey(field, proto);
    +  }
    +
    +  // Only message type fields may be lazy.
    +  if (field->options().lazy()) {
    +    if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
    +      AddError(field->full_name(), proto,
    +               DescriptorPool::ErrorCollector::TYPE,
    +               "[lazy = true] can only be specified for submessage fields.");
    +    }
    +  }
    +
    +  // Only repeated primitive fields may be packed.
    +  if (field->options().packed() && !field->is_packable()) {
    +    AddError(
    +      field->full_name(), proto,
    +      DescriptorPool::ErrorCollector::TYPE,
    +      "[packed = true] can only be specified for repeated primitive fields.");
    +  }
    +
    +  // Note:  Default instance may not yet be initialized here, so we have to
    +  //   avoid reading from it.
    +  if (field->containing_type_ != NULL &&
    +      &field->containing_type()->options() !=
    +      &MessageOptions::default_instance() &&
    +      field->containing_type()->options().message_set_wire_format()) {
    +    if (field->is_extension()) {
    +      if (!field->is_optional() ||
    +          field->type() != FieldDescriptor::TYPE_MESSAGE) {
    +        AddError(field->full_name(), proto,
    +                 DescriptorPool::ErrorCollector::TYPE,
    +                 "Extensions of MessageSets must be optional messages.");
    +      }
    +    } else {
    +      AddError(field->full_name(), proto,
    +               DescriptorPool::ErrorCollector::NAME,
    +               "MessageSets cannot have fields, only extensions.");
    +    }
    +  }
    +
    +  // Lite extensions can only be of Lite types.
    +  if (IsLite(field->file()) &&
    +      field->containing_type_ != NULL &&
    +      !IsLite(field->containing_type()->file())) {
    +    AddError(field->full_name(), proto,
    +             DescriptorPool::ErrorCollector::EXTENDEE,
    +             "Extensions to non-lite types can only be declared in non-lite "
    +             "files.  Note that you cannot extend a non-lite type to contain "
    +             "a lite type, but the reverse is allowed.");
    +  }
    +
    +}
    +
    +void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
    +                                            const EnumDescriptorProto& proto) {
    +  VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue);
    +  if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) {
    +    map used_values;
    +    for (int i = 0; i < enm->value_count(); ++i) {
    +      const EnumValueDescriptor* enum_value = enm->value(i);
    +      if (used_values.find(enum_value->number()) != used_values.end()) {
    +        string error =
    +            "\"" + enum_value->full_name() +
    +            "\" uses the same enum value as \"" +
    +            used_values[enum_value->number()] + "\". If this is intended, set "
    +            "'option allow_alias = true;' to the enum definition.";
    +        if (!enm->options().allow_alias()) {
    +          // Generate error if duplicated enum values are explicitly disallowed.
    +          AddError(enm->full_name(), proto,
    +                   DescriptorPool::ErrorCollector::NUMBER,
    +                   error);
    +        } else {
    +          // Generate warning if duplicated values are found but the option
    +          // isn't set.
    +          GOOGLE_LOG(ERROR) << error;
    +        }
    +      } else {
    +        used_values[enum_value->number()] = enum_value->full_name();
    +      }
    +    }
    +  }
    +}
    +
    +void DescriptorBuilder::ValidateEnumValueOptions(
    +    EnumValueDescriptor* /* enum_value */,
    +    const EnumValueDescriptorProto& /* proto */) {
    +  // Nothing to do so far.
    +}
    +void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service,
    +    const ServiceDescriptorProto& proto) {
    +  if (IsLite(service->file()) &&
    +      (service->file()->options().cc_generic_services() ||
    +       service->file()->options().java_generic_services())) {
    +    AddError(service->full_name(), proto,
    +             DescriptorPool::ErrorCollector::NAME,
    +             "Files with optimize_for = LITE_RUNTIME cannot define services "
    +             "unless you set both options cc_generic_services and "
    +             "java_generic_sevices to false.");
    +  }
    +
    +  VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method);
    +}
    +
    +void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* /* method */,
    +    const MethodDescriptorProto& /* proto */) {
    +  // Nothing to do so far.
    +}
    +
    +void DescriptorBuilder::ValidateMapKey(FieldDescriptor* field,
    +                                       const FieldDescriptorProto& proto) {
    +  if (!field->is_repeated()) {
    +    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +             "map type is only allowed for repeated fields.");
    +    return;
    +  }
    +
    +  if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
    +    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +             "map type is only allowed for fields with a message type.");
    +    return;
    +  }
    +
    +  const Descriptor* item_type = field->message_type();
    +  if (item_type == NULL) {
    +    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +             "Could not find field type.");
    +    return;
    +  }
    +
    +  // Find the field in item_type named by "experimental_map_key"
    +  const string& key_name = field->options().experimental_map_key();
    +  const Symbol key_symbol = LookupSymbol(
    +      key_name,
    +      // We append ".key_name" to the containing type's name since
    +      // LookupSymbol() searches for peers of the supplied name, not
    +      // children of the supplied name.
    +      item_type->full_name() + "." + key_name);
    +
    +  if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) {
    +    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +             "Could not find field named \"" + key_name + "\" in type \"" +
    +             item_type->full_name() + "\".");
    +    return;
    +  }
    +  const FieldDescriptor* key_field = key_symbol.field_descriptor;
    +
    +  if (key_field->is_repeated()) {
    +    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +             "map_key must not name a repeated field.");
    +    return;
    +  }
    +
    +  if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
    +             "map key must name a scalar or string field.");
    +    return;
    +  }
    +
    +  field->experimental_map_key_ = key_field;
    +}
    +
    +
    +#undef VALIDATE_OPTIONS_FROM_ARRAY
    +
    +// -------------------------------------------------------------------
    +
    +DescriptorBuilder::OptionInterpreter::OptionInterpreter(
    +    DescriptorBuilder* builder) : builder_(builder) {
    +  GOOGLE_CHECK(builder_);
    +}
    +
    +DescriptorBuilder::OptionInterpreter::~OptionInterpreter() {
    +}
    +
    +bool DescriptorBuilder::OptionInterpreter::InterpretOptions(
    +    OptionsToInterpret* options_to_interpret) {
    +  // Note that these may be in different pools, so we can't use the same
    +  // descriptor and reflection objects on both.
    +  Message* options = options_to_interpret->options;
    +  const Message* original_options = options_to_interpret->original_options;
    +
    +  bool failed = false;
    +  options_to_interpret_ = options_to_interpret;
    +
    +  // Find the uninterpreted_option field in the mutable copy of the options
    +  // and clear them, since we're about to interpret them.
    +  const FieldDescriptor* uninterpreted_options_field =
    +      options->GetDescriptor()->FindFieldByName("uninterpreted_option");
    +  GOOGLE_CHECK(uninterpreted_options_field != NULL)
    +      << "No field named \"uninterpreted_option\" in the Options proto.";
    +  options->GetReflection()->ClearField(options, uninterpreted_options_field);
    +
    +  // Find the uninterpreted_option field in the original options.
    +  const FieldDescriptor* original_uninterpreted_options_field =
    +      original_options->GetDescriptor()->
    +          FindFieldByName("uninterpreted_option");
    +  GOOGLE_CHECK(original_uninterpreted_options_field != NULL)
    +      << "No field named \"uninterpreted_option\" in the Options proto.";
    +
    +  const int num_uninterpreted_options = original_options->GetReflection()->
    +      FieldSize(*original_options, original_uninterpreted_options_field);
    +  for (int i = 0; i < num_uninterpreted_options; ++i) {
    +    uninterpreted_option_ = down_cast(
    +        &original_options->GetReflection()->GetRepeatedMessage(
    +            *original_options, original_uninterpreted_options_field, i));
    +    if (!InterpretSingleOption(options)) {
    +      // Error already added by InterpretSingleOption().
    +      failed = true;
    +      break;
    +    }
    +  }
    +  // Reset these, so we don't have any dangling pointers.
    +  uninterpreted_option_ = NULL;
    +  options_to_interpret_ = NULL;
    +
    +  if (!failed) {
    +    // InterpretSingleOption() added the interpreted options in the
    +    // UnknownFieldSet, in case the option isn't yet known to us.  Now we
    +    // serialize the options message and deserialize it back.  That way, any
    +    // option fields that we do happen to know about will get moved from the
    +    // UnknownFieldSet into the real fields, and thus be available right away.
    +    // If they are not known, that's OK too. They will get reparsed into the
    +    // UnknownFieldSet and wait there until the message is parsed by something
    +    // that does know about the options.
    +    string buf;
    +    options->AppendToString(&buf);
    +    GOOGLE_CHECK(options->ParseFromString(buf))
    +        << "Protocol message serialized itself in invalid fashion.";
    +  }
    +
    +  return !failed;
    +}
    +
    +bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
    +    Message* options) {
    +  // First do some basic validation.
    +  if (uninterpreted_option_->name_size() == 0) {
    +    // This should never happen unless the parser has gone seriously awry or
    +    // someone has manually created the uninterpreted option badly.
    +    return AddNameError("Option must have a name.");
    +  }
    +  if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") {
    +    return AddNameError("Option must not use reserved name "
    +                        "\"uninterpreted_option\".");
    +  }
    +
    +  const Descriptor* options_descriptor = NULL;
    +  // Get the options message's descriptor from the builder's pool, so that we
    +  // get the version that knows about any extension options declared in the
    +  // file we're currently building. The descriptor should be there as long as
    +  // the file we're building imported "google/protobuf/descriptors.proto".
    +
    +  // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
    +  // DescriptorPool::FindMessageTypeByName() because we're already holding the
    +  // pool's mutex, and the latter method locks it again.  We don't use
    +  // FindSymbol() because files that use custom options only need to depend on
    +  // the file that defines the option, not descriptor.proto itself.
    +  Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
    +    options->GetDescriptor()->full_name());
    +  if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) {
    +    options_descriptor = symbol.descriptor;
    +  } else {
    +    // The options message's descriptor was not in the builder's pool, so use
    +    // the standard version from the generated pool. We're not holding the
    +    // generated pool's mutex, so we can search it the straightforward way.
    +    options_descriptor = options->GetDescriptor();
    +  }
    +  GOOGLE_CHECK(options_descriptor);
    +
    +  // We iterate over the name parts to drill into the submessages until we find
    +  // the leaf field for the option. As we drill down we remember the current
    +  // submessage's descriptor in |descriptor| and the next field in that
    +  // submessage in |field|. We also track the fields we're drilling down
    +  // through in |intermediate_fields|. As we go, we reconstruct the full option
    +  // name in |debug_msg_name|, for use in error messages.
    +  const Descriptor* descriptor = options_descriptor;
    +  const FieldDescriptor* field = NULL;
    +  vector intermediate_fields;
    +  string debug_msg_name = "";
    +
    +  for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
    +    const string& name_part = uninterpreted_option_->name(i).name_part();
    +    if (debug_msg_name.size() > 0) {
    +      debug_msg_name += ".";
    +    }
    +    if (uninterpreted_option_->name(i).is_extension()) {
    +      debug_msg_name += "(" + name_part + ")";
    +      // Search for the extension's descriptor as an extension in the builder's
    +      // pool. Note that we use DescriptorBuilder::LookupSymbol(), not
    +      // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows
    +      // relative lookups, and 2) because we're already holding the pool's
    +      // mutex, and the latter method locks it again.
    +      symbol = builder_->LookupSymbol(name_part,
    +                                      options_to_interpret_->name_scope);
    +      if (!symbol.IsNull() && symbol.type == Symbol::FIELD) {
    +        field = symbol.field_descriptor;
    +      }
    +      // If we don't find the field then the field's descriptor was not in the
    +      // builder's pool, but there's no point in looking in the generated
    +      // pool. We require that you import the file that defines any extensions
    +      // you use, so they must be present in the builder's pool.
    +    } else {
    +      debug_msg_name += name_part;
    +      // Search for the field's descriptor as a regular field.
    +      field = descriptor->FindFieldByName(name_part);
    +    }
    +
    +    if (field == NULL) {
    +      if (get_allow_unknown(builder_->pool_)) {
    +        // We can't find the option, but AllowUnknownDependencies() is enabled,
    +        // so we will just leave it as uninterpreted.
    +        AddWithoutInterpreting(*uninterpreted_option_, options);
    +        return true;
    +      } else if (!(builder_->undefine_resolved_name_).empty()) {
    +        // Option is resolved to a name which is not defined.
    +        return AddNameError(
    +            "Option \"" + debug_msg_name + "\" is resolved to \"(" +
    +            builder_->undefine_resolved_name_ +
    +            ")\", which is not defined. The innermost scope is searched first "
    +            "in name resolution. Consider using a leading '.'(i.e., \"(." +
    +            debug_msg_name.substr(1) +
    +            "\") to start from the outermost scope.");
    +      } else {
    +        return AddNameError("Option \"" + debug_msg_name + "\" unknown.");
    +      }
    +    } else if (field->containing_type() != descriptor) {
    +      if (get_is_placeholder(field->containing_type())) {
    +        // The field is an extension of a placeholder type, so we can't
    +        // reliably verify whether it is a valid extension to use here (e.g.
    +        // we don't know if it is an extension of the correct *Options message,
    +        // or if it has a valid field number, etc.).  Just leave it as
    +        // uninterpreted instead.
    +        AddWithoutInterpreting(*uninterpreted_option_, options);
    +        return true;
    +      } else {
    +        // This can only happen if, due to some insane misconfiguration of the
    +        // pools, we find the options message in one pool but the field in
    +        // another. This would probably imply a hefty bug somewhere.
    +        return AddNameError("Option field \"" + debug_msg_name +
    +                            "\" is not a field or extension of message \"" +
    +                            descriptor->name() + "\".");
    +      }
    +    } else if (i < uninterpreted_option_->name_size() - 1) {
    +      if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
    +        return AddNameError("Option \"" +  debug_msg_name +
    +                            "\" is an atomic type, not a message.");
    +      } else if (field->is_repeated()) {
    +        return AddNameError("Option field \"" + debug_msg_name +
    +                            "\" is a repeated message. Repeated message "
    +                            "options must be initialized using an "
    +                            "aggregate value.");
    +      } else {
    +        // Drill down into the submessage.
    +        intermediate_fields.push_back(field);
    +        descriptor = field->message_type();
    +      }
    +    }
    +  }
    +
    +  // We've found the leaf field. Now we use UnknownFieldSets to set its value
    +  // on the options message. We do so because the message may not yet know
    +  // about its extension fields, so we may not be able to set the fields
    +  // directly. But the UnknownFieldSets will serialize to the same wire-format
    +  // message, so reading that message back in once the extension fields are
    +  // known will populate them correctly.
    +
    +  // First see if the option is already set.
    +  if (!field->is_repeated() && !ExamineIfOptionIsSet(
    +          intermediate_fields.begin(),
    +          intermediate_fields.end(),
    +          field, debug_msg_name,
    +          options->GetReflection()->GetUnknownFields(*options))) {
    +    return false;  // ExamineIfOptionIsSet() already added the error.
    +  }
    +
    +
    +  // First set the value on the UnknownFieldSet corresponding to the
    +  // innermost message.
    +  scoped_ptr unknown_fields(new UnknownFieldSet());
    +  if (!SetOptionValue(field, unknown_fields.get())) {
    +    return false;  // SetOptionValue() already added the error.
    +  }
    +
    +  // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all
    +  // the intermediate messages.
    +  for (vector::reverse_iterator iter =
    +           intermediate_fields.rbegin();
    +       iter != intermediate_fields.rend(); ++iter) {
    +    scoped_ptr parent_unknown_fields(new UnknownFieldSet());
    +    switch ((*iter)->type()) {
    +      case FieldDescriptor::TYPE_MESSAGE: {
    +        io::StringOutputStream outstr(
    +            parent_unknown_fields->AddLengthDelimited((*iter)->number()));
    +        io::CodedOutputStream out(&outstr);
    +        internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out);
    +        GOOGLE_CHECK(!out.HadError())
    +            << "Unexpected failure while serializing option submessage "
    +            << debug_msg_name << "\".";
    +        break;
    +      }
    +
    +      case FieldDescriptor::TYPE_GROUP: {
    +         parent_unknown_fields->AddGroup((*iter)->number())
    +                              ->MergeFrom(*unknown_fields);
    +        break;
    +      }
    +
    +      default:
    +        GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: "
    +                   << (*iter)->type();
    +        return false;
    +    }
    +    unknown_fields.reset(parent_unknown_fields.release());
    +  }
    +
    +  // Now merge the UnknownFieldSet corresponding to the top-level message into
    +  // the options message.
    +  options->GetReflection()->MutableUnknownFields(options)->MergeFrom(
    +      *unknown_fields);
    +
    +  return true;
    +}
    +
    +void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting(
    +    const UninterpretedOption& uninterpreted_option, Message* options) {
    +  const FieldDescriptor* field =
    +    options->GetDescriptor()->FindFieldByName("uninterpreted_option");
    +  GOOGLE_CHECK(field != NULL);
    +
    +  options->GetReflection()->AddMessage(options, field)
    +    ->CopyFrom(uninterpreted_option);
    +}
    +
    +bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet(
    +    vector::const_iterator intermediate_fields_iter,
    +    vector::const_iterator intermediate_fields_end,
    +    const FieldDescriptor* innermost_field, const string& debug_msg_name,
    +    const UnknownFieldSet& unknown_fields) {
    +  // We do linear searches of the UnknownFieldSet and its sub-groups.  This
    +  // should be fine since it's unlikely that any one options structure will
    +  // contain more than a handful of options.
    +
    +  if (intermediate_fields_iter == intermediate_fields_end) {
    +    // We're at the innermost submessage.
    +    for (int i = 0; i < unknown_fields.field_count(); i++) {
    +      if (unknown_fields.field(i).number() == innermost_field->number()) {
    +        return AddNameError("Option \"" + debug_msg_name +
    +                            "\" was already set.");
    +      }
    +    }
    +    return true;
    +  }
    +
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    if (unknown_fields.field(i).number() ==
    +        (*intermediate_fields_iter)->number()) {
    +      const UnknownField* unknown_field = &unknown_fields.field(i);
    +      FieldDescriptor::Type type = (*intermediate_fields_iter)->type();
    +      // Recurse into the next submessage.
    +      switch (type) {
    +        case FieldDescriptor::TYPE_MESSAGE:
    +          if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) {
    +            UnknownFieldSet intermediate_unknown_fields;
    +            if (intermediate_unknown_fields.ParseFromString(
    +                    unknown_field->length_delimited()) &&
    +                !ExamineIfOptionIsSet(intermediate_fields_iter + 1,
    +                                      intermediate_fields_end,
    +                                      innermost_field, debug_msg_name,
    +                                      intermediate_unknown_fields)) {
    +              return false;  // Error already added.
    +            }
    +          }
    +          break;
    +
    +        case FieldDescriptor::TYPE_GROUP:
    +          if (unknown_field->type() == UnknownField::TYPE_GROUP) {
    +            if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1,
    +                                      intermediate_fields_end,
    +                                      innermost_field, debug_msg_name,
    +                                      unknown_field->group())) {
    +              return false;  // Error already added.
    +            }
    +          }
    +          break;
    +
    +        default:
    +          GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type;
    +          return false;
    +      }
    +    }
    +  }
    +  return true;
    +}
    +
    +bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
    +    const FieldDescriptor* option_field,
    +    UnknownFieldSet* unknown_fields) {
    +  // We switch on the CppType to validate.
    +  switch (option_field->cpp_type()) {
    +
    +    case FieldDescriptor::CPPTYPE_INT32:
    +      if (uninterpreted_option_->has_positive_int_value()) {
    +        if (uninterpreted_option_->positive_int_value() >
    +            static_cast(kint32max)) {
    +          return AddValueError("Value out of range for int32 option \"" +
    +                               option_field->full_name() + "\".");
    +        } else {
    +          SetInt32(option_field->number(),
    +                   uninterpreted_option_->positive_int_value(),
    +                   option_field->type(), unknown_fields);
    +        }
    +      } else if (uninterpreted_option_->has_negative_int_value()) {
    +        if (uninterpreted_option_->negative_int_value() <
    +            static_cast(kint32min)) {
    +          return AddValueError("Value out of range for int32 option \"" +
    +                               option_field->full_name() + "\".");
    +        } else {
    +          SetInt32(option_field->number(),
    +                   uninterpreted_option_->negative_int_value(),
    +                   option_field->type(), unknown_fields);
    +        }
    +      } else {
    +        return AddValueError("Value must be integer for int32 option \"" +
    +                             option_field->full_name() + "\".");
    +      }
    +      break;
    +
    +    case FieldDescriptor::CPPTYPE_INT64:
    +      if (uninterpreted_option_->has_positive_int_value()) {
    +        if (uninterpreted_option_->positive_int_value() >
    +            static_cast(kint64max)) {
    +          return AddValueError("Value out of range for int64 option \"" +
    +                               option_field->full_name() + "\".");
    +        } else {
    +          SetInt64(option_field->number(),
    +                   uninterpreted_option_->positive_int_value(),
    +                   option_field->type(), unknown_fields);
    +        }
    +      } else if (uninterpreted_option_->has_negative_int_value()) {
    +        SetInt64(option_field->number(),
    +                 uninterpreted_option_->negative_int_value(),
    +                 option_field->type(), unknown_fields);
    +      } else {
    +        return AddValueError("Value must be integer for int64 option \"" +
    +                             option_field->full_name() + "\".");
    +      }
    +      break;
    +
    +    case FieldDescriptor::CPPTYPE_UINT32:
    +      if (uninterpreted_option_->has_positive_int_value()) {
    +        if (uninterpreted_option_->positive_int_value() > kuint32max) {
    +          return AddValueError("Value out of range for uint32 option \"" +
    +                               option_field->name() + "\".");
    +        } else {
    +          SetUInt32(option_field->number(),
    +                    uninterpreted_option_->positive_int_value(),
    +                    option_field->type(), unknown_fields);
    +        }
    +      } else {
    +        return AddValueError("Value must be non-negative integer for uint32 "
    +                             "option \"" + option_field->full_name() + "\".");
    +      }
    +      break;
    +
    +    case FieldDescriptor::CPPTYPE_UINT64:
    +      if (uninterpreted_option_->has_positive_int_value()) {
    +        SetUInt64(option_field->number(),
    +                  uninterpreted_option_->positive_int_value(),
    +                  option_field->type(), unknown_fields);
    +      } else {
    +        return AddValueError("Value must be non-negative integer for uint64 "
    +                             "option \"" + option_field->full_name() + "\".");
    +      }
    +      break;
    +
    +    case FieldDescriptor::CPPTYPE_FLOAT: {
    +      float value;
    +      if (uninterpreted_option_->has_double_value()) {
    +        value = uninterpreted_option_->double_value();
    +      } else if (uninterpreted_option_->has_positive_int_value()) {
    +        value = uninterpreted_option_->positive_int_value();
    +      } else if (uninterpreted_option_->has_negative_int_value()) {
    +        value = uninterpreted_option_->negative_int_value();
    +      } else {
    +        return AddValueError("Value must be number for float option \"" +
    +                             option_field->full_name() + "\".");
    +      }
    +      unknown_fields->AddFixed32(option_field->number(),
    +          google::protobuf::internal::WireFormatLite::EncodeFloat(value));
    +      break;
    +    }
    +
    +    case FieldDescriptor::CPPTYPE_DOUBLE: {
    +      double value;
    +      if (uninterpreted_option_->has_double_value()) {
    +        value = uninterpreted_option_->double_value();
    +      } else if (uninterpreted_option_->has_positive_int_value()) {
    +        value = uninterpreted_option_->positive_int_value();
    +      } else if (uninterpreted_option_->has_negative_int_value()) {
    +        value = uninterpreted_option_->negative_int_value();
    +      } else {
    +        return AddValueError("Value must be number for double option \"" +
    +                             option_field->full_name() + "\".");
    +      }
    +      unknown_fields->AddFixed64(option_field->number(),
    +          google::protobuf::internal::WireFormatLite::EncodeDouble(value));
    +      break;
    +    }
    +
    +    case FieldDescriptor::CPPTYPE_BOOL:
    +      uint64 value;
    +      if (!uninterpreted_option_->has_identifier_value()) {
    +        return AddValueError("Value must be identifier for boolean option "
    +                             "\"" + option_field->full_name() + "\".");
    +      }
    +      if (uninterpreted_option_->identifier_value() == "true") {
    +        value = 1;
    +      } else if (uninterpreted_option_->identifier_value() == "false") {
    +        value = 0;
    +      } else {
    +        return AddValueError("Value must be \"true\" or \"false\" for boolean "
    +                             "option \"" + option_field->full_name() + "\".");
    +      }
    +      unknown_fields->AddVarint(option_field->number(), value);
    +      break;
    +
    +    case FieldDescriptor::CPPTYPE_ENUM: {
    +      if (!uninterpreted_option_->has_identifier_value()) {
    +        return AddValueError("Value must be identifier for enum-valued option "
    +                             "\"" + option_field->full_name() + "\".");
    +      }
    +      const EnumDescriptor* enum_type = option_field->enum_type();
    +      const string& value_name = uninterpreted_option_->identifier_value();
    +      const EnumValueDescriptor* enum_value = NULL;
    +
    +      if (enum_type->file()->pool() != DescriptorPool::generated_pool()) {
    +        // Note that the enum value's fully-qualified name is a sibling of the
    +        // enum's name, not a child of it.
    +        string fully_qualified_name = enum_type->full_name();
    +        fully_qualified_name.resize(fully_qualified_name.size() -
    +                                    enum_type->name().size());
    +        fully_qualified_name += value_name;
    +
    +        // Search for the enum value's descriptor in the builder's pool. Note
    +        // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
    +        // DescriptorPool::FindEnumValueByName() because we're already holding
    +        // the pool's mutex, and the latter method locks it again.
    +        Symbol symbol =
    +          builder_->FindSymbolNotEnforcingDeps(fully_qualified_name);
    +        if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) {
    +          if (symbol.enum_value_descriptor->type() != enum_type) {
    +            return AddValueError("Enum type \"" + enum_type->full_name() +
    +                "\" has no value named \"" + value_name + "\" for option \"" +
    +                option_field->full_name() +
    +                "\". This appears to be a value from a sibling type.");
    +          } else {
    +            enum_value = symbol.enum_value_descriptor;
    +          }
    +        }
    +      } else {
    +        // The enum type is in the generated pool, so we can search for the
    +        // value there.
    +        enum_value = enum_type->FindValueByName(value_name);
    +      }
    +
    +      if (enum_value == NULL) {
    +        return AddValueError("Enum type \"" +
    +                             option_field->enum_type()->full_name() +
    +                             "\" has no value named \"" + value_name + "\" for "
    +                             "option \"" + option_field->full_name() + "\".");
    +      } else {
    +        // Sign-extension is not a problem, since we cast directly from int32 to
    +        // uint64, without first going through uint32.
    +        unknown_fields->AddVarint(option_field->number(),
    +          static_cast(static_cast(enum_value->number())));
    +      }
    +      break;
    +    }
    +
    +    case FieldDescriptor::CPPTYPE_STRING:
    +      if (!uninterpreted_option_->has_string_value()) {
    +        return AddValueError("Value must be quoted string for string option "
    +                             "\"" + option_field->full_name() + "\".");
    +      }
    +      // The string has already been unquoted and unescaped by the parser.
    +      unknown_fields->AddLengthDelimited(option_field->number(),
    +          uninterpreted_option_->string_value());
    +      break;
    +
    +    case FieldDescriptor::CPPTYPE_MESSAGE:
    +      if (!SetAggregateOption(option_field, unknown_fields)) {
    +        return false;
    +      }
    +      break;
    +  }
    +
    +  return true;
    +}
    +
    +class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
    +    : public TextFormat::Finder {
    + public:
    +  DescriptorBuilder* builder_;
    +
    +  virtual const FieldDescriptor* FindExtension(
    +      Message* message, const string& name) const {
    +    assert_mutex_held(builder_->pool_);
    +    const Descriptor* descriptor = message->GetDescriptor();
    +    Symbol result = builder_->LookupSymbolNoPlaceholder(
    +        name, descriptor->full_name());
    +    if (result.type == Symbol::FIELD &&
    +        result.field_descriptor->is_extension()) {
    +      return result.field_descriptor;
    +    } else if (result.type == Symbol::MESSAGE &&
    +               descriptor->options().message_set_wire_format()) {
    +      const Descriptor* foreign_type = result.descriptor;
    +      // The text format allows MessageSet items to be specified using
    +      // the type name, rather than the extension identifier. If the symbol
    +      // lookup returned a Message, and the enclosing Message has
    +      // message_set_wire_format = true, then return the message set
    +      // extension, if one exists.
    +      for (int i = 0; i < foreign_type->extension_count(); i++) {
    +        const FieldDescriptor* extension = foreign_type->extension(i);
    +        if (extension->containing_type() == descriptor &&
    +            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
    +            extension->is_optional() &&
    +            extension->message_type() == foreign_type) {
    +          // Found it.
    +          return extension;
    +        }
    +      }
    +    }
    +    return NULL;
    +  }
    +};
    +
    +// A custom error collector to record any text-format parsing errors
    +namespace {
    +class AggregateErrorCollector : public io::ErrorCollector {
    + public:
    +  string error_;
    +
    +  virtual void AddError(int /* line */, int /* column */,
    +                        const string& message) {
    +    if (!error_.empty()) {
    +      error_ += "; ";
    +    }
    +    error_ += message;
    +  }
    +
    +  virtual void AddWarning(int /* line */, int /* column */,
    +                          const string& /* message */) {
    +    // Ignore warnings
    +  }
    +};
    +}
    +
    +// We construct a dynamic message of the type corresponding to
    +// option_field, parse the supplied text-format string into this
    +// message, and serialize the resulting message to produce the value.
    +bool DescriptorBuilder::OptionInterpreter::SetAggregateOption(
    +    const FieldDescriptor* option_field,
    +    UnknownFieldSet* unknown_fields) {
    +  if (!uninterpreted_option_->has_aggregate_value()) {
    +    return AddValueError("Option \"" + option_field->full_name() +
    +                         "\" is a message. To set the entire message, use "
    +                         "syntax like \"" + option_field->name() +
    +                         " = {  }\". "
    +                         "To set fields within it, use "
    +                         "syntax like \"" + option_field->name() +
    +                         ".foo = value\".");
    +  }
    +
    +  const Descriptor* type = option_field->message_type();
    +  scoped_ptr dynamic(dynamic_factory_.GetPrototype(type)->New());
    +  GOOGLE_CHECK(dynamic.get() != NULL)
    +      << "Could not create an instance of " << option_field->DebugString();
    +
    +  AggregateErrorCollector collector;
    +  AggregateOptionFinder finder;
    +  finder.builder_ = builder_;
    +  TextFormat::Parser parser;
    +  parser.RecordErrorsTo(&collector);
    +  parser.SetFinder(&finder);
    +  if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
    +                              dynamic.get())) {
    +    AddValueError("Error while parsing option value for \"" +
    +                  option_field->name() + "\": " + collector.error_);
    +    return false;
    +  } else {
    +    string serial;
    +    dynamic->SerializeToString(&serial);  // Never fails
    +    if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) {
    +      unknown_fields->AddLengthDelimited(option_field->number(), serial);
    +    } else {
    +      GOOGLE_CHECK_EQ(option_field->type(),  FieldDescriptor::TYPE_GROUP);
    +      UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number());
    +      group->ParseFromString(serial);
    +    }
    +    return true;
    +  }
    +}
    +
    +void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value,
    +    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
    +  switch (type) {
    +    case FieldDescriptor::TYPE_INT32:
    +      unknown_fields->AddVarint(number,
    +        static_cast(static_cast(value)));
    +      break;
    +
    +    case FieldDescriptor::TYPE_SFIXED32:
    +      unknown_fields->AddFixed32(number, static_cast(value));
    +      break;
    +
    +    case FieldDescriptor::TYPE_SINT32:
    +      unknown_fields->AddVarint(number,
    +          google::protobuf::internal::WireFormatLite::ZigZagEncode32(value));
    +      break;
    +
    +    default:
    +      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type;
    +      break;
    +  }
    +}
    +
    +void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value,
    +    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
    +  switch (type) {
    +    case FieldDescriptor::TYPE_INT64:
    +      unknown_fields->AddVarint(number, static_cast(value));
    +      break;
    +
    +    case FieldDescriptor::TYPE_SFIXED64:
    +      unknown_fields->AddFixed64(number, static_cast(value));
    +      break;
    +
    +    case FieldDescriptor::TYPE_SINT64:
    +      unknown_fields->AddVarint(number,
    +          google::protobuf::internal::WireFormatLite::ZigZagEncode64(value));
    +      break;
    +
    +    default:
    +      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type;
    +      break;
    +  }
    +}
    +
    +void DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value,
    +    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
    +  switch (type) {
    +    case FieldDescriptor::TYPE_UINT32:
    +      unknown_fields->AddVarint(number, static_cast(value));
    +      break;
    +
    +    case FieldDescriptor::TYPE_FIXED32:
    +      unknown_fields->AddFixed32(number, static_cast(value));
    +      break;
    +
    +    default:
    +      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type;
    +      break;
    +  }
    +}
    +
    +void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value,
    +    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
    +  switch (type) {
    +    case FieldDescriptor::TYPE_UINT64:
    +      unknown_fields->AddVarint(number, value);
    +      break;
    +
    +    case FieldDescriptor::TYPE_FIXED64:
    +      unknown_fields->AddFixed64(number, value);
    +      break;
    +
    +    default:
    +      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type;
    +      break;
    +  }
    +}
    +
    +void DescriptorBuilder::LogUnusedDependency(const FileDescriptor* result) {
    +
    +  if (!unused_dependency_.empty()) {
    +    std::set annotation_extensions;
    +    annotation_extensions.insert("google.protobuf.MessageOptions");
    +    annotation_extensions.insert("google.protobuf.FileOptions");
    +    annotation_extensions.insert("google.protobuf.FieldOptions");
    +    annotation_extensions.insert("google.protobuf.EnumOptions");
    +    annotation_extensions.insert("google.protobuf.EnumValueOptions");
    +    annotation_extensions.insert("google.protobuf.ServiceOptions");
    +    annotation_extensions.insert("google.protobuf.MethodOptions");
    +    annotation_extensions.insert("google.protobuf.StreamOptions");
    +    for (set::const_iterator
    +             it = unused_dependency_.begin();
    +         it != unused_dependency_.end(); ++it) {
    +      // Do not log warnings for proto files which extend annotations.
    +      int i;
    +      for (i = 0 ; i < (*it)->extension_count(); ++i) {
    +        if (annotation_extensions.find(
    +                (*it)->extension(i)->containing_type()->full_name())
    +            != annotation_extensions.end()) {
    +          break;
    +        }
    +      }
    +      // Log warnings for unused imported files.
    +      if (i == (*it)->extension_count()) {
    +        GOOGLE_LOG(WARNING) << "Warning: Unused import: \"" << result->name()
    +                     << "\" imports \"" << (*it)->name()
    +                     << "\" which is not used.";
    +      }
    +    }
    +  }
    +}
    +
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.h b/toolkit/components/protobuf/src/google/protobuf/descriptor.h
    new file mode 100644
    index 000000000000..67afc774dbd0
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.h
    @@ -0,0 +1,1691 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// This file contains classes which describe a type of protocol message.
    +// You can use a message's descriptor to learn at runtime what fields
    +// it contains and what the types of those fields are.  The Message
    +// interface also allows you to dynamically access and modify individual
    +// fields by passing the FieldDescriptor of the field you are interested
    +// in.
    +//
    +// Most users will not care about descriptors, because they will write
    +// code specific to certain protocol types and will simply use the classes
    +// generated by the protocol compiler directly.  Advanced users who want
    +// to operate on arbitrary types (not known at compile time) may want to
    +// read descriptors in order to learn about the contents of a message.
    +// A very small number of users will want to construct their own
    +// Descriptors, either because they are implementing Message manually or
    +// because they are writing something like the protocol compiler.
    +//
    +// For an example of how you might use descriptors, see the code example
    +// at the top of message.h.
    +
    +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__
    +#define GOOGLE_PROTOBUF_DESCRIPTOR_H__
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +
    +namespace google {
    +namespace protobuf {
    +
    +// Defined in this file.
    +class Descriptor;
    +class FieldDescriptor;
    +class OneofDescriptor;
    +class EnumDescriptor;
    +class EnumValueDescriptor;
    +class ServiceDescriptor;
    +class MethodDescriptor;
    +class FileDescriptor;
    +class DescriptorDatabase;
    +class DescriptorPool;
    +
    +// Defined in descriptor.proto
    +class DescriptorProto;
    +class FieldDescriptorProto;
    +class OneofDescriptorProto;
    +class EnumDescriptorProto;
    +class EnumValueDescriptorProto;
    +class ServiceDescriptorProto;
    +class MethodDescriptorProto;
    +class FileDescriptorProto;
    +class MessageOptions;
    +class FieldOptions;
    +class EnumOptions;
    +class EnumValueOptions;
    +class ServiceOptions;
    +class MethodOptions;
    +class FileOptions;
    +class UninterpretedOption;
    +class SourceCodeInfo;
    +
    +// Defined in message.h
    +class Message;
    +
    +// Defined in descriptor.cc
    +class DescriptorBuilder;
    +class FileDescriptorTables;
    +
    +// Defined in unknown_field_set.h.
    +class UnknownField;
    +
    +// NB, all indices are zero-based.
    +struct SourceLocation {
    +  int start_line;
    +  int end_line;
    +  int start_column;
    +  int end_column;
    +
    +  // Doc comments found at the source location.
    +  // TODO(kenton):  Maybe this struct should have been named SourceInfo or
    +  //   something instead.  Oh well.
    +  string leading_comments;
    +  string trailing_comments;
    +};
    +
    +// Describes a type of protocol message, or a particular group within a
    +// message.  To obtain the Descriptor for a given message object, call
    +// Message::GetDescriptor().  Generated message classes also have a
    +// static method called descriptor() which returns the type's descriptor.
    +// Use DescriptorPool to construct your own descriptors.
    +class LIBPROTOBUF_EXPORT Descriptor {
    + public:
    +  // The name of the message type, not including its scope.
    +  const string& name() const;
    +
    +  // The fully-qualified name of the message type, scope delimited by
    +  // periods.  For example, message type "Foo" which is declared in package
    +  // "bar" has full name "bar.Foo".  If a type "Baz" is nested within
    +  // Foo, Baz's full_name is "bar.Foo.Baz".  To get only the part that
    +  // comes after the last '.', use name().
    +  const string& full_name() const;
    +
    +  // Index of this descriptor within the file or containing type's message
    +  // type array.
    +  int index() const;
    +
    +  // The .proto file in which this message type was defined.  Never NULL.
    +  const FileDescriptor* file() const;
    +
    +  // If this Descriptor describes a nested type, this returns the type
    +  // in which it is nested.  Otherwise, returns NULL.
    +  const Descriptor* containing_type() const;
    +
    +  // Get options for this message type.  These are specified in the .proto file
    +  // by placing lines like "option foo = 1234;" in the message definition.
    +  // Allowed options are defined by MessageOptions in
    +  // google/protobuf/descriptor.proto, and any available extensions of that
    +  // message.
    +  const MessageOptions& options() const;
    +
    +  // Write the contents of this Descriptor into the given DescriptorProto.
    +  // The target DescriptorProto must be clear before calling this; if it
    +  // isn't, the result may be garbage.
    +  void CopyTo(DescriptorProto* proto) const;
    +
    +  // Write the contents of this decriptor in a human-readable form. Output
    +  // will be suitable for re-parsing.
    +  string DebugString() const;
    +
    +  // Returns true if this is a placeholder for an unknown type. This will
    +  // only be the case if this descriptor comes from a DescriptorPool
    +  // with AllowUnknownDependencies() set.
    +  bool is_placeholder() const;
    +
    +  // Field stuff -----------------------------------------------------
    +
    +  // The number of fields in this message type.
    +  int field_count() const;
    +  // Gets a field by index, where 0 <= index < field_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const FieldDescriptor* field(int index) const;
    +
    +  // Looks up a field by declared tag number.  Returns NULL if no such field
    +  // exists.
    +  const FieldDescriptor* FindFieldByNumber(int number) const;
    +  // Looks up a field by name.  Returns NULL if no such field exists.
    +  const FieldDescriptor* FindFieldByName(const string& name) const;
    +
    +  // Looks up a field by lowercased name (as returned by lowercase_name()).
    +  // This lookup may be ambiguous if multiple field names differ only by case,
    +  // in which case the field returned is chosen arbitrarily from the matches.
    +  const FieldDescriptor* FindFieldByLowercaseName(
    +      const string& lowercase_name) const;
    +
    +  // Looks up a field by camel-case name (as returned by camelcase_name()).
    +  // This lookup may be ambiguous if multiple field names differ in a way that
    +  // leads them to have identical camel-case names, in which case the field
    +  // returned is chosen arbitrarily from the matches.
    +  const FieldDescriptor* FindFieldByCamelcaseName(
    +      const string& camelcase_name) const;
    +
    +  // The number of oneofs in this message type.
    +  int oneof_decl_count() const;
    +  // Get a oneof by index, where 0 <= index < oneof_decl_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const OneofDescriptor* oneof_decl(int index) const;
    +
    +  // Looks up a oneof by name.  Returns NULL if no such oneof exists.
    +  const OneofDescriptor* FindOneofByName(const string& name) const;
    +
    +  // Nested type stuff -----------------------------------------------
    +
    +  // The number of nested types in this message type.
    +  int nested_type_count() const;
    +  // Gets a nested type by index, where 0 <= index < nested_type_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const Descriptor* nested_type(int index) const;
    +
    +  // Looks up a nested type by name.  Returns NULL if no such nested type
    +  // exists.
    +  const Descriptor* FindNestedTypeByName(const string& name) const;
    +
    +  // Enum stuff ------------------------------------------------------
    +
    +  // The number of enum types in this message type.
    +  int enum_type_count() const;
    +  // Gets an enum type by index, where 0 <= index < enum_type_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const EnumDescriptor* enum_type(int index) const;
    +
    +  // Looks up an enum type by name.  Returns NULL if no such enum type exists.
    +  const EnumDescriptor* FindEnumTypeByName(const string& name) const;
    +
    +  // Looks up an enum value by name, among all enum types in this message.
    +  // Returns NULL if no such value exists.
    +  const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
    +
    +  // Extensions ------------------------------------------------------
    +
    +  // A range of field numbers which are designated for third-party
    +  // extensions.
    +  struct ExtensionRange {
    +    int start;  // inclusive
    +    int end;    // exclusive
    +  };
    +
    +  // The number of extension ranges in this message type.
    +  int extension_range_count() const;
    +  // Gets an extension range by index, where 0 <= index <
    +  // extension_range_count(). These are returned in the order they were defined
    +  // in the .proto file.
    +  const ExtensionRange* extension_range(int index) const;
    +
    +  // Returns true if the number is in one of the extension ranges.
    +  bool IsExtensionNumber(int number) const;
    +
    +  // Returns NULL if no extension range contains the given number.
    +  const ExtensionRange* FindExtensionRangeContainingNumber(int number) const;
    +
    +  // The number of extensions -- extending *other* messages -- that were
    +  // defined nested within this message type's scope.
    +  int extension_count() const;
    +  // Get an extension by index, where 0 <= index < extension_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const FieldDescriptor* extension(int index) const;
    +
    +  // Looks up a named extension (which extends some *other* message type)
    +  // defined within this message type's scope.
    +  const FieldDescriptor* FindExtensionByName(const string& name) const;
    +
    +  // Similar to FindFieldByLowercaseName(), but finds extensions defined within
    +  // this message type's scope.
    +  const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
    +
    +  // Similar to FindFieldByCamelcaseName(), but finds extensions defined within
    +  // this message type's scope.
    +  const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
    +
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of this message declaration.  Returns false and leaves
    +  // |*out_location| unchanged iff location information was not available.
    +  bool GetSourceLocation(SourceLocation* out_location) const;
    +
    + private:
    +  typedef MessageOptions OptionsType;
    +
    +  // Internal version of DebugString; controls the level of indenting for
    +  // correct depth
    +  void DebugString(int depth, string *contents) const;
    +
    +  // Walks up the descriptor tree to generate the source location path
    +  // to this descriptor from the file root.
    +  void GetLocationPath(vector* output) const;
    +
    +  const string* name_;
    +  const string* full_name_;
    +  const FileDescriptor* file_;
    +  const Descriptor* containing_type_;
    +  const MessageOptions* options_;
    +
    +  // True if this is a placeholder for an unknown type.
    +  bool is_placeholder_;
    +  // True if this is a placeholder and the type name wasn't fully-qualified.
    +  bool is_unqualified_placeholder_;
    +
    +  int field_count_;
    +  FieldDescriptor* fields_;
    +  int oneof_decl_count_;
    +  OneofDescriptor* oneof_decls_;
    +  int nested_type_count_;
    +  Descriptor* nested_types_;
    +  int enum_type_count_;
    +  EnumDescriptor* enum_types_;
    +  int extension_range_count_;
    +  ExtensionRange* extension_ranges_;
    +  int extension_count_;
    +  FieldDescriptor* extensions_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray() in descriptor.cc
    +  // and update them to initialize the field.
    +
    +  // Must be constructed using DescriptorPool.
    +  Descriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class EnumDescriptor;
    +  friend class FieldDescriptor;
    +  friend class OneofDescriptor;
    +  friend class MethodDescriptor;
    +  friend class FileDescriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor);
    +};
    +
    +// Describes a single field of a message.  To get the descriptor for a given
    +// field, first get the Descriptor for the message in which it is defined,
    +// then call Descriptor::FindFieldByName().  To get a FieldDescriptor for
    +// an extension, do one of the following:
    +// - Get the Descriptor or FileDescriptor for its containing scope, then
    +//   call Descriptor::FindExtensionByName() or
    +//   FileDescriptor::FindExtensionByName().
    +// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber().
    +// - Given a Reflection for a message object, call
    +//   Reflection::FindKnownExtensionByName() or
    +//   Reflection::FindKnownExtensionByNumber().
    +// Use DescriptorPool to construct your own descriptors.
    +class LIBPROTOBUF_EXPORT FieldDescriptor {
    + public:
    +  // Identifies a field type.  0 is reserved for errors.  The order is weird
    +  // for historical reasons.  Types 12 and up are new in proto2.
    +  enum Type {
    +    TYPE_DOUBLE         = 1,   // double, exactly eight bytes on the wire.
    +    TYPE_FLOAT          = 2,   // float, exactly four bytes on the wire.
    +    TYPE_INT64          = 3,   // int64, varint on the wire.  Negative numbers
    +                               // take 10 bytes.  Use TYPE_SINT64 if negative
    +                               // values are likely.
    +    TYPE_UINT64         = 4,   // uint64, varint on the wire.
    +    TYPE_INT32          = 5,   // int32, varint on the wire.  Negative numbers
    +                               // take 10 bytes.  Use TYPE_SINT32 if negative
    +                               // values are likely.
    +    TYPE_FIXED64        = 6,   // uint64, exactly eight bytes on the wire.
    +    TYPE_FIXED32        = 7,   // uint32, exactly four bytes on the wire.
    +    TYPE_BOOL           = 8,   // bool, varint on the wire.
    +    TYPE_STRING         = 9,   // UTF-8 text.
    +    TYPE_GROUP          = 10,  // Tag-delimited message.  Deprecated.
    +    TYPE_MESSAGE        = 11,  // Length-delimited message.
    +
    +    TYPE_BYTES          = 12,  // Arbitrary byte array.
    +    TYPE_UINT32         = 13,  // uint32, varint on the wire
    +    TYPE_ENUM           = 14,  // Enum, varint on the wire
    +    TYPE_SFIXED32       = 15,  // int32, exactly four bytes on the wire
    +    TYPE_SFIXED64       = 16,  // int64, exactly eight bytes on the wire
    +    TYPE_SINT32         = 17,  // int32, ZigZag-encoded varint on the wire
    +    TYPE_SINT64         = 18,  // int64, ZigZag-encoded varint on the wire
    +
    +    MAX_TYPE            = 18,  // Constant useful for defining lookup tables
    +                               // indexed by Type.
    +  };
    +
    +  // Specifies the C++ data type used to represent the field.  There is a
    +  // fixed mapping from Type to CppType where each Type maps to exactly one
    +  // CppType.  0 is reserved for errors.
    +  enum CppType {
    +    CPPTYPE_INT32       = 1,     // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32
    +    CPPTYPE_INT64       = 2,     // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64
    +    CPPTYPE_UINT32      = 3,     // TYPE_UINT32, TYPE_FIXED32
    +    CPPTYPE_UINT64      = 4,     // TYPE_UINT64, TYPE_FIXED64
    +    CPPTYPE_DOUBLE      = 5,     // TYPE_DOUBLE
    +    CPPTYPE_FLOAT       = 6,     // TYPE_FLOAT
    +    CPPTYPE_BOOL        = 7,     // TYPE_BOOL
    +    CPPTYPE_ENUM        = 8,     // TYPE_ENUM
    +    CPPTYPE_STRING      = 9,     // TYPE_STRING, TYPE_BYTES
    +    CPPTYPE_MESSAGE     = 10,    // TYPE_MESSAGE, TYPE_GROUP
    +
    +    MAX_CPPTYPE         = 10,    // Constant useful for defining lookup tables
    +                                 // indexed by CppType.
    +  };
    +
    +  // Identifies whether the field is optional, required, or repeated.  0 is
    +  // reserved for errors.
    +  enum Label {
    +    LABEL_OPTIONAL      = 1,    // optional
    +    LABEL_REQUIRED      = 2,    // required
    +    LABEL_REPEATED      = 3,    // repeated
    +
    +    MAX_LABEL           = 3,    // Constant useful for defining lookup tables
    +                                // indexed by Label.
    +  };
    +
    +  // Valid field numbers are positive integers up to kMaxNumber.
    +  static const int kMaxNumber = (1 << 29) - 1;
    +
    +  // First field number reserved for the protocol buffer library implementation.
    +  // Users may not declare fields that use reserved numbers.
    +  static const int kFirstReservedNumber = 19000;
    +  // Last field number reserved for the protocol buffer library implementation.
    +  // Users may not declare fields that use reserved numbers.
    +  static const int kLastReservedNumber  = 19999;
    +
    +  const string& name() const;        // Name of this field within the message.
    +  const string& full_name() const;   // Fully-qualified name of the field.
    +  const FileDescriptor* file() const;// File in which this field was defined.
    +  bool is_extension() const;         // Is this an extension field?
    +  int number() const;                // Declared tag number.
    +
    +  // Same as name() except converted to lower-case.  This (and especially the
    +  // FindFieldByLowercaseName() method) can be useful when parsing formats
    +  // which prefer to use lowercase naming style.  (Although, technically
    +  // field names should be lowercased anyway according to the protobuf style
    +  // guide, so this only makes a difference when dealing with old .proto files
    +  // which do not follow the guide.)
    +  const string& lowercase_name() const;
    +
    +  // Same as name() except converted to camel-case.  In this conversion, any
    +  // time an underscore appears in the name, it is removed and the next
    +  // letter is capitalized.  Furthermore, the first letter of the name is
    +  // lower-cased.  Examples:
    +  //   FooBar -> fooBar
    +  //   foo_bar -> fooBar
    +  //   fooBar -> fooBar
    +  // This (and especially the FindFieldByCamelcaseName() method) can be useful
    +  // when parsing formats which prefer to use camel-case naming style.
    +  const string& camelcase_name() const;
    +
    +  Type type() const;                  // Declared type of this field.
    +  const char* type_name() const;      // Name of the declared type.
    +  CppType cpp_type() const;           // C++ type of this field.
    +  const char* cpp_type_name() const;  // Name of the C++ type.
    +  Label label() const;                // optional/required/repeated
    +
    +  bool is_required() const;      // shorthand for label() == LABEL_REQUIRED
    +  bool is_optional() const;      // shorthand for label() == LABEL_OPTIONAL
    +  bool is_repeated() const;      // shorthand for label() == LABEL_REPEATED
    +  bool is_packable() const;      // shorthand for is_repeated() &&
    +                                 //               IsTypePackable(type())
    +  bool is_packed() const;        // shorthand for is_packable() &&
    +                                 //               options().packed()
    +
    +  // Index of this field within the message's field array, or the file or
    +  // extension scope's extensions array.
    +  int index() const;
    +
    +  // Does this field have an explicitly-declared default value?
    +  bool has_default_value() const;
    +
    +  // Get the field default value if cpp_type() == CPPTYPE_INT32.  If no
    +  // explicit default was defined, the default is 0.
    +  int32 default_value_int32() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_INT64.  If no
    +  // explicit default was defined, the default is 0.
    +  int64 default_value_int64() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_UINT32.  If no
    +  // explicit default was defined, the default is 0.
    +  uint32 default_value_uint32() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_UINT64.  If no
    +  // explicit default was defined, the default is 0.
    +  uint64 default_value_uint64() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_FLOAT.  If no
    +  // explicit default was defined, the default is 0.0.
    +  float default_value_float() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_DOUBLE.  If no
    +  // explicit default was defined, the default is 0.0.
    +  double default_value_double() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_BOOL.  If no
    +  // explicit default was defined, the default is false.
    +  bool default_value_bool() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_ENUM.  If no
    +  // explicit default was defined, the default is the first value defined
    +  // in the enum type (all enum types are required to have at least one value).
    +  // This never returns NULL.
    +  const EnumValueDescriptor* default_value_enum() const;
    +  // Get the field default value if cpp_type() == CPPTYPE_STRING.  If no
    +  // explicit default was defined, the default is the empty string.
    +  const string& default_value_string() const;
    +
    +  // The Descriptor for the message of which this is a field.  For extensions,
    +  // this is the extended type.  Never NULL.
    +  const Descriptor* containing_type() const;
    +
    +  // If the field is a member of a oneof, this is the one, otherwise this is
    +  // NULL.
    +  const OneofDescriptor* containing_oneof() const;
    +
    +  // If the field is a member of a oneof, returns the index in that oneof.
    +  int index_in_oneof() const;
    +
    +  // An extension may be declared within the scope of another message.  If this
    +  // field is an extension (is_extension() is true), then extension_scope()
    +  // returns that message, or NULL if the extension was declared at global
    +  // scope.  If this is not an extension, extension_scope() is undefined (may
    +  // assert-fail).
    +  const Descriptor* extension_scope() const;
    +
    +  // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the
    +  // message or the group type.  Otherwise, returns null.
    +  const Descriptor* message_type() const;
    +  // If type is TYPE_ENUM, returns a descriptor for the enum.  Otherwise,
    +  // returns null.
    +  const EnumDescriptor* enum_type() const;
    +
    +  // EXPERIMENTAL; DO NOT USE.
    +  // If this field is a map field, experimental_map_key() is the field
    +  // that is the key for this map.
    +  // experimental_map_key()->containing_type() is the same as message_type().
    +  const FieldDescriptor* experimental_map_key() const;
    +
    +  // Get the FieldOptions for this field.  This includes things listed in
    +  // square brackets after the field definition.  E.g., the field:
    +  //   optional string text = 1 [ctype=CORD];
    +  // has the "ctype" option set.  Allowed options are defined by FieldOptions
    +  // in google/protobuf/descriptor.proto, and any available extensions of that
    +  // message.
    +  const FieldOptions& options() const;
    +
    +  // See Descriptor::CopyTo().
    +  void CopyTo(FieldDescriptorProto* proto) const;
    +
    +  // See Descriptor::DebugString().
    +  string DebugString() const;
    +
    +  // Helper method to get the CppType for a particular Type.
    +  static CppType TypeToCppType(Type type);
    +
    +  // Helper method to get the name of a Type.
    +  static const char* TypeName(Type type);
    +
    +  // Helper method to get the name of a CppType.
    +  static const char* CppTypeName(CppType cpp_type);
    +
    +  // Return true iff [packed = true] is valid for fields of this type.
    +  static inline bool IsTypePackable(Type field_type);
    +
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of this field declaration.  Returns false and leaves
    +  // |*out_location| unchanged iff location information was not available.
    +  bool GetSourceLocation(SourceLocation* out_location) const;
    +
    + private:
    +  typedef FieldOptions OptionsType;
    +
    +  // See Descriptor::DebugString().
    +  enum PrintLabelFlag { PRINT_LABEL, OMIT_LABEL };
    +  void DebugString(int depth, PrintLabelFlag print_label_flag,
    +                   string* contents) const;
    +
    +  // formats the default value appropriately and returns it as a string.
    +  // Must have a default value to call this. If quote_string_type is true, then
    +  // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped.
    +  string DefaultValueAsString(bool quote_string_type) const;
    +
    +  // Walks up the descriptor tree to generate the source location path
    +  // to this descriptor from the file root.
    +  void GetLocationPath(vector* output) const;
    +
    +  const string* name_;
    +  const string* full_name_;
    +  const string* lowercase_name_;
    +  const string* camelcase_name_;
    +  const FileDescriptor* file_;
    +  int number_;
    +  Type type_;
    +  Label label_;
    +  bool is_extension_;
    +  int index_in_oneof_;
    +  const Descriptor* containing_type_;
    +  const OneofDescriptor* containing_oneof_;
    +  const Descriptor* extension_scope_;
    +  const Descriptor* message_type_;
    +  const EnumDescriptor* enum_type_;
    +  const FieldDescriptor* experimental_map_key_;
    +  const FieldOptions* options_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray() in
    +  // descriptor.cc and update them to initialize the field.
    +
    +  bool has_default_value_;
    +  union {
    +    int32  default_value_int32_;
    +    int64  default_value_int64_;
    +    uint32 default_value_uint32_;
    +    uint64 default_value_uint64_;
    +    float  default_value_float_;
    +    double default_value_double_;
    +    bool   default_value_bool_;
    +
    +    const EnumValueDescriptor* default_value_enum_;
    +    const string* default_value_string_;
    +  };
    +
    +  static const CppType kTypeToCppTypeMap[MAX_TYPE + 1];
    +
    +  static const char * const kTypeToName[MAX_TYPE + 1];
    +
    +  static const char * const kCppTypeToName[MAX_CPPTYPE + 1];
    +
    +  static const char * const kLabelToName[MAX_LABEL + 1];
    +
    +  // Must be constructed using DescriptorPool.
    +  FieldDescriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class FileDescriptor;
    +  friend class Descriptor;
    +  friend class OneofDescriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor);
    +};
    +
    +// Describes a oneof defined in a message type.
    +class LIBPROTOBUF_EXPORT OneofDescriptor {
    + public:
    +  const string& name() const;       // Name of this oneof.
    +  const string& full_name() const;  // Fully-qualified name of the oneof.
    +
    +  // Index of this oneof within the message's oneof array.
    +  int index() const;
    +
    +  // The Descriptor for the message containing this oneof.
    +  const Descriptor* containing_type() const;
    +
    +  // The number of (non-extension) fields which are members of this oneof.
    +  int field_count() const;
    +  // Get a member of this oneof, in the order in which they were declared in the
    +  // .proto file.  Does not include extensions.
    +  const FieldDescriptor* field(int index) const;
    +
    +  // See Descriptor::CopyTo().
    +  void CopyTo(OneofDescriptorProto* proto) const;
    +
    +  // See Descriptor::DebugString().
    +  string DebugString() const;
    +
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of this oneof declaration.  Returns false and leaves
    +  // |*out_location| unchanged iff location information was not available.
    +  bool GetSourceLocation(SourceLocation* out_location) const;
    +
    + private:
    +  // See Descriptor::DebugString().
    +  void DebugString(int depth, string* contents) const;
    +
    +  // Walks up the descriptor tree to generate the source location path
    +  // to this descriptor from the file root.
    +  void GetLocationPath(vector* output) const;
    +
    +  const string* name_;
    +  const string* full_name_;
    +  const Descriptor* containing_type_;
    +  bool is_extendable_;
    +  int field_count_;
    +  const FieldDescriptor** fields_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray()
    +  // in descriptor.cc and update them to initialize the field.
    +
    +  // Must be constructed using DescriptorPool.
    +  OneofDescriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class Descriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofDescriptor);
    +};
    +
    +// Describes an enum type defined in a .proto file.  To get the EnumDescriptor
    +// for a generated enum type, call TypeName_descriptor().  Use DescriptorPool
    +// to construct your own descriptors.
    +class LIBPROTOBUF_EXPORT EnumDescriptor {
    + public:
    +  // The name of this enum type in the containing scope.
    +  const string& name() const;
    +
    +  // The fully-qualified name of the enum type, scope delimited by periods.
    +  const string& full_name() const;
    +
    +  // Index of this enum within the file or containing message's enum array.
    +  int index() const;
    +
    +  // The .proto file in which this enum type was defined.  Never NULL.
    +  const FileDescriptor* file() const;
    +
    +  // The number of values for this EnumDescriptor.  Guaranteed to be greater
    +  // than zero.
    +  int value_count() const;
    +  // Gets a value by index, where 0 <= index < value_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const EnumValueDescriptor* value(int index) const;
    +
    +  // Looks up a value by name.  Returns NULL if no such value exists.
    +  const EnumValueDescriptor* FindValueByName(const string& name) const;
    +  // Looks up a value by number.  Returns NULL if no such value exists.  If
    +  // multiple values have this number, the first one defined is returned.
    +  const EnumValueDescriptor* FindValueByNumber(int number) const;
    +
    +  // If this enum type is nested in a message type, this is that message type.
    +  // Otherwise, NULL.
    +  const Descriptor* containing_type() const;
    +
    +  // Get options for this enum type.  These are specified in the .proto file by
    +  // placing lines like "option foo = 1234;" in the enum definition.  Allowed
    +  // options are defined by EnumOptions in google/protobuf/descriptor.proto,
    +  // and any available extensions of that message.
    +  const EnumOptions& options() const;
    +
    +  // See Descriptor::CopyTo().
    +  void CopyTo(EnumDescriptorProto* proto) const;
    +
    +  // See Descriptor::DebugString().
    +  string DebugString() const;
    +
    +  // Returns true if this is a placeholder for an unknown enum. This will
    +  // only be the case if this descriptor comes from a DescriptorPool
    +  // with AllowUnknownDependencies() set.
    +  bool is_placeholder() const;
    +
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of this enum declaration.  Returns false and leaves
    +  // |*out_location| unchanged iff location information was not available.
    +  bool GetSourceLocation(SourceLocation* out_location) const;
    +
    + private:
    +  typedef EnumOptions OptionsType;
    +
    +  // See Descriptor::DebugString().
    +  void DebugString(int depth, string *contents) const;
    +
    +  // Walks up the descriptor tree to generate the source location path
    +  // to this descriptor from the file root.
    +  void GetLocationPath(vector* output) const;
    +
    +  const string* name_;
    +  const string* full_name_;
    +  const FileDescriptor* file_;
    +  const Descriptor* containing_type_;
    +  const EnumOptions* options_;
    +
    +  // True if this is a placeholder for an unknown type.
    +  bool is_placeholder_;
    +  // True if this is a placeholder and the type name wasn't fully-qualified.
    +  bool is_unqualified_placeholder_;
    +
    +  int value_count_;
    +  EnumValueDescriptor* values_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray() in
    +  // descriptor.cc and update them to initialize the field.
    +
    +  // Must be constructed using DescriptorPool.
    +  EnumDescriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class Descriptor;
    +  friend class FieldDescriptor;
    +  friend class EnumValueDescriptor;
    +  friend class FileDescriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
    +};
    +
    +// Describes an individual enum constant of a particular type.  To get the
    +// EnumValueDescriptor for a given enum value, first get the EnumDescriptor
    +// for its type, then use EnumDescriptor::FindValueByName() or
    +// EnumDescriptor::FindValueByNumber().  Use DescriptorPool to construct
    +// your own descriptors.
    +class LIBPROTOBUF_EXPORT EnumValueDescriptor {
    + public:
    +  const string& name() const;  // Name of this enum constant.
    +  int index() const;           // Index within the enums's Descriptor.
    +  int number() const;          // Numeric value of this enum constant.
    +
    +  // The full_name of an enum value is a sibling symbol of the enum type.
    +  // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually
    +  // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT
    +  // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32".  This is to conform
    +  // with C++ scoping rules for enums.
    +  const string& full_name() const;
    +
    +  // The type of this value.  Never NULL.
    +  const EnumDescriptor* type() const;
    +
    +  // Get options for this enum value.  These are specified in the .proto file
    +  // by adding text like "[foo = 1234]" after an enum value definition.
    +  // Allowed options are defined by EnumValueOptions in
    +  // google/protobuf/descriptor.proto, and any available extensions of that
    +  // message.
    +  const EnumValueOptions& options() const;
    +
    +  // See Descriptor::CopyTo().
    +  void CopyTo(EnumValueDescriptorProto* proto) const;
    +
    +  // See Descriptor::DebugString().
    +  string DebugString() const;
    +
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of this enum value declaration.  Returns false and leaves
    +  // |*out_location| unchanged iff location information was not available.
    +  bool GetSourceLocation(SourceLocation* out_location) const;
    +
    + private:
    +  typedef EnumValueOptions OptionsType;
    +
    +  // See Descriptor::DebugString().
    +  void DebugString(int depth, string *contents) const;
    +
    +  // Walks up the descriptor tree to generate the source location path
    +  // to this descriptor from the file root.
    +  void GetLocationPath(vector* output) const;
    +
    +  const string* name_;
    +  const string* full_name_;
    +  int number_;
    +  const EnumDescriptor* type_;
    +  const EnumValueOptions* options_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray()
    +  // in descriptor.cc and update them to initialize the field.
    +
    +  // Must be constructed using DescriptorPool.
    +  EnumValueDescriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class EnumDescriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
    +};
    +
    +// Describes an RPC service.  To get the ServiceDescriptor for a service,
    +// call Service::GetDescriptor().  Generated service classes also have a
    +// static method called descriptor() which returns the type's
    +// ServiceDescriptor.  Use DescriptorPool to construct your own descriptors.
    +class LIBPROTOBUF_EXPORT ServiceDescriptor {
    + public:
    +  // The name of the service, not including its containing scope.
    +  const string& name() const;
    +  // The fully-qualified name of the service, scope delimited by periods.
    +  const string& full_name() const;
    +  // Index of this service within the file's services array.
    +  int index() const;
    +
    +  // The .proto file in which this service was defined.  Never NULL.
    +  const FileDescriptor* file() const;
    +
    +  // Get options for this service type.  These are specified in the .proto file
    +  // by placing lines like "option foo = 1234;" in the service definition.
    +  // Allowed options are defined by ServiceOptions in
    +  // google/protobuf/descriptor.proto, and any available extensions of that
    +  // message.
    +  const ServiceOptions& options() const;
    +
    +  // The number of methods this service defines.
    +  int method_count() const;
    +  // Gets a MethodDescriptor by index, where 0 <= index < method_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const MethodDescriptor* method(int index) const;
    +
    +  // Look up a MethodDescriptor by name.
    +  const MethodDescriptor* FindMethodByName(const string& name) const;
    +  // See Descriptor::CopyTo().
    +  void CopyTo(ServiceDescriptorProto* proto) const;
    +
    +  // See Descriptor::DebugString().
    +  string DebugString() const;
    +
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of this service declaration.  Returns false and leaves
    +  // |*out_location| unchanged iff location information was not available.
    +  bool GetSourceLocation(SourceLocation* out_location) const;
    +
    + private:
    +  typedef ServiceOptions OptionsType;
    +
    +  // See Descriptor::DebugString().
    +  void DebugString(string *contents) const;
    +
    +  // Walks up the descriptor tree to generate the source location path
    +  // to this descriptor from the file root.
    +  void GetLocationPath(vector* output) const;
    +
    +  const string* name_;
    +  const string* full_name_;
    +  const FileDescriptor* file_;
    +  const ServiceOptions* options_;
    +  int method_count_;
    +  MethodDescriptor* methods_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray() in
    +  // descriptor.cc and update them to initialize the field.
    +
    +  // Must be constructed using DescriptorPool.
    +  ServiceDescriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class FileDescriptor;
    +  friend class MethodDescriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor);
    +};
    +
    +// Describes an individual service method.  To obtain a MethodDescriptor given
    +// a service, first get its ServiceDescriptor, then call
    +// ServiceDescriptor::FindMethodByName().  Use DescriptorPool to construct your
    +// own descriptors.
    +class LIBPROTOBUF_EXPORT MethodDescriptor {
    + public:
    +  // Name of this method, not including containing scope.
    +  const string& name() const;
    +  // The fully-qualified name of the method, scope delimited by periods.
    +  const string& full_name() const;
    +  // Index within the service's Descriptor.
    +  int index() const;
    +
    +  // Gets the service to which this method belongs.  Never NULL.
    +  const ServiceDescriptor* service() const;
    +
    +  // Gets the type of protocol message which this method accepts as input.
    +  const Descriptor* input_type() const;
    +  // Gets the type of protocol message which this message produces as output.
    +  const Descriptor* output_type() const;
    +
    +  // Get options for this method.  These are specified in the .proto file by
    +  // placing lines like "option foo = 1234;" in curly-braces after a method
    +  // declaration.  Allowed options are defined by MethodOptions in
    +  // google/protobuf/descriptor.proto, and any available extensions of that
    +  // message.
    +  const MethodOptions& options() const;
    +
    +  // See Descriptor::CopyTo().
    +  void CopyTo(MethodDescriptorProto* proto) const;
    +
    +  // See Descriptor::DebugString().
    +  string DebugString() const;
    +
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of this method declaration.  Returns false and leaves
    +  // |*out_location| unchanged iff location information was not available.
    +  bool GetSourceLocation(SourceLocation* out_location) const;
    +
    + private:
    +  typedef MethodOptions OptionsType;
    +
    +  // See Descriptor::DebugString().
    +  void DebugString(int depth, string *contents) const;
    +
    +  // Walks up the descriptor tree to generate the source location path
    +  // to this descriptor from the file root.
    +  void GetLocationPath(vector* output) const;
    +
    +  const string* name_;
    +  const string* full_name_;
    +  const ServiceDescriptor* service_;
    +  const Descriptor* input_type_;
    +  const Descriptor* output_type_;
    +  const MethodOptions* options_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray() in
    +  // descriptor.cc and update them to initialize the field.
    +
    +  // Must be constructed using DescriptorPool.
    +  MethodDescriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class ServiceDescriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor);
    +};
    +
    +
    +// Describes a whole .proto file.  To get the FileDescriptor for a compiled-in
    +// file, get the descriptor for something defined in that file and call
    +// descriptor->file().  Use DescriptorPool to construct your own descriptors.
    +class LIBPROTOBUF_EXPORT FileDescriptor {
    + public:
    +  // The filename, relative to the source tree.
    +  // e.g. "google/protobuf/descriptor.proto"
    +  const string& name() const;
    +
    +  // The package, e.g. "google.protobuf.compiler".
    +  const string& package() const;
    +
    +  // The DescriptorPool in which this FileDescriptor and all its contents were
    +  // allocated.  Never NULL.
    +  const DescriptorPool* pool() const;
    +
    +  // The number of files imported by this one.
    +  int dependency_count() const;
    +  // Gets an imported file by index, where 0 <= index < dependency_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const FileDescriptor* dependency(int index) const;
    +
    +  // The number of files public imported by this one.
    +  // The public dependency list is a subset of the dependency list.
    +  int public_dependency_count() const;
    +  // Gets a public imported file by index, where 0 <= index <
    +  // public_dependency_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const FileDescriptor* public_dependency(int index) const;
    +
    +  // The number of files that are imported for weak fields.
    +  // The weak dependency list is a subset of the dependency list.
    +  int weak_dependency_count() const;
    +  // Gets a weak imported file by index, where 0 <= index <
    +  // weak_dependency_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const FileDescriptor* weak_dependency(int index) const;
    +
    +  // Number of top-level message types defined in this file.  (This does not
    +  // include nested types.)
    +  int message_type_count() const;
    +  // Gets a top-level message type, where 0 <= index < message_type_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const Descriptor* message_type(int index) const;
    +
    +  // Number of top-level enum types defined in this file.  (This does not
    +  // include nested types.)
    +  int enum_type_count() const;
    +  // Gets a top-level enum type, where 0 <= index < enum_type_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const EnumDescriptor* enum_type(int index) const;
    +
    +  // Number of services defined in this file.
    +  int service_count() const;
    +  // Gets a service, where 0 <= index < service_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const ServiceDescriptor* service(int index) const;
    +
    +  // Number of extensions defined at file scope.  (This does not include
    +  // extensions nested within message types.)
    +  int extension_count() const;
    +  // Gets an extension's descriptor, where 0 <= index < extension_count().
    +  // These are returned in the order they were defined in the .proto file.
    +  const FieldDescriptor* extension(int index) const;
    +
    +  // Get options for this file.  These are specified in the .proto file by
    +  // placing lines like "option foo = 1234;" at the top level, outside of any
    +  // other definitions.  Allowed options are defined by FileOptions in
    +  // google/protobuf/descriptor.proto, and any available extensions of that
    +  // message.
    +  const FileOptions& options() const;
    +
    +  // Find a top-level message type by name.  Returns NULL if not found.
    +  const Descriptor* FindMessageTypeByName(const string& name) const;
    +  // Find a top-level enum type by name.  Returns NULL if not found.
    +  const EnumDescriptor* FindEnumTypeByName(const string& name) const;
    +  // Find an enum value defined in any top-level enum by name.  Returns NULL if
    +  // not found.
    +  const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
    +  // Find a service definition by name.  Returns NULL if not found.
    +  const ServiceDescriptor* FindServiceByName(const string& name) const;
    +  // Find a top-level extension definition by name.  Returns NULL if not found.
    +  const FieldDescriptor* FindExtensionByName(const string& name) const;
    +  // Similar to FindExtensionByName(), but searches by lowercased-name.  See
    +  // Descriptor::FindFieldByLowercaseName().
    +  const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
    +  // Similar to FindExtensionByName(), but searches by camelcased-name.  See
    +  // Descriptor::FindFieldByCamelcaseName().
    +  const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
    +
    +  // See Descriptor::CopyTo().
    +  // Notes:
    +  // - This method does NOT copy source code information since it is relatively
    +  //   large and rarely needed.  See CopySourceCodeInfoTo() below.
    +  void CopyTo(FileDescriptorProto* proto) const;
    +  // Write the source code information of this FileDescriptor into the given
    +  // FileDescriptorProto.  See CopyTo() above.
    +  void CopySourceCodeInfoTo(FileDescriptorProto* proto) const;
    +
    +  // See Descriptor::DebugString().
    +  string DebugString() const;
    +
    +  // Returns true if this is a placeholder for an unknown file. This will
    +  // only be the case if this descriptor comes from a DescriptorPool
    +  // with AllowUnknownDependencies() set.
    +  bool is_placeholder() const;
    +
    + private:
    +  // Source Location ---------------------------------------------------
    +
    +  // Updates |*out_location| to the source location of the complete
    +  // extent of the declaration or declaration-part denoted by |path|.
    +  // Returns false and leaves |*out_location| unchanged iff location
    +  // information was not available.  (See SourceCodeInfo for
    +  // description of path encoding.)
    +  bool GetSourceLocation(const vector& path,
    +                         SourceLocation* out_location) const;
    +
    +  typedef FileOptions OptionsType;
    +
    +  const string* name_;
    +  const string* package_;
    +  const DescriptorPool* pool_;
    +  int dependency_count_;
    +  const FileDescriptor** dependencies_;
    +  int public_dependency_count_;
    +  int* public_dependencies_;
    +  int weak_dependency_count_;
    +  int* weak_dependencies_;
    +  int message_type_count_;
    +  Descriptor* message_types_;
    +  int enum_type_count_;
    +  EnumDescriptor* enum_types_;
    +  int service_count_;
    +  ServiceDescriptor* services_;
    +  int extension_count_;
    +  bool is_placeholder_;
    +  FieldDescriptor* extensions_;
    +  const FileOptions* options_;
    +
    +  const FileDescriptorTables* tables_;
    +  const SourceCodeInfo* source_code_info_;
    +  // IMPORTANT:  If you add a new field, make sure to search for all instances
    +  // of Allocate() and AllocateArray() in
    +  // descriptor.cc and update them to initialize the field.
    +
    +  FileDescriptor() {}
    +  friend class DescriptorBuilder;
    +  friend class Descriptor;
    +  friend class FieldDescriptor;
    +  friend class OneofDescriptor;
    +  friend class EnumDescriptor;
    +  friend class EnumValueDescriptor;
    +  friend class MethodDescriptor;
    +  friend class ServiceDescriptor;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor);
    +};
    +
    +// ===================================================================
    +
    +// Used to construct descriptors.
    +//
    +// Normally you won't want to build your own descriptors.  Message classes
    +// constructed by the protocol compiler will provide them for you.  However,
    +// if you are implementing Message on your own, or if you are writing a
    +// program which can operate on totally arbitrary types and needs to load
    +// them from some sort of database, you might need to.
    +//
    +// Since Descriptors are composed of a whole lot of cross-linked bits of
    +// data that would be a pain to put together manually, the
    +// DescriptorPool class is provided to make the process easier.  It can
    +// take a FileDescriptorProto (defined in descriptor.proto), validate it,
    +// and convert it to a set of nicely cross-linked Descriptors.
    +//
    +// DescriptorPool also helps with memory management.  Descriptors are
    +// composed of many objects containing static data and pointers to each
    +// other.  In all likelihood, when it comes time to delete this data,
    +// you'll want to delete it all at once.  In fact, it is not uncommon to
    +// have a whole pool of descriptors all cross-linked with each other which
    +// you wish to delete all at once.  This class represents such a pool, and
    +// handles the memory management for you.
    +//
    +// You can also search for descriptors within a DescriptorPool by name, and
    +// extensions by number.
    +class LIBPROTOBUF_EXPORT DescriptorPool {
    + public:
    +  // Create a normal, empty DescriptorPool.
    +  DescriptorPool();
    +
    +  // Constructs a DescriptorPool that, when it can't find something among the
    +  // descriptors already in the pool, looks for it in the given
    +  // DescriptorDatabase.
    +  // Notes:
    +  // - If a DescriptorPool is constructed this way, its BuildFile*() methods
    +  //   must not be called (they will assert-fail).  The only way to populate
    +  //   the pool with descriptors is to call the Find*By*() methods.
    +  // - The Find*By*() methods may block the calling thread if the
    +  //   DescriptorDatabase blocks.  This in turn means that parsing messages
    +  //   may block if they need to look up extensions.
    +  // - The Find*By*() methods will use mutexes for thread-safety, thus making
    +  //   them slower even when they don't have to fall back to the database.
    +  //   In fact, even the Find*By*() methods of descriptor objects owned by
    +  //   this pool will be slower, since they will have to obtain locks too.
    +  // - An ErrorCollector may optionally be given to collect validation errors
    +  //   in files loaded from the database.  If not given, errors will be printed
    +  //   to GOOGLE_LOG(ERROR).  Remember that files are built on-demand, so this
    +  //   ErrorCollector may be called from any thread that calls one of the
    +  //   Find*By*() methods.
    +  // - The DescriptorDatabase must not be mutated during the lifetime of
    +  //   the DescriptorPool. Even if the client takes care to avoid data races,
    +  //   changes to the content of the DescriptorDatabase may not be reflected
    +  //   in subsequent lookups in the DescriptorPool.
    +  class ErrorCollector;
    +  explicit DescriptorPool(DescriptorDatabase* fallback_database,
    +                          ErrorCollector* error_collector = NULL);
    +
    +  ~DescriptorPool();
    +
    +  // Get a pointer to the generated pool.  Generated protocol message classes
    +  // which are compiled into the binary will allocate their descriptors in
    +  // this pool.  Do not add your own descriptors to this pool.
    +  static const DescriptorPool* generated_pool();
    +
    +  // Find a FileDescriptor in the pool by file name.  Returns NULL if not
    +  // found.
    +  const FileDescriptor* FindFileByName(const string& name) const;
    +
    +  // Find the FileDescriptor in the pool which defines the given symbol.
    +  // If any of the Find*ByName() methods below would succeed, then this is
    +  // equivalent to calling that method and calling the result's file() method.
    +  // Otherwise this returns NULL.
    +  const FileDescriptor* FindFileContainingSymbol(
    +      const string& symbol_name) const;
    +
    +  // Looking up descriptors ------------------------------------------
    +  // These find descriptors by fully-qualified name.  These will find both
    +  // top-level descriptors and nested descriptors.  They return NULL if not
    +  // found.
    +
    +  const Descriptor* FindMessageTypeByName(const string& name) const;
    +  const FieldDescriptor* FindFieldByName(const string& name) const;
    +  const FieldDescriptor* FindExtensionByName(const string& name) const;
    +  const OneofDescriptor* FindOneofByName(const string& name) const;
    +  const EnumDescriptor* FindEnumTypeByName(const string& name) const;
    +  const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
    +  const ServiceDescriptor* FindServiceByName(const string& name) const;
    +  const MethodDescriptor* FindMethodByName(const string& name) const;
    +
    +  // Finds an extension of the given type by number.  The extendee must be
    +  // a member of this DescriptorPool or one of its underlays.
    +  const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee,
    +                                               int number) const;
    +
    +  // Finds extensions of extendee. The extensions will be appended to
    +  // out in an undefined order. Only extensions defined directly in
    +  // this DescriptorPool or one of its underlays are guaranteed to be
    +  // found: extensions defined in the fallback database might not be found
    +  // depending on the database implementation.
    +  void FindAllExtensions(const Descriptor* extendee,
    +                         vector* out) const;
    +
    +  // Building descriptors --------------------------------------------
    +
    +  // When converting a FileDescriptorProto to a FileDescriptor, various
    +  // errors might be detected in the input.  The caller may handle these
    +  // programmatically by implementing an ErrorCollector.
    +  class LIBPROTOBUF_EXPORT ErrorCollector {
    +   public:
    +    inline ErrorCollector() {}
    +    virtual ~ErrorCollector();
    +
    +    // These constants specify what exact part of the construct is broken.
    +    // This is useful e.g. for mapping the error back to an exact location
    +    // in a .proto file.
    +    enum ErrorLocation {
    +      NAME,              // the symbol name, or the package name for files
    +      NUMBER,            // field or extension range number
    +      TYPE,              // field type
    +      EXTENDEE,          // field extendee
    +      DEFAULT_VALUE,     // field default value
    +      INPUT_TYPE,        // method input type
    +      OUTPUT_TYPE,       // method output type
    +      OPTION_NAME,       // name in assignment
    +      OPTION_VALUE,      // value in option assignment
    +      OTHER              // some other problem
    +    };
    +
    +    // Reports an error in the FileDescriptorProto. Use this function if the
    +    // problem occured should interrupt building the FileDescriptorProto.
    +    virtual void AddError(
    +      const string& filename,      // File name in which the error occurred.
    +      const string& element_name,  // Full name of the erroneous element.
    +      const Message* descriptor,   // Descriptor of the erroneous element.
    +      ErrorLocation location,      // One of the location constants, above.
    +      const string& message        // Human-readable error message.
    +      ) = 0;
    +
    +    // Reports a warning in the FileDescriptorProto. Use this function if the
    +    // problem occured should NOT interrupt building the FileDescriptorProto.
    +    virtual void AddWarning(
    +      const string& filename,      // File name in which the error occurred.
    +      const string& element_name,  // Full name of the erroneous element.
    +      const Message* descriptor,   // Descriptor of the erroneous element.
    +      ErrorLocation location,      // One of the location constants, above.
    +      const string& message        // Human-readable error message.
    +      ) {}
    +
    +   private:
    +    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
    +  };
    +
    +  // Convert the FileDescriptorProto to real descriptors and place them in
    +  // this DescriptorPool.  All dependencies of the file must already be in
    +  // the pool.  Returns the resulting FileDescriptor, or NULL if there were
    +  // problems with the input (e.g. the message was invalid, or dependencies
    +  // were missing).  Details about the errors are written to GOOGLE_LOG(ERROR).
    +  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
    +
    +  // Same as BuildFile() except errors are sent to the given ErrorCollector.
    +  const FileDescriptor* BuildFileCollectingErrors(
    +    const FileDescriptorProto& proto,
    +    ErrorCollector* error_collector);
    +
    +  // By default, it is an error if a FileDescriptorProto contains references
    +  // to types or other files that are not found in the DescriptorPool (or its
    +  // backing DescriptorDatabase, if any).  If you call
    +  // AllowUnknownDependencies(), however, then unknown types and files
    +  // will be replaced by placeholder descriptors (which can be identified by
    +  // the is_placeholder() method).  This can allow you to
    +  // perform some useful operations with a .proto file even if you do not
    +  // have access to other .proto files on which it depends.  However, some
    +  // heuristics must be used to fill in the gaps in information, and these
    +  // can lead to descriptors which are inaccurate.  For example, the
    +  // DescriptorPool may be forced to guess whether an unknown type is a message
    +  // or an enum, as well as what package it resides in.  Furthermore,
    +  // placeholder types will not be discoverable via FindMessageTypeByName()
    +  // and similar methods, which could confuse some descriptor-based algorithms.
    +  // Generally, the results of this option should be handled with extreme care.
    +  void AllowUnknownDependencies() { allow_unknown_ = true; }
    +
    +  // By default, weak imports are allowed to be missing, in which case we will
    +  // use a placeholder for the dependency and convert the field to be an Empty
    +  // message field. If you call EnforceWeakDependencies(true), however, the
    +  // DescriptorPool will report a import not found error.
    +  void EnforceWeakDependencies(bool enforce) { enforce_weak_ = enforce; }
    +
    +  // Internal stuff --------------------------------------------------
    +  // These methods MUST NOT be called from outside the proto2 library.
    +  // These methods may contain hidden pitfalls and may be removed in a
    +  // future library version.
    +
    +  // Create a DescriptorPool which is overlaid on top of some other pool.
    +  // If you search for a descriptor in the overlay and it is not found, the
    +  // underlay will be searched as a backup.  If the underlay has its own
    +  // underlay, that will be searched next, and so on.  This also means that
    +  // files built in the overlay will be cross-linked with the underlay's
    +  // descriptors if necessary.  The underlay remains property of the caller;
    +  // it must remain valid for the lifetime of the newly-constructed pool.
    +  //
    +  // Example:  Say you want to parse a .proto file at runtime in order to use
    +  // its type with a DynamicMessage.  Say this .proto file has dependencies,
    +  // but you know that all the dependencies will be things that are already
    +  // compiled into the binary.  For ease of use, you'd like to load the types
    +  // right out of generated_pool() rather than have to parse redundant copies
    +  // of all these .protos and runtime.  But, you don't want to add the parsed
    +  // types directly into generated_pool(): this is not allowed, and would be
    +  // bad design anyway.  So, instead, you could use generated_pool() as an
    +  // underlay for a new DescriptorPool in which you add only the new file.
    +  //
    +  // WARNING:  Use of underlays can lead to many subtle gotchas.  Instead,
    +  //   try to formulate what you want to do in terms of DescriptorDatabases.
    +  explicit DescriptorPool(const DescriptorPool* underlay);
    +
    +  // Called by generated classes at init time to add their descriptors to
    +  // generated_pool.  Do NOT call this in your own code!  filename must be a
    +  // permanent string (e.g. a string literal).
    +  static void InternalAddGeneratedFile(
    +      const void* encoded_file_descriptor, int size);
    +
    +
    +  // For internal use only:  Gets a non-const pointer to the generated pool.
    +  // This is called at static-initialization time only, so thread-safety is
    +  // not a concern.  If both an underlay and a fallback database are present,
    +  // the underlay takes precedence.
    +  static DescriptorPool* internal_generated_pool();
    +
    +  // For internal use only:  Changes the behavior of BuildFile() such that it
    +  // allows the file to make reference to message types declared in other files
    +  // which it did not officially declare as dependencies.
    +  void InternalDontEnforceDependencies();
    +
    +  // For internal use only.
    +  void internal_set_underlay(const DescriptorPool* underlay) {
    +    underlay_ = underlay;
    +  }
    +
    +  // For internal (unit test) use only:  Returns true if a FileDescriptor has
    +  // been constructed for the given file, false otherwise.  Useful for testing
    +  // lazy descriptor initialization behavior.
    +  bool InternalIsFileLoaded(const string& filename) const;
    +
    +
    +  // Add a file to unused_import_track_files_. DescriptorBuilder will log
    +  // warnings for those files if there is any unused import.
    +  void AddUnusedImportTrackFile(const string& file_name);
    +  void ClearUnusedImportTrackFiles();
    +
    + private:
    +  friend class Descriptor;
    +  friend class FieldDescriptor;
    +  friend class EnumDescriptor;
    +  friend class ServiceDescriptor;
    +  friend class FileDescriptor;
    +  friend class DescriptorBuilder;
    +
    +  // Return true if the given name is a sub-symbol of any non-package
    +  // descriptor that already exists in the descriptor pool.  (The full
    +  // definition of such types is already known.)
    +  bool IsSubSymbolOfBuiltType(const string& name) const;
    +
    +  // Tries to find something in the fallback database and link in the
    +  // corresponding proto file.  Returns true if successful, in which case
    +  // the caller should search for the thing again.  These are declared
    +  // const because they are called by (semantically) const methods.
    +  bool TryFindFileInFallbackDatabase(const string& name) const;
    +  bool TryFindSymbolInFallbackDatabase(const string& name) const;
    +  bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type,
    +                                          int field_number) const;
    +
    +  // Like BuildFile() but called internally when the file has been loaded from
    +  // fallback_database_.  Declared const because it is called by (semantically)
    +  // const methods.
    +  const FileDescriptor* BuildFileFromDatabase(
    +    const FileDescriptorProto& proto) const;
    +
    +  // If fallback_database_ is NULL, this is NULL.  Otherwise, this is a mutex
    +  // which must be locked while accessing tables_.
    +  Mutex* mutex_;
    +
    +  // See constructor.
    +  DescriptorDatabase* fallback_database_;
    +  ErrorCollector* default_error_collector_;
    +  const DescriptorPool* underlay_;
    +
    +  // This class contains a lot of hash maps with complicated types that
    +  // we'd like to keep out of the header.
    +  class Tables;
    +  scoped_ptr tables_;
    +
    +  bool enforce_dependencies_;
    +  bool allow_unknown_;
    +  bool enforce_weak_;
    +  std::set unused_import_track_files_;
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool);
    +};
    +
    +// inline methods ====================================================
    +
    +// These macros makes this repetitive code more readable.
    +#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \
    +  inline TYPE CLASS::FIELD() const { return FIELD##_; }
    +
    +// Strings fields are stored as pointers but returned as const references.
    +#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \
    +  inline const string& CLASS::FIELD() const { return *FIELD##_; }
    +
    +// Arrays take an index parameter, obviously.
    +#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \
    +  inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; }
    +
    +#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \
    +  inline const TYPE& CLASS::options() const { return *options_; }
    +
    +PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name)
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*)
    +
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, oneof_decl_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int)
    +
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, oneof_decl, const OneofDescriptor*)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*)
    +
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range,
    +                               const Descriptor::ExtensionRange*)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension,
    +                               const FieldDescriptor*)
    +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions);
    +PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool)
    +
    +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_oneof,
    +                         const OneofDescriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, index_in_oneof, int)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key,
    +                         const FieldDescriptor*)
    +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 )
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 )
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float )
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double)
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool  , bool  )
    +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum,
    +                         const EnumValueDescriptor*)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string)
    +
    +PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, full_name)
    +PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int)
    +
    +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name)
    +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value,
    +                               const EnumValueDescriptor*)
    +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions);
    +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, is_placeholder, bool)
    +
    +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name)
    +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int)
    +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*)
    +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions)
    +
    +PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name)
    +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method,
    +                               const MethodDescriptor*)
    +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions);
    +
    +PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name)
    +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*)
    +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*)
    +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions);
    +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name)
    +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, public_dependency_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_dependency_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int)
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int)
    +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions);
    +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, is_placeholder, bool)
    +
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service,
    +                               const ServiceDescriptor*)
    +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension,
    +                               const FieldDescriptor*)
    +
    +#undef PROTOBUF_DEFINE_ACCESSOR
    +#undef PROTOBUF_DEFINE_STRING_ACCESSOR
    +#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR
    +
    +// A few accessors differ from the macros...
    +
    +inline bool Descriptor::IsExtensionNumber(int number) const {
    +  return FindExtensionRangeContainingNumber(number) != NULL;
    +}
    +
    +inline bool FieldDescriptor::is_required() const {
    +  return label() == LABEL_REQUIRED;
    +}
    +
    +inline bool FieldDescriptor::is_optional() const {
    +  return label() == LABEL_OPTIONAL;
    +}
    +
    +inline bool FieldDescriptor::is_repeated() const {
    +  return label() == LABEL_REPEATED;
    +}
    +
    +inline bool FieldDescriptor::is_packable() const {
    +  return is_repeated() && IsTypePackable(type());
    +}
    +
    +// To save space, index() is computed by looking at the descriptor's position
    +// in the parent's array of children.
    +inline int FieldDescriptor::index() const {
    +  if (!is_extension_) {
    +    return static_cast(this - containing_type_->fields_);
    +  } else if (extension_scope_ != NULL) {
    +    return static_cast(this - extension_scope_->extensions_);
    +  } else {
    +    return static_cast(this - file_->extensions_);
    +  }
    +}
    +
    +inline int Descriptor::index() const {
    +  if (containing_type_ == NULL) {
    +    return static_cast(this - file_->message_types_);
    +  } else {
    +    return static_cast(this - containing_type_->nested_types_);
    +  }
    +}
    +
    +inline int OneofDescriptor::index() const {
    +  return static_cast(this - containing_type_->oneof_decls_);
    +}
    +
    +inline int EnumDescriptor::index() const {
    +  if (containing_type_ == NULL) {
    +    return static_cast(this - file_->enum_types_);
    +  } else {
    +    return static_cast(this - containing_type_->enum_types_);
    +  }
    +}
    +
    +inline int EnumValueDescriptor::index() const {
    +  return static_cast(this - type_->values_);
    +}
    +
    +inline int ServiceDescriptor::index() const {
    +  return static_cast(this - file_->services_);
    +}
    +
    +inline int MethodDescriptor::index() const {
    +  return static_cast(this - service_->methods_);
    +}
    +
    +inline const char* FieldDescriptor::type_name() const {
    +  return kTypeToName[type_];
    +}
    +
    +inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
    +  return kTypeToCppTypeMap[type_];
    +}
    +
    +inline const char* FieldDescriptor::cpp_type_name() const {
    +  return kCppTypeToName[kTypeToCppTypeMap[type_]];
    +}
    +
    +inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) {
    +  return kTypeToCppTypeMap[type];
    +}
    +
    +inline const char* FieldDescriptor::TypeName(Type type) {
    +  return kTypeToName[type];
    +}
    +
    +inline const char* FieldDescriptor::CppTypeName(CppType cpp_type) {
    +  return kCppTypeToName[cpp_type];
    +}
    +
    +inline bool FieldDescriptor::IsTypePackable(Type field_type) {
    +  return (field_type != FieldDescriptor::TYPE_STRING &&
    +          field_type != FieldDescriptor::TYPE_GROUP &&
    +          field_type != FieldDescriptor::TYPE_MESSAGE &&
    +          field_type != FieldDescriptor::TYPE_BYTES);
    +}
    +
    +inline const FileDescriptor* FileDescriptor::dependency(int index) const {
    +  return dependencies_[index];
    +}
    +
    +inline const FileDescriptor* FileDescriptor::public_dependency(
    +    int index) const {
    +  return dependencies_[public_dependencies_[index]];
    +}
    +
    +inline const FileDescriptor* FileDescriptor::weak_dependency(
    +    int index) const {
    +  return dependencies_[weak_dependencies_[index]];
    +}
    +
    +// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array
    +// of pointers rather than the usual array of objects.
    +inline const FieldDescriptor* OneofDescriptor::field(int index) const {
    +  return fields_[index];
    +}
    +
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc
    new file mode 100644
    index 000000000000..c3aa2fb68f0c
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc
    @@ -0,0 +1,9135 @@
    +// Generated by the protocol buffer compiler.  DO NOT EDIT!
    +// source: google/protobuf/descriptor.proto
    +
    +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
    +#include "google/protobuf/descriptor.pb.h"
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +// @@protoc_insertion_point(includes)
    +
    +namespace google {
    +namespace protobuf {
    +
    +namespace {
    +
    +const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  FileDescriptorSet_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  FileDescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  DescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  DescriptorProto_ExtensionRange_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  FieldDescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL;
    +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL;
    +const ::google::protobuf::Descriptor* OneofDescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  OneofDescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  EnumDescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  EnumValueDescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  ServiceDescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  MethodDescriptorProto_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  FileOptions_reflection_ = NULL;
    +const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL;
    +const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  MessageOptions_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  FieldOptions_reflection_ = NULL;
    +const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL;
    +const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  EnumOptions_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  EnumValueOptions_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  ServiceOptions_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  MethodOptions_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* UninterpretedOption_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  UninterpretedOption_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  UninterpretedOption_NamePart_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  SourceCodeInfo_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  SourceCodeInfo_Location_reflection_ = NULL;
    +
    +}  // namespace
    +
    +
    +void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
    +  protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  const ::google::protobuf::FileDescriptor* file =
    +    ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
    +      "google/protobuf/descriptor.proto");
    +  GOOGLE_CHECK(file != NULL);
    +  FileDescriptorSet_descriptor_ = file->message_type(0);
    +  static const int FileDescriptorSet_offsets_[1] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_),
    +  };
    +  FileDescriptorSet_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      FileDescriptorSet_descriptor_,
    +      FileDescriptorSet::default_instance_,
    +      FileDescriptorSet_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(FileDescriptorSet));
    +  FileDescriptorProto_descriptor_ = file->message_type(1);
    +  static const int FileDescriptorProto_offsets_[11] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, public_dependency_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, weak_dependency_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_),
    +  };
    +  FileDescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      FileDescriptorProto_descriptor_,
    +      FileDescriptorProto::default_instance_,
    +      FileDescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(FileDescriptorProto));
    +  DescriptorProto_descriptor_ = file->message_type(2);
    +  static const int DescriptorProto_offsets_[8] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, oneof_decl_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_),
    +  };
    +  DescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      DescriptorProto_descriptor_,
    +      DescriptorProto::default_instance_,
    +      DescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(DescriptorProto));
    +  DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0);
    +  static const int DescriptorProto_ExtensionRange_offsets_[2] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_),
    +  };
    +  DescriptorProto_ExtensionRange_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      DescriptorProto_ExtensionRange_descriptor_,
    +      DescriptorProto_ExtensionRange::default_instance_,
    +      DescriptorProto_ExtensionRange_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(DescriptorProto_ExtensionRange));
    +  FieldDescriptorProto_descriptor_ = file->message_type(3);
    +  static const int FieldDescriptorProto_offsets_[9] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, oneof_index_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_),
    +  };
    +  FieldDescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      FieldDescriptorProto_descriptor_,
    +      FieldDescriptorProto::default_instance_,
    +      FieldDescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(FieldDescriptorProto));
    +  FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
    +  FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
    +  OneofDescriptorProto_descriptor_ = file->message_type(4);
    +  static const int OneofDescriptorProto_offsets_[1] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, name_),
    +  };
    +  OneofDescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      OneofDescriptorProto_descriptor_,
    +      OneofDescriptorProto::default_instance_,
    +      OneofDescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(OneofDescriptorProto));
    +  EnumDescriptorProto_descriptor_ = file->message_type(5);
    +  static const int EnumDescriptorProto_offsets_[3] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_),
    +  };
    +  EnumDescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      EnumDescriptorProto_descriptor_,
    +      EnumDescriptorProto::default_instance_,
    +      EnumDescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(EnumDescriptorProto));
    +  EnumValueDescriptorProto_descriptor_ = file->message_type(6);
    +  static const int EnumValueDescriptorProto_offsets_[3] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_),
    +  };
    +  EnumValueDescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      EnumValueDescriptorProto_descriptor_,
    +      EnumValueDescriptorProto::default_instance_,
    +      EnumValueDescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(EnumValueDescriptorProto));
    +  ServiceDescriptorProto_descriptor_ = file->message_type(7);
    +  static const int ServiceDescriptorProto_offsets_[3] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_),
    +  };
    +  ServiceDescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      ServiceDescriptorProto_descriptor_,
    +      ServiceDescriptorProto::default_instance_,
    +      ServiceDescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(ServiceDescriptorProto));
    +  MethodDescriptorProto_descriptor_ = file->message_type(8);
    +  static const int MethodDescriptorProto_offsets_[4] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, options_),
    +  };
    +  MethodDescriptorProto_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      MethodDescriptorProto_descriptor_,
    +      MethodDescriptorProto::default_instance_,
    +      MethodDescriptorProto_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(MethodDescriptorProto));
    +  FileOptions_descriptor_ = file->message_type(9);
    +  static const int FileOptions_offsets_[12] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generate_equals_and_hash_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_string_check_utf8_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, go_package_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
    +  };
    +  FileOptions_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      FileOptions_descriptor_,
    +      FileOptions::default_instance_,
    +      FileOptions_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_),
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(FileOptions));
    +  FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
    +  MessageOptions_descriptor_ = file->message_type(10);
    +  static const int MessageOptions_offsets_[4] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, deprecated_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_),
    +  };
    +  MessageOptions_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      MessageOptions_descriptor_,
    +      MessageOptions::default_instance_,
    +      MessageOptions_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_),
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(MessageOptions));
    +  FieldOptions_descriptor_ = file->message_type(11);
    +  static const int FieldOptions_offsets_[7] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, lazy_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_),
    +  };
    +  FieldOptions_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      FieldOptions_descriptor_,
    +      FieldOptions::default_instance_,
    +      FieldOptions_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_),
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(FieldOptions));
    +  FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
    +  EnumOptions_descriptor_ = file->message_type(12);
    +  static const int EnumOptions_offsets_[3] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, deprecated_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_),
    +  };
    +  EnumOptions_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      EnumOptions_descriptor_,
    +      EnumOptions::default_instance_,
    +      EnumOptions_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_),
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(EnumOptions));
    +  EnumValueOptions_descriptor_ = file->message_type(13);
    +  static const int EnumValueOptions_offsets_[2] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_),
    +  };
    +  EnumValueOptions_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      EnumValueOptions_descriptor_,
    +      EnumValueOptions::default_instance_,
    +      EnumValueOptions_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_),
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(EnumValueOptions));
    +  ServiceOptions_descriptor_ = file->message_type(14);
    +  static const int ServiceOptions_offsets_[2] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_),
    +  };
    +  ServiceOptions_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      ServiceOptions_descriptor_,
    +      ServiceOptions::default_instance_,
    +      ServiceOptions_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_),
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(ServiceOptions));
    +  MethodOptions_descriptor_ = file->message_type(15);
    +  static const int MethodOptions_offsets_[2] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_),
    +  };
    +  MethodOptions_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      MethodOptions_descriptor_,
    +      MethodOptions::default_instance_,
    +      MethodOptions_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_),
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(MethodOptions));
    +  UninterpretedOption_descriptor_ = file->message_type(16);
    +  static const int UninterpretedOption_offsets_[7] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_),
    +  };
    +  UninterpretedOption_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      UninterpretedOption_descriptor_,
    +      UninterpretedOption::default_instance_,
    +      UninterpretedOption_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(UninterpretedOption));
    +  UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0);
    +  static const int UninterpretedOption_NamePart_offsets_[2] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_),
    +  };
    +  UninterpretedOption_NamePart_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      UninterpretedOption_NamePart_descriptor_,
    +      UninterpretedOption_NamePart::default_instance_,
    +      UninterpretedOption_NamePart_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(UninterpretedOption_NamePart));
    +  SourceCodeInfo_descriptor_ = file->message_type(17);
    +  static const int SourceCodeInfo_offsets_[1] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
    +  };
    +  SourceCodeInfo_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      SourceCodeInfo_descriptor_,
    +      SourceCodeInfo::default_instance_,
    +      SourceCodeInfo_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(SourceCodeInfo));
    +  SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
    +  static const int SourceCodeInfo_Location_offsets_[4] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_comments_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, trailing_comments_),
    +  };
    +  SourceCodeInfo_Location_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      SourceCodeInfo_Location_descriptor_,
    +      SourceCodeInfo_Location::default_instance_,
    +      SourceCodeInfo_Location_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(SourceCodeInfo_Location));
    +}
    +
    +namespace {
    +
    +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
    +inline void protobuf_AssignDescriptorsOnce() {
    +  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
    +                 &protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto);
    +}
    +
    +void protobuf_RegisterTypes(const ::std::string&) {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    DescriptorProto_descriptor_, &DescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    OneofDescriptorProto_descriptor_, &OneofDescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    FileOptions_descriptor_, &FileOptions::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    MessageOptions_descriptor_, &MessageOptions::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    FieldOptions_descriptor_, &FieldOptions::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    EnumOptions_descriptor_, &EnumOptions::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    EnumValueOptions_descriptor_, &EnumValueOptions::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    ServiceOptions_descriptor_, &ServiceOptions::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    MethodOptions_descriptor_, &MethodOptions::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    UninterpretedOption_descriptor_, &UninterpretedOption::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance());
    +}
    +
    +}  // namespace
    +
    +void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
    +  delete FileDescriptorSet::default_instance_;
    +  delete FileDescriptorSet_reflection_;
    +  delete FileDescriptorProto::default_instance_;
    +  delete FileDescriptorProto_reflection_;
    +  delete DescriptorProto::default_instance_;
    +  delete DescriptorProto_reflection_;
    +  delete DescriptorProto_ExtensionRange::default_instance_;
    +  delete DescriptorProto_ExtensionRange_reflection_;
    +  delete FieldDescriptorProto::default_instance_;
    +  delete FieldDescriptorProto_reflection_;
    +  delete OneofDescriptorProto::default_instance_;
    +  delete OneofDescriptorProto_reflection_;
    +  delete EnumDescriptorProto::default_instance_;
    +  delete EnumDescriptorProto_reflection_;
    +  delete EnumValueDescriptorProto::default_instance_;
    +  delete EnumValueDescriptorProto_reflection_;
    +  delete ServiceDescriptorProto::default_instance_;
    +  delete ServiceDescriptorProto_reflection_;
    +  delete MethodDescriptorProto::default_instance_;
    +  delete MethodDescriptorProto_reflection_;
    +  delete FileOptions::default_instance_;
    +  delete FileOptions_reflection_;
    +  delete MessageOptions::default_instance_;
    +  delete MessageOptions_reflection_;
    +  delete FieldOptions::default_instance_;
    +  delete FieldOptions_reflection_;
    +  delete EnumOptions::default_instance_;
    +  delete EnumOptions_reflection_;
    +  delete EnumValueOptions::default_instance_;
    +  delete EnumValueOptions_reflection_;
    +  delete ServiceOptions::default_instance_;
    +  delete ServiceOptions_reflection_;
    +  delete MethodOptions::default_instance_;
    +  delete MethodOptions_reflection_;
    +  delete UninterpretedOption::default_instance_;
    +  delete UninterpretedOption_reflection_;
    +  delete UninterpretedOption_NamePart::default_instance_;
    +  delete UninterpretedOption_NamePart_reflection_;
    +  delete SourceCodeInfo::default_instance_;
    +  delete SourceCodeInfo_reflection_;
    +  delete SourceCodeInfo_Location::default_instance_;
    +  delete SourceCodeInfo_Location_reflection_;
    +}
    +
    +void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
    +  static bool already_here = false;
    +  if (already_here) return;
    +  already_here = true;
    +  GOOGLE_PROTOBUF_VERIFY_VERSION;
    +
    +  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
    +    "\n google/protobuf/descriptor.proto\022\017goog"
    +    "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
    +    "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
    +    "roto\"\313\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
    +    "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
    +    "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
    +    "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
    +    "le.protobuf.DescriptorProto\0227\n\tenum_type"
    +    "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
    +    "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
    +    "ServiceDescriptorProto\0228\n\textension\030\007 \003("
    +    "\0132%.google.protobuf.FieldDescriptorProto"
    +    "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
    +    "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
    +    "le.protobuf.SourceCodeInfo\"\344\003\n\017Descripto"
    +    "rProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.go"
    +    "ogle.protobuf.FieldDescriptorProto\0228\n\tex"
    +    "tension\030\006 \003(\0132%.google.protobuf.FieldDes"
    +    "criptorProto\0225\n\013nested_type\030\003 \003(\0132 .goog"
    +    "le.protobuf.DescriptorProto\0227\n\tenum_type"
    +    "\030\004 \003(\0132$.google.protobuf.EnumDescriptorP"
    +    "roto\022H\n\017extension_range\030\005 \003(\0132/.google.p"
    +    "rotobuf.DescriptorProto.ExtensionRange\0229"
    +    "\n\noneof_decl\030\010 \003(\0132%.google.protobuf.One"
    +    "ofDescriptorProto\0220\n\007options\030\007 \001(\0132\037.goo"
    +    "gle.protobuf.MessageOptions\032,\n\016Extension"
    +    "Range\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\251\005\n\024Fi"
    +    "eldDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numb"
    +    "er\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobu"
    +    "f.FieldDescriptorProto.Label\0228\n\004type\030\005 \001"
    +    "(\0162*.google.protobuf.FieldDescriptorProt"
    +    "o.Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 "
    +    "\001(\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_inde"
    +    "x\030\t \001(\005\022.\n\007options\030\010 \001(\0132\035.google.protob"
    +    "uf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020"
    +    "\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYP"
    +    "E_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED"
    +    "64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n"
    +    "\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_M"
    +    "ESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020"
    +    "\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rT"
    +    "YPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_"
    +    "SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n"
    +    "\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"$\n"
    +    "\024OneofDescriptorProto\022\014\n\004name\030\001 \001(\t\"\214\001\n\023"
    +    "EnumDescriptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005val"
    +    "ue\030\002 \003(\0132).google.protobuf.EnumValueDesc"
    +    "riptorProto\022-\n\007options\030\003 \001(\0132\034.google.pr"
    +    "otobuf.EnumOptions\"l\n\030EnumValueDescripto"
    +    "rProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007"
    +    "options\030\003 \001(\0132!.google.protobuf.EnumValu"
    +    "eOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n\004n"
    +    "ame\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.proto"
    +    "buf.MethodDescriptorProto\0220\n\007options\030\003 \001"
    +    "(\0132\037.google.protobuf.ServiceOptions\"\177\n\025M"
    +    "ethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\nin"
    +    "put_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007o"
    +    "ptions\030\004 \001(\0132\036.google.protobuf.MethodOpt"
    +    "ions\"\253\004\n\013FileOptions\022\024\n\014java_package\030\001 \001"
    +    "(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023java"
    +    "_multiple_files\030\n \001(\010:\005false\022,\n\035java_gen"
    +    "erate_equals_and_hash\030\024 \001(\010:\005false\022%\n\026ja"
    +    "va_string_check_utf8\030\033 \001(\010:\005false\022F\n\014opt"
    +    "imize_for\030\t \001(\0162).google.protobuf.FileOp"
    +    "tions.OptimizeMode:\005SPEED\022\022\n\ngo_package\030"
    +    "\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fals"
    +    "e\022$\n\025java_generic_services\030\021 \001(\010:\005false\022"
    +    "\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031\n\nd"
    +    "eprecated\030\027 \001(\010:\005false\022C\n\024uninterpreted_"
    +    "option\030\347\007 \003(\0132$.google.protobuf.Uninterp"
    +    "retedOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r"
    +    "\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200"
    +    "\200\002\"\323\001\n\016MessageOptions\022&\n\027message_set_wir"
    +    "e_format\030\001 \001(\010:\005false\022.\n\037no_standard_des"
    +    "criptor_accessor\030\002 \001(\010:\005false\022\031\n\ndepreca"
    +    "ted\030\003 \001(\010:\005false\022C\n\024uninterpreted_option"
    +    "\030\347\007 \003(\0132$.google.protobuf.UninterpretedO"
    +    "ption*\t\010\350\007\020\200\200\200\200\002\"\276\002\n\014FieldOptions\022:\n\005cty"
    +    "pe\030\001 \001(\0162#.google.protobuf.FieldOptions."
    +    "CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030\005 "
    +    "\001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\034\n"
    +    "\024experimental_map_key\030\t \001(\t\022\023\n\004weak\030\n \001("
    +    "\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132"
    +    "$.google.protobuf.UninterpretedOption\"/\n"
    +    "\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_P"
    +    "IECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013all"
    +    "ow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005fals"
    +    "e\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl"
    +    "e.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200"
    +    "\002\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001("
    +    "\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132"
    +    "$.google.protobuf.UninterpretedOption*\t\010"
    +    "\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated"
    +    "\030! \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007"
    +    " \003(\0132$.google.protobuf.UninterpretedOpti"
    +    "on*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptions\022\031\n\ndeprec"
    +    "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio"
    +    "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
    +    "Option*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOptio"
    +    "n\022;\n\004name\030\002 \003(\0132-.google.protobuf.Uninte"
    +    "rpretedOption.NamePart\022\030\n\020identifier_val"
    +    "ue\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022"
    +    "negative_int_value\030\005 \001(\003\022\024\n\014double_value"
    +    "\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggregat"
    +    "e_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_part\030\001"
    +    " \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\261\001\n\016SourceCod"
    +    "eInfo\022:\n\010location\030\001 \003(\0132(.google.protobu"
    +    "f.SourceCodeInfo.Location\032c\n\010Location\022\020\n"
    +    "\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020lea"
    +    "ding_comments\030\003 \001(\t\022\031\n\021trailing_comments"
    +    "\030\004 \001(\tB)\n\023com.google.protobufB\020Descripto"
    +    "rProtosH\001", 4449);
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    +    "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
    +  FileDescriptorSet::default_instance_ = new FileDescriptorSet();
    +  FileDescriptorProto::default_instance_ = new FileDescriptorProto();
    +  DescriptorProto::default_instance_ = new DescriptorProto();
    +  DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange();
    +  FieldDescriptorProto::default_instance_ = new FieldDescriptorProto();
    +  OneofDescriptorProto::default_instance_ = new OneofDescriptorProto();
    +  EnumDescriptorProto::default_instance_ = new EnumDescriptorProto();
    +  EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto();
    +  ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto();
    +  MethodDescriptorProto::default_instance_ = new MethodDescriptorProto();
    +  FileOptions::default_instance_ = new FileOptions();
    +  MessageOptions::default_instance_ = new MessageOptions();
    +  FieldOptions::default_instance_ = new FieldOptions();
    +  EnumOptions::default_instance_ = new EnumOptions();
    +  EnumValueOptions::default_instance_ = new EnumValueOptions();
    +  ServiceOptions::default_instance_ = new ServiceOptions();
    +  MethodOptions::default_instance_ = new MethodOptions();
    +  UninterpretedOption::default_instance_ = new UninterpretedOption();
    +  UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart();
    +  SourceCodeInfo::default_instance_ = new SourceCodeInfo();
    +  SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location();
    +  FileDescriptorSet::default_instance_->InitAsDefaultInstance();
    +  FileDescriptorProto::default_instance_->InitAsDefaultInstance();
    +  DescriptorProto::default_instance_->InitAsDefaultInstance();
    +  DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance();
    +  FieldDescriptorProto::default_instance_->InitAsDefaultInstance();
    +  OneofDescriptorProto::default_instance_->InitAsDefaultInstance();
    +  EnumDescriptorProto::default_instance_->InitAsDefaultInstance();
    +  EnumValueDescriptorProto::default_instance_->InitAsDefaultInstance();
    +  ServiceDescriptorProto::default_instance_->InitAsDefaultInstance();
    +  MethodDescriptorProto::default_instance_->InitAsDefaultInstance();
    +  FileOptions::default_instance_->InitAsDefaultInstance();
    +  MessageOptions::default_instance_->InitAsDefaultInstance();
    +  FieldOptions::default_instance_->InitAsDefaultInstance();
    +  EnumOptions::default_instance_->InitAsDefaultInstance();
    +  EnumValueOptions::default_instance_->InitAsDefaultInstance();
    +  ServiceOptions::default_instance_->InitAsDefaultInstance();
    +  MethodOptions::default_instance_->InitAsDefaultInstance();
    +  UninterpretedOption::default_instance_->InitAsDefaultInstance();
    +  UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance();
    +  SourceCodeInfo::default_instance_->InitAsDefaultInstance();
    +  SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance();
    +  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto);
    +}
    +
    +// Force AddDescriptors() to be called at static initialization time.
    +struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
    +  StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() {
    +    protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  }
    +} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int FileDescriptorSet::kFileFieldNumber;
    +#endif  // !_MSC_VER
    +
    +FileDescriptorSet::FileDescriptorSet()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorSet)
    +}
    +
    +void FileDescriptorSet::InitAsDefaultInstance() {
    +}
    +
    +FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
    +}
    +
    +void FileDescriptorSet::SharedCtor() {
    +  _cached_size_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +FileDescriptorSet::~FileDescriptorSet() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet)
    +  SharedDtor();
    +}
    +
    +void FileDescriptorSet::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void FileDescriptorSet::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FileDescriptorSet_descriptor_;
    +}
    +
    +const FileDescriptorSet& FileDescriptorSet::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL;
    +
    +FileDescriptorSet* FileDescriptorSet::New() const {
    +  return new FileDescriptorSet;
    +}
    +
    +void FileDescriptorSet::Clear() {
    +  file_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool FileDescriptorSet::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorSet)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // repeated .google.protobuf.FileDescriptorProto file = 1;
    +      case 1: {
    +        if (tag == 10) {
    +         parse_file:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_file()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(10)) goto parse_file;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorSet)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorSet)
    +  return false;
    +#undef DO_
    +}
    +
    +void FileDescriptorSet::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorSet)
    +  // repeated .google.protobuf.FileDescriptorProto file = 1;
    +  for (int i = 0; i < this->file_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      1, this->file(i), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorSet)
    +}
    +
    +::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet)
    +  // repeated .google.protobuf.FileDescriptorProto file = 1;
    +  for (int i = 0; i < this->file_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        1, this->file(i), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet)
    +  return target;
    +}
    +
    +int FileDescriptorSet::ByteSize() const {
    +  int total_size = 0;
    +
    +  // repeated .google.protobuf.FileDescriptorProto file = 1;
    +  total_size += 1 * this->file_size();
    +  for (int i = 0; i < this->file_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->file(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const FileDescriptorSet* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  file_.MergeFrom(from.file_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool FileDescriptorSet::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->file())) return false;
    +  return true;
    +}
    +
    +void FileDescriptorSet::Swap(FileDescriptorSet* other) {
    +  if (other != this) {
    +    file_.Swap(&other->file_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = FileDescriptorSet_descriptor_;
    +  metadata.reflection = FileDescriptorSet_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int FileDescriptorProto::kNameFieldNumber;
    +const int FileDescriptorProto::kPackageFieldNumber;
    +const int FileDescriptorProto::kDependencyFieldNumber;
    +const int FileDescriptorProto::kPublicDependencyFieldNumber;
    +const int FileDescriptorProto::kWeakDependencyFieldNumber;
    +const int FileDescriptorProto::kMessageTypeFieldNumber;
    +const int FileDescriptorProto::kEnumTypeFieldNumber;
    +const int FileDescriptorProto::kServiceFieldNumber;
    +const int FileDescriptorProto::kExtensionFieldNumber;
    +const int FileDescriptorProto::kOptionsFieldNumber;
    +const int FileDescriptorProto::kSourceCodeInfoFieldNumber;
    +#endif  // !_MSC_VER
    +
    +FileDescriptorProto::FileDescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorProto)
    +}
    +
    +void FileDescriptorProto::InitAsDefaultInstance() {
    +  options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance());
    +  source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance());
    +}
    +
    +FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
    +}
    +
    +void FileDescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  options_ = NULL;
    +  source_code_info_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +FileDescriptorProto::~FileDescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto)
    +  SharedDtor();
    +}
    +
    +void FileDescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete package_;
    +  }
    +  if (this != default_instance_) {
    +    delete options_;
    +    delete source_code_info_;
    +  }
    +}
    +
    +void FileDescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FileDescriptorProto_descriptor_;
    +}
    +
    +const FileDescriptorProto& FileDescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL;
    +
    +FileDescriptorProto* FileDescriptorProto::New() const {
    +  return new FileDescriptorProto;
    +}
    +
    +void FileDescriptorProto::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    if (has_package()) {
    +      if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        package_->clear();
    +      }
    +    }
    +  }
    +  if (_has_bits_[8 / 32] & 1536) {
    +    if (has_options()) {
    +      if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
    +    }
    +    if (has_source_code_info()) {
    +      if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
    +    }
    +  }
    +  dependency_.Clear();
    +  public_dependency_.Clear();
    +  weak_dependency_.Clear();
    +  message_type_.Clear();
    +  enum_type_.Clear();
    +  service_.Clear();
    +  extension_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool FileDescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_package;
    +        break;
    +      }
    +
    +      // optional string package = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_package:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_package()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->package().data(), this->package().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "package");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_dependency;
    +        break;
    +      }
    +
    +      // repeated string dependency = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_dependency:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->add_dependency()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->dependency(this->dependency_size() - 1).data(),
    +            this->dependency(this->dependency_size() - 1).length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "dependency");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_dependency;
    +        if (input->ExpectTag(34)) goto parse_message_type;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.DescriptorProto message_type = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_message_type:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_message_type()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_message_type;
    +        if (input->ExpectTag(42)) goto parse_enum_type;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
    +      case 5: {
    +        if (tag == 42) {
    +         parse_enum_type:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_enum_type()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(42)) goto parse_enum_type;
    +        if (input->ExpectTag(50)) goto parse_service;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.ServiceDescriptorProto service = 6;
    +      case 6: {
    +        if (tag == 50) {
    +         parse_service:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_service()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(50)) goto parse_service;
    +        if (input->ExpectTag(58)) goto parse_extension;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
    +      case 7: {
    +        if (tag == 58) {
    +         parse_extension:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_extension()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(58)) goto parse_extension;
    +        if (input->ExpectTag(66)) goto parse_options;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.FileOptions options = 8;
    +      case 8: {
    +        if (tag == 66) {
    +         parse_options:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_options()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(74)) goto parse_source_code_info;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    +      case 9: {
    +        if (tag == 74) {
    +         parse_source_code_info:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_source_code_info()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(80)) goto parse_public_dependency;
    +        break;
    +      }
    +
    +      // repeated int32 public_dependency = 10;
    +      case 10: {
    +        if (tag == 80) {
    +         parse_public_dependency:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 1, 80, input, this->mutable_public_dependency())));
    +        } else if (tag == 82) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, this->mutable_public_dependency())));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(80)) goto parse_public_dependency;
    +        if (input->ExpectTag(88)) goto parse_weak_dependency;
    +        break;
    +      }
    +
    +      // repeated int32 weak_dependency = 11;
    +      case 11: {
    +        if (tag == 88) {
    +         parse_weak_dependency:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 1, 88, input, this->mutable_weak_dependency())));
    +        } else if (tag == 90) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, this->mutable_weak_dependency())));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(88)) goto parse_weak_dependency;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void FileDescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // optional string package = 2;
    +  if (has_package()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->package().data(), this->package().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "package");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->package(), output);
    +  }
    +
    +  // repeated string dependency = 3;
    +  for (int i = 0; i < this->dependency_size(); i++) {
    +  ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +    this->dependency(i).data(), this->dependency(i).length(),
    +    ::google::protobuf::internal::WireFormat::SERIALIZE,
    +    "dependency");
    +    ::google::protobuf::internal::WireFormatLite::WriteString(
    +      3, this->dependency(i), output);
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto message_type = 4;
    +  for (int i = 0; i < this->message_type_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      4, this->message_type(i), output);
    +  }
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
    +  for (int i = 0; i < this->enum_type_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      5, this->enum_type(i), output);
    +  }
    +
    +  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
    +  for (int i = 0; i < this->service_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      6, this->service(i), output);
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
    +  for (int i = 0; i < this->extension_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      7, this->extension(i), output);
    +  }
    +
    +  // optional .google.protobuf.FileOptions options = 8;
    +  if (has_options()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      8, this->options(), output);
    +  }
    +
    +  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    +  if (has_source_code_info()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      9, this->source_code_info(), output);
    +  }
    +
    +  // repeated int32 public_dependency = 10;
    +  for (int i = 0; i < this->public_dependency_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(
    +      10, this->public_dependency(i), output);
    +  }
    +
    +  // repeated int32 weak_dependency = 11;
    +  for (int i = 0; i < this->weak_dependency_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(
    +      11, this->weak_dependency(i), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorProto)
    +}
    +
    +::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  // optional string package = 2;
    +  if (has_package()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->package().data(), this->package().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "package");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        2, this->package(), target);
    +  }
    +
    +  // repeated string dependency = 3;
    +  for (int i = 0; i < this->dependency_size(); i++) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->dependency(i).data(), this->dependency(i).length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "dependency");
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteStringToArray(3, this->dependency(i), target);
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto message_type = 4;
    +  for (int i = 0; i < this->message_type_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        4, this->message_type(i), target);
    +  }
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
    +  for (int i = 0; i < this->enum_type_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        5, this->enum_type(i), target);
    +  }
    +
    +  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
    +  for (int i = 0; i < this->service_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        6, this->service(i), target);
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
    +  for (int i = 0; i < this->extension_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        7, this->extension(i), target);
    +  }
    +
    +  // optional .google.protobuf.FileOptions options = 8;
    +  if (has_options()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        8, this->options(), target);
    +  }
    +
    +  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    +  if (has_source_code_info()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        9, this->source_code_info(), target);
    +  }
    +
    +  // repeated int32 public_dependency = 10;
    +  for (int i = 0; i < this->public_dependency_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteInt32ToArray(10, this->public_dependency(i), target);
    +  }
    +
    +  // repeated int32 weak_dependency = 11;
    +  for (int i = 0; i < this->weak_dependency_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteInt32ToArray(11, this->weak_dependency(i), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto)
    +  return target;
    +}
    +
    +int FileDescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional string package = 2;
    +    if (has_package()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->package());
    +    }
    +
    +  }
    +  if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) {
    +    // optional .google.protobuf.FileOptions options = 8;
    +    if (has_options()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->options());
    +    }
    +
    +    // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    +    if (has_source_code_info()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->source_code_info());
    +    }
    +
    +  }
    +  // repeated string dependency = 3;
    +  total_size += 1 * this->dependency_size();
    +  for (int i = 0; i < this->dependency_size(); i++) {
    +    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
    +      this->dependency(i));
    +  }
    +
    +  // repeated int32 public_dependency = 10;
    +  {
    +    int data_size = 0;
    +    for (int i = 0; i < this->public_dependency_size(); i++) {
    +      data_size += ::google::protobuf::internal::WireFormatLite::
    +        Int32Size(this->public_dependency(i));
    +    }
    +    total_size += 1 * this->public_dependency_size() + data_size;
    +  }
    +
    +  // repeated int32 weak_dependency = 11;
    +  {
    +    int data_size = 0;
    +    for (int i = 0; i < this->weak_dependency_size(); i++) {
    +      data_size += ::google::protobuf::internal::WireFormatLite::
    +        Int32Size(this->weak_dependency(i));
    +    }
    +    total_size += 1 * this->weak_dependency_size() + data_size;
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto message_type = 4;
    +  total_size += 1 * this->message_type_size();
    +  for (int i = 0; i < this->message_type_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->message_type(i));
    +  }
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
    +  total_size += 1 * this->enum_type_size();
    +  for (int i = 0; i < this->enum_type_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->enum_type(i));
    +  }
    +
    +  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
    +  total_size += 1 * this->service_size();
    +  for (int i = 0; i < this->service_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->service(i));
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
    +  total_size += 1 * this->extension_size();
    +  for (int i = 0; i < this->extension_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->extension(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const FileDescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  dependency_.MergeFrom(from.dependency_);
    +  public_dependency_.MergeFrom(from.public_dependency_);
    +  weak_dependency_.MergeFrom(from.weak_dependency_);
    +  message_type_.MergeFrom(from.message_type_);
    +  enum_type_.MergeFrom(from.enum_type_);
    +  service_.MergeFrom(from.service_);
    +  extension_.MergeFrom(from.extension_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_package()) {
    +      set_package(from.package());
    +    }
    +  }
    +  if (from._has_bits_[9 / 32] & (0xffu << (9 % 32))) {
    +    if (from.has_options()) {
    +      mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
    +    }
    +    if (from.has_source_code_info()) {
    +      mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool FileDescriptorProto::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->message_type())) return false;
    +  if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
    +  if (!::google::protobuf::internal::AllAreInitialized(this->service())) return false;
    +  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
    +  if (has_options()) {
    +    if (!this->options().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void FileDescriptorProto::Swap(FileDescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    std::swap(package_, other->package_);
    +    dependency_.Swap(&other->dependency_);
    +    public_dependency_.Swap(&other->public_dependency_);
    +    weak_dependency_.Swap(&other->weak_dependency_);
    +    message_type_.Swap(&other->message_type_);
    +    enum_type_.Swap(&other->enum_type_);
    +    service_.Swap(&other->service_);
    +    extension_.Swap(&other->extension_);
    +    std::swap(options_, other->options_);
    +    std::swap(source_code_info_, other->source_code_info_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = FileDescriptorProto_descriptor_;
    +  metadata.reflection = FileDescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int DescriptorProto_ExtensionRange::kStartFieldNumber;
    +const int DescriptorProto_ExtensionRange::kEndFieldNumber;
    +#endif  // !_MSC_VER
    +
    +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ExtensionRange)
    +}
    +
    +void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {
    +}
    +
    +DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
    +}
    +
    +void DescriptorProto_ExtensionRange::SharedCtor() {
    +  _cached_size_ = 0;
    +  start_ = 0;
    +  end_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange)
    +  SharedDtor();
    +}
    +
    +void DescriptorProto_ExtensionRange::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return DescriptorProto_ExtensionRange_descriptor_;
    +}
    +
    +const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL;
    +
    +DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const {
    +  return new DescriptorProto_ExtensionRange;
    +}
    +
    +void DescriptorProto_ExtensionRange::Clear() {
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(start_, end_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ExtensionRange)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional int32 start = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &start_)));
    +          set_has_start();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_end;
    +        break;
    +      }
    +
    +      // optional int32 end = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_end:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &end_)));
    +          set_has_end();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto.ExtensionRange)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto.ExtensionRange)
    +  return false;
    +#undef DO_
    +}
    +
    +void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ExtensionRange)
    +  // optional int32 start = 1;
    +  if (has_start()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
    +  }
    +
    +  // optional int32 end = 2;
    +  if (has_end()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ExtensionRange)
    +}
    +
    +::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange)
    +  // optional int32 start = 1;
    +  if (has_start()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
    +  }
    +
    +  // optional int32 end = 2;
    +  if (has_end()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange)
    +  return target;
    +}
    +
    +int DescriptorProto_ExtensionRange::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional int32 start = 1;
    +    if (has_start()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->start());
    +    }
    +
    +    // optional int32 end = 2;
    +    if (has_end()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->end());
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const DescriptorProto_ExtensionRange* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_start()) {
    +      set_start(from.start());
    +    }
    +    if (from.has_end()) {
    +      set_end(from.end());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool DescriptorProto_ExtensionRange::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) {
    +  if (other != this) {
    +    std::swap(start_, other->start_);
    +    std::swap(end_, other->end_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = DescriptorProto_ExtensionRange_descriptor_;
    +  metadata.reflection = DescriptorProto_ExtensionRange_reflection_;
    +  return metadata;
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int DescriptorProto::kNameFieldNumber;
    +const int DescriptorProto::kFieldFieldNumber;
    +const int DescriptorProto::kExtensionFieldNumber;
    +const int DescriptorProto::kNestedTypeFieldNumber;
    +const int DescriptorProto::kEnumTypeFieldNumber;
    +const int DescriptorProto::kExtensionRangeFieldNumber;
    +const int DescriptorProto::kOneofDeclFieldNumber;
    +const int DescriptorProto::kOptionsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +DescriptorProto::DescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto)
    +}
    +
    +void DescriptorProto::InitAsDefaultInstance() {
    +  options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance());
    +}
    +
    +DescriptorProto::DescriptorProto(const DescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
    +}
    +
    +void DescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  options_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +DescriptorProto::~DescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto)
    +  SharedDtor();
    +}
    +
    +void DescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (this != default_instance_) {
    +    delete options_;
    +  }
    +}
    +
    +void DescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return DescriptorProto_descriptor_;
    +}
    +
    +const DescriptorProto& DescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +DescriptorProto* DescriptorProto::default_instance_ = NULL;
    +
    +DescriptorProto* DescriptorProto::New() const {
    +  return new DescriptorProto;
    +}
    +
    +void DescriptorProto::Clear() {
    +  if (_has_bits_[0 / 32] & 129) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    if (has_options()) {
    +      if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
    +    }
    +  }
    +  field_.Clear();
    +  extension_.Clear();
    +  nested_type_.Clear();
    +  enum_type_.Clear();
    +  extension_range_.Clear();
    +  oneof_decl_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool DescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_field;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.FieldDescriptorProto field = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_field:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_field()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_field;
    +        if (input->ExpectTag(26)) goto parse_nested_type;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.DescriptorProto nested_type = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_nested_type:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_nested_type()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_nested_type;
    +        if (input->ExpectTag(34)) goto parse_enum_type;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_enum_type:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_enum_type()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_enum_type;
    +        if (input->ExpectTag(42)) goto parse_extension_range;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
    +      case 5: {
    +        if (tag == 42) {
    +         parse_extension_range:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_extension_range()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(42)) goto parse_extension_range;
    +        if (input->ExpectTag(50)) goto parse_extension;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.FieldDescriptorProto extension = 6;
    +      case 6: {
    +        if (tag == 50) {
    +         parse_extension:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_extension()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(50)) goto parse_extension;
    +        if (input->ExpectTag(58)) goto parse_options;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.MessageOptions options = 7;
    +      case 7: {
    +        if (tag == 58) {
    +         parse_options:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_options()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(66)) goto parse_oneof_decl;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
    +      case 8: {
    +        if (tag == 66) {
    +         parse_oneof_decl:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_oneof_decl()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(66)) goto parse_oneof_decl;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void DescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto field = 2;
    +  for (int i = 0; i < this->field_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      2, this->field(i), output);
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto nested_type = 3;
    +  for (int i = 0; i < this->nested_type_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      3, this->nested_type(i), output);
    +  }
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
    +  for (int i = 0; i < this->enum_type_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      4, this->enum_type(i), output);
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
    +  for (int i = 0; i < this->extension_range_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      5, this->extension_range(i), output);
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
    +  for (int i = 0; i < this->extension_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      6, this->extension(i), output);
    +  }
    +
    +  // optional .google.protobuf.MessageOptions options = 7;
    +  if (has_options()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      7, this->options(), output);
    +  }
    +
    +  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
    +  for (int i = 0; i < this->oneof_decl_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      8, this->oneof_decl(i), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto)
    +}
    +
    +::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto field = 2;
    +  for (int i = 0; i < this->field_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        2, this->field(i), target);
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto nested_type = 3;
    +  for (int i = 0; i < this->nested_type_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        3, this->nested_type(i), target);
    +  }
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
    +  for (int i = 0; i < this->enum_type_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        4, this->enum_type(i), target);
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
    +  for (int i = 0; i < this->extension_range_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        5, this->extension_range(i), target);
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
    +  for (int i = 0; i < this->extension_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        6, this->extension(i), target);
    +  }
    +
    +  // optional .google.protobuf.MessageOptions options = 7;
    +  if (has_options()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        7, this->options(), target);
    +  }
    +
    +  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
    +  for (int i = 0; i < this->oneof_decl_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        8, this->oneof_decl(i), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto)
    +  return target;
    +}
    +
    +int DescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional .google.protobuf.MessageOptions options = 7;
    +    if (has_options()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->options());
    +    }
    +
    +  }
    +  // repeated .google.protobuf.FieldDescriptorProto field = 2;
    +  total_size += 1 * this->field_size();
    +  for (int i = 0; i < this->field_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->field(i));
    +  }
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
    +  total_size += 1 * this->extension_size();
    +  for (int i = 0; i < this->extension_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->extension(i));
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto nested_type = 3;
    +  total_size += 1 * this->nested_type_size();
    +  for (int i = 0; i < this->nested_type_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->nested_type(i));
    +  }
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
    +  total_size += 1 * this->enum_type_size();
    +  for (int i = 0; i < this->enum_type_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->enum_type(i));
    +  }
    +
    +  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
    +  total_size += 1 * this->extension_range_size();
    +  for (int i = 0; i < this->extension_range_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->extension_range(i));
    +  }
    +
    +  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
    +  total_size += 1 * this->oneof_decl_size();
    +  for (int i = 0; i < this->oneof_decl_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->oneof_decl(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const DescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void DescriptorProto::MergeFrom(const DescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  field_.MergeFrom(from.field_);
    +  extension_.MergeFrom(from.extension_);
    +  nested_type_.MergeFrom(from.nested_type_);
    +  enum_type_.MergeFrom(from.enum_type_);
    +  extension_range_.MergeFrom(from.extension_range_);
    +  oneof_decl_.MergeFrom(from.oneof_decl_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_options()) {
    +      mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void DescriptorProto::CopyFrom(const DescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool DescriptorProto::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->field())) return false;
    +  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
    +  if (!::google::protobuf::internal::AllAreInitialized(this->nested_type())) return false;
    +  if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
    +  if (has_options()) {
    +    if (!this->options().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void DescriptorProto::Swap(DescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    field_.Swap(&other->field_);
    +    extension_.Swap(&other->extension_);
    +    nested_type_.Swap(&other->nested_type_);
    +    enum_type_.Swap(&other->enum_type_);
    +    extension_range_.Swap(&other->extension_range_);
    +    oneof_decl_.Swap(&other->oneof_decl_);
    +    std::swap(options_, other->options_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata DescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = DescriptorProto_descriptor_;
    +  metadata.reflection = DescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FieldDescriptorProto_Type_descriptor_;
    +}
    +bool FieldDescriptorProto_Type_IsValid(int value) {
    +  switch(value) {
    +    case 1:
    +    case 2:
    +    case 3:
    +    case 4:
    +    case 5:
    +    case 6:
    +    case 7:
    +    case 8:
    +    case 9:
    +    case 10:
    +    case 11:
    +    case 12:
    +    case 13:
    +    case 14:
    +    case 15:
    +    case 16:
    +    case 17:
    +    case 18:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
    +const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
    +const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
    +const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
    +const int FieldDescriptorProto::Type_ARRAYSIZE;
    +#endif  // _MSC_VER
    +const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FieldDescriptorProto_Label_descriptor_;
    +}
    +bool FieldDescriptorProto_Label_IsValid(int value) {
    +  switch(value) {
    +    case 1:
    +    case 2:
    +    case 3:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
    +const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
    +const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
    +const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
    +const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
    +const int FieldDescriptorProto::Label_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int FieldDescriptorProto::kNameFieldNumber;
    +const int FieldDescriptorProto::kNumberFieldNumber;
    +const int FieldDescriptorProto::kLabelFieldNumber;
    +const int FieldDescriptorProto::kTypeFieldNumber;
    +const int FieldDescriptorProto::kTypeNameFieldNumber;
    +const int FieldDescriptorProto::kExtendeeFieldNumber;
    +const int FieldDescriptorProto::kDefaultValueFieldNumber;
    +const int FieldDescriptorProto::kOneofIndexFieldNumber;
    +const int FieldDescriptorProto::kOptionsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +FieldDescriptorProto::FieldDescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.FieldDescriptorProto)
    +}
    +
    +void FieldDescriptorProto::InitAsDefaultInstance() {
    +  options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance());
    +}
    +
    +FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
    +}
    +
    +void FieldDescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  number_ = 0;
    +  label_ = 1;
    +  type_ = 1;
    +  type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  oneof_index_ = 0;
    +  options_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +FieldDescriptorProto::~FieldDescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto)
    +  SharedDtor();
    +}
    +
    +void FieldDescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete type_name_;
    +  }
    +  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete extendee_;
    +  }
    +  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete default_value_;
    +  }
    +  if (this != default_instance_) {
    +    delete options_;
    +  }
    +}
    +
    +void FieldDescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FieldDescriptorProto_descriptor_;
    +}
    +
    +const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL;
    +
    +FieldDescriptorProto* FieldDescriptorProto::New() const {
    +  return new FieldDescriptorProto;
    +}
    +
    +void FieldDescriptorProto::Clear() {
    +  if (_has_bits_[0 / 32] & 255) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    number_ = 0;
    +    label_ = 1;
    +    type_ = 1;
    +    if (has_type_name()) {
    +      if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        type_name_->clear();
    +      }
    +    }
    +    if (has_extendee()) {
    +      if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        extendee_->clear();
    +      }
    +    }
    +    if (has_default_value()) {
    +      if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        default_value_->clear();
    +      }
    +    }
    +    oneof_index_ = 0;
    +  }
    +  if (has_options()) {
    +    if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool FieldDescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.FieldDescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_extendee;
    +        break;
    +      }
    +
    +      // optional string extendee = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_extendee:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_extendee()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->extendee().data(), this->extendee().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "extendee");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_number;
    +        break;
    +      }
    +
    +      // optional int32 number = 3;
    +      case 3: {
    +        if (tag == 24) {
    +         parse_number:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &number_)));
    +          set_has_number();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_label;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_label:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) {
    +            set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
    +          } else {
    +            mutable_unknown_fields()->AddVarint(4, value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(40)) goto parse_type;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    +      case 5: {
    +        if (tag == 40) {
    +         parse_type:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) {
    +            set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
    +          } else {
    +            mutable_unknown_fields()->AddVarint(5, value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(50)) goto parse_type_name;
    +        break;
    +      }
    +
    +      // optional string type_name = 6;
    +      case 6: {
    +        if (tag == 50) {
    +         parse_type_name:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_type_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->type_name().data(), this->type_name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "type_name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(58)) goto parse_default_value;
    +        break;
    +      }
    +
    +      // optional string default_value = 7;
    +      case 7: {
    +        if (tag == 58) {
    +         parse_default_value:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_default_value()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->default_value().data(), this->default_value().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "default_value");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(66)) goto parse_options;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.FieldOptions options = 8;
    +      case 8: {
    +        if (tag == 66) {
    +         parse_options:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_options()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(72)) goto parse_oneof_index;
    +        break;
    +      }
    +
    +      // optional int32 oneof_index = 9;
    +      case 9: {
    +        if (tag == 72) {
    +         parse_oneof_index:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &oneof_index_)));
    +          set_has_oneof_index();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.FieldDescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.FieldDescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void FieldDescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.FieldDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // optional string extendee = 2;
    +  if (has_extendee()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->extendee().data(), this->extendee().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "extendee");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->extendee(), output);
    +  }
    +
    +  // optional int32 number = 3;
    +  if (has_number()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
    +  }
    +
    +  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    +  if (has_label()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      4, this->label(), output);
    +  }
    +
    +  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    +  if (has_type()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      5, this->type(), output);
    +  }
    +
    +  // optional string type_name = 6;
    +  if (has_type_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->type_name().data(), this->type_name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "type_name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      6, this->type_name(), output);
    +  }
    +
    +  // optional string default_value = 7;
    +  if (has_default_value()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->default_value().data(), this->default_value().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "default_value");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      7, this->default_value(), output);
    +  }
    +
    +  // optional .google.protobuf.FieldOptions options = 8;
    +  if (has_options()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      8, this->options(), output);
    +  }
    +
    +  // optional int32 oneof_index = 9;
    +  if (has_oneof_index()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->oneof_index(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.FieldDescriptorProto)
    +}
    +
    +::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  // optional string extendee = 2;
    +  if (has_extendee()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->extendee().data(), this->extendee().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "extendee");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        2, this->extendee(), target);
    +  }
    +
    +  // optional int32 number = 3;
    +  if (has_number()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
    +  }
    +
    +  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    +  if (has_label()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
    +      4, this->label(), target);
    +  }
    +
    +  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    +  if (has_type()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
    +      5, this->type(), target);
    +  }
    +
    +  // optional string type_name = 6;
    +  if (has_type_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->type_name().data(), this->type_name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "type_name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        6, this->type_name(), target);
    +  }
    +
    +  // optional string default_value = 7;
    +  if (has_default_value()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->default_value().data(), this->default_value().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "default_value");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        7, this->default_value(), target);
    +  }
    +
    +  // optional .google.protobuf.FieldOptions options = 8;
    +  if (has_options()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        8, this->options(), target);
    +  }
    +
    +  // optional int32 oneof_index = 9;
    +  if (has_oneof_index()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->oneof_index(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto)
    +  return target;
    +}
    +
    +int FieldDescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional int32 number = 3;
    +    if (has_number()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->number());
    +    }
    +
    +    // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    +    if (has_label()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->label());
    +    }
    +
    +    // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    +    if (has_type()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
    +    }
    +
    +    // optional string type_name = 6;
    +    if (has_type_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->type_name());
    +    }
    +
    +    // optional string extendee = 2;
    +    if (has_extendee()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->extendee());
    +    }
    +
    +    // optional string default_value = 7;
    +    if (has_default_value()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->default_value());
    +    }
    +
    +    // optional int32 oneof_index = 9;
    +    if (has_oneof_index()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->oneof_index());
    +    }
    +
    +  }
    +  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    +    // optional .google.protobuf.FieldOptions options = 8;
    +    if (has_options()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->options());
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const FieldDescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_number()) {
    +      set_number(from.number());
    +    }
    +    if (from.has_label()) {
    +      set_label(from.label());
    +    }
    +    if (from.has_type()) {
    +      set_type(from.type());
    +    }
    +    if (from.has_type_name()) {
    +      set_type_name(from.type_name());
    +    }
    +    if (from.has_extendee()) {
    +      set_extendee(from.extendee());
    +    }
    +    if (from.has_default_value()) {
    +      set_default_value(from.default_value());
    +    }
    +    if (from.has_oneof_index()) {
    +      set_oneof_index(from.oneof_index());
    +    }
    +  }
    +  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    +    if (from.has_options()) {
    +      mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool FieldDescriptorProto::IsInitialized() const {
    +
    +  if (has_options()) {
    +    if (!this->options().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    std::swap(number_, other->number_);
    +    std::swap(label_, other->label_);
    +    std::swap(type_, other->type_);
    +    std::swap(type_name_, other->type_name_);
    +    std::swap(extendee_, other->extendee_);
    +    std::swap(default_value_, other->default_value_);
    +    std::swap(oneof_index_, other->oneof_index_);
    +    std::swap(options_, other->options_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = FieldDescriptorProto_descriptor_;
    +  metadata.reflection = FieldDescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int OneofDescriptorProto::kNameFieldNumber;
    +#endif  // !_MSC_VER
    +
    +OneofDescriptorProto::OneofDescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.OneofDescriptorProto)
    +}
    +
    +void OneofDescriptorProto::InitAsDefaultInstance() {
    +}
    +
    +OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
    +}
    +
    +void OneofDescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +OneofDescriptorProto::~OneofDescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto)
    +  SharedDtor();
    +}
    +
    +void OneofDescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void OneofDescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* OneofDescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return OneofDescriptorProto_descriptor_;
    +}
    +
    +const OneofDescriptorProto& OneofDescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +OneofDescriptorProto* OneofDescriptorProto::default_instance_ = NULL;
    +
    +OneofDescriptorProto* OneofDescriptorProto::New() const {
    +  return new OneofDescriptorProto;
    +}
    +
    +void OneofDescriptorProto::Clear() {
    +  if (has_name()) {
    +    if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +      name_->clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool OneofDescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.OneofDescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.OneofDescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.OneofDescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void OneofDescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.OneofDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.OneofDescriptorProto)
    +}
    +
    +::google::protobuf::uint8* OneofDescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto)
    +  return target;
    +}
    +
    +int OneofDescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const OneofDescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void OneofDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool OneofDescriptorProto::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void OneofDescriptorProto::Swap(OneofDescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = OneofDescriptorProto_descriptor_;
    +  metadata.reflection = OneofDescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int EnumDescriptorProto::kNameFieldNumber;
    +const int EnumDescriptorProto::kValueFieldNumber;
    +const int EnumDescriptorProto::kOptionsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +EnumDescriptorProto::EnumDescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto)
    +}
    +
    +void EnumDescriptorProto::InitAsDefaultInstance() {
    +  options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance());
    +}
    +
    +EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
    +}
    +
    +void EnumDescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  options_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +EnumDescriptorProto::~EnumDescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto)
    +  SharedDtor();
    +}
    +
    +void EnumDescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (this != default_instance_) {
    +    delete options_;
    +  }
    +}
    +
    +void EnumDescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return EnumDescriptorProto_descriptor_;
    +}
    +
    +const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL;
    +
    +EnumDescriptorProto* EnumDescriptorProto::New() const {
    +  return new EnumDescriptorProto;
    +}
    +
    +void EnumDescriptorProto::Clear() {
    +  if (_has_bits_[0 / 32] & 5) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    if (has_options()) {
    +      if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
    +    }
    +  }
    +  value_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool EnumDescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.EnumDescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_value;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_value:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_value()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_value;
    +        if (input->ExpectTag(26)) goto parse_options;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.EnumOptions options = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_options:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_options()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.EnumDescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumDescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void EnumDescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
    +  for (int i = 0; i < this->value_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      2, this->value(i), output);
    +  }
    +
    +  // optional .google.protobuf.EnumOptions options = 3;
    +  if (has_options()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      3, this->options(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto)
    +}
    +
    +::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
    +  for (int i = 0; i < this->value_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        2, this->value(i), target);
    +  }
    +
    +  // optional .google.protobuf.EnumOptions options = 3;
    +  if (has_options()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        3, this->options(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto)
    +  return target;
    +}
    +
    +int EnumDescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional .google.protobuf.EnumOptions options = 3;
    +    if (has_options()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->options());
    +    }
    +
    +  }
    +  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
    +  total_size += 1 * this->value_size();
    +  for (int i = 0; i < this->value_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->value(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const EnumDescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  value_.MergeFrom(from.value_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_options()) {
    +      mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool EnumDescriptorProto::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->value())) return false;
    +  if (has_options()) {
    +    if (!this->options().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void EnumDescriptorProto::Swap(EnumDescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    value_.Swap(&other->value_);
    +    std::swap(options_, other->options_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = EnumDescriptorProto_descriptor_;
    +  metadata.reflection = EnumDescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int EnumValueDescriptorProto::kNameFieldNumber;
    +const int EnumValueDescriptorProto::kNumberFieldNumber;
    +const int EnumValueDescriptorProto::kOptionsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +EnumValueDescriptorProto::EnumValueDescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.EnumValueDescriptorProto)
    +}
    +
    +void EnumValueDescriptorProto::InitAsDefaultInstance() {
    +  options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance());
    +}
    +
    +EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
    +}
    +
    +void EnumValueDescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  number_ = 0;
    +  options_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +EnumValueDescriptorProto::~EnumValueDescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto)
    +  SharedDtor();
    +}
    +
    +void EnumValueDescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (this != default_instance_) {
    +    delete options_;
    +  }
    +}
    +
    +void EnumValueDescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return EnumValueDescriptorProto_descriptor_;
    +}
    +
    +const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL;
    +
    +EnumValueDescriptorProto* EnumValueDescriptorProto::New() const {
    +  return new EnumValueDescriptorProto;
    +}
    +
    +void EnumValueDescriptorProto::Clear() {
    +  if (_has_bits_[0 / 32] & 7) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    number_ = 0;
    +    if (has_options()) {
    +      if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool EnumValueDescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueDescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_number;
    +        break;
    +      }
    +
    +      // optional int32 number = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_number:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, &number_)));
    +          set_has_number();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_options;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.EnumValueOptions options = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_options:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_options()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueDescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueDescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void EnumValueDescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // optional int32 number = 2;
    +  if (has_number()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
    +  }
    +
    +  // optional .google.protobuf.EnumValueOptions options = 3;
    +  if (has_options()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      3, this->options(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueDescriptorProto)
    +}
    +
    +::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  // optional int32 number = 2;
    +  if (has_number()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
    +  }
    +
    +  // optional .google.protobuf.EnumValueOptions options = 3;
    +  if (has_options()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        3, this->options(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto)
    +  return target;
    +}
    +
    +int EnumValueDescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional int32 number = 2;
    +    if (has_number()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(
    +          this->number());
    +    }
    +
    +    // optional .google.protobuf.EnumValueOptions options = 3;
    +    if (has_options()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->options());
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const EnumValueDescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_number()) {
    +      set_number(from.number());
    +    }
    +    if (from.has_options()) {
    +      mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool EnumValueDescriptorProto::IsInitialized() const {
    +
    +  if (has_options()) {
    +    if (!this->options().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    std::swap(number_, other->number_);
    +    std::swap(options_, other->options_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = EnumValueDescriptorProto_descriptor_;
    +  metadata.reflection = EnumValueDescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int ServiceDescriptorProto::kNameFieldNumber;
    +const int ServiceDescriptorProto::kMethodFieldNumber;
    +const int ServiceDescriptorProto::kOptionsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ServiceDescriptorProto::ServiceDescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.ServiceDescriptorProto)
    +}
    +
    +void ServiceDescriptorProto::InitAsDefaultInstance() {
    +  options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance());
    +}
    +
    +ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
    +}
    +
    +void ServiceDescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  options_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ServiceDescriptorProto::~ServiceDescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto)
    +  SharedDtor();
    +}
    +
    +void ServiceDescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (this != default_instance_) {
    +    delete options_;
    +  }
    +}
    +
    +void ServiceDescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return ServiceDescriptorProto_descriptor_;
    +}
    +
    +const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL;
    +
    +ServiceDescriptorProto* ServiceDescriptorProto::New() const {
    +  return new ServiceDescriptorProto;
    +}
    +
    +void ServiceDescriptorProto::Clear() {
    +  if (_has_bits_[0 / 32] & 5) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    if (has_options()) {
    +      if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
    +    }
    +  }
    +  method_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool ServiceDescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.ServiceDescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_method;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.MethodDescriptorProto method = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_method:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_method()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_method;
    +        if (input->ExpectTag(26)) goto parse_options;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.ServiceOptions options = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_options:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_options()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.ServiceDescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceDescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void ServiceDescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // repeated .google.protobuf.MethodDescriptorProto method = 2;
    +  for (int i = 0; i < this->method_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      2, this->method(i), output);
    +  }
    +
    +  // optional .google.protobuf.ServiceOptions options = 3;
    +  if (has_options()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      3, this->options(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceDescriptorProto)
    +}
    +
    +::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  // repeated .google.protobuf.MethodDescriptorProto method = 2;
    +  for (int i = 0; i < this->method_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        2, this->method(i), target);
    +  }
    +
    +  // optional .google.protobuf.ServiceOptions options = 3;
    +  if (has_options()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        3, this->options(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto)
    +  return target;
    +}
    +
    +int ServiceDescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional .google.protobuf.ServiceOptions options = 3;
    +    if (has_options()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->options());
    +    }
    +
    +  }
    +  // repeated .google.protobuf.MethodDescriptorProto method = 2;
    +  total_size += 1 * this->method_size();
    +  for (int i = 0; i < this->method_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->method(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const ServiceDescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  method_.MergeFrom(from.method_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_options()) {
    +      mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ServiceDescriptorProto::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->method())) return false;
    +  if (has_options()) {
    +    if (!this->options().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    method_.Swap(&other->method_);
    +    std::swap(options_, other->options_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = ServiceDescriptorProto_descriptor_;
    +  metadata.reflection = ServiceDescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int MethodDescriptorProto::kNameFieldNumber;
    +const int MethodDescriptorProto::kInputTypeFieldNumber;
    +const int MethodDescriptorProto::kOutputTypeFieldNumber;
    +const int MethodDescriptorProto::kOptionsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +MethodDescriptorProto::MethodDescriptorProto()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.MethodDescriptorProto)
    +}
    +
    +void MethodDescriptorProto::InitAsDefaultInstance() {
    +  options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance());
    +}
    +
    +MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
    +}
    +
    +void MethodDescriptorProto::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  options_ = NULL;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +MethodDescriptorProto::~MethodDescriptorProto() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto)
    +  SharedDtor();
    +}
    +
    +void MethodDescriptorProto::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete input_type_;
    +  }
    +  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete output_type_;
    +  }
    +  if (this != default_instance_) {
    +    delete options_;
    +  }
    +}
    +
    +void MethodDescriptorProto::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return MethodDescriptorProto_descriptor_;
    +}
    +
    +const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL;
    +
    +MethodDescriptorProto* MethodDescriptorProto::New() const {
    +  return new MethodDescriptorProto;
    +}
    +
    +void MethodDescriptorProto::Clear() {
    +  if (_has_bits_[0 / 32] & 15) {
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +    if (has_input_type()) {
    +      if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        input_type_->clear();
    +      }
    +    }
    +    if (has_output_type()) {
    +      if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        output_type_->clear();
    +      }
    +    }
    +    if (has_options()) {
    +      if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool MethodDescriptorProto::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.MethodDescriptorProto)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string name = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name().data(), this->name().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_input_type;
    +        break;
    +      }
    +
    +      // optional string input_type = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_input_type:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_input_type()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->input_type().data(), this->input_type().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "input_type");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_output_type;
    +        break;
    +      }
    +
    +      // optional string output_type = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_output_type:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_output_type()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->output_type().data(), this->output_type().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "output_type");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_options;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.MethodOptions options = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_options:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +               input, mutable_options()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.MethodDescriptorProto)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.MethodDescriptorProto)
    +  return false;
    +#undef DO_
    +}
    +
    +void MethodDescriptorProto::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.MethodDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name(), output);
    +  }
    +
    +  // optional string input_type = 2;
    +  if (has_input_type()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->input_type().data(), this->input_type().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "input_type");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      2, this->input_type(), output);
    +  }
    +
    +  // optional string output_type = 3;
    +  if (has_output_type()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->output_type().data(), this->output_type().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "output_type");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      3, this->output_type(), output);
    +  }
    +
    +  // optional .google.protobuf.MethodOptions options = 4;
    +  if (has_options()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      4, this->options(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.MethodDescriptorProto)
    +}
    +
    +::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto)
    +  // optional string name = 1;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name().data(), this->name().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name(), target);
    +  }
    +
    +  // optional string input_type = 2;
    +  if (has_input_type()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->input_type().data(), this->input_type().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "input_type");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        2, this->input_type(), target);
    +  }
    +
    +  // optional string output_type = 3;
    +  if (has_output_type()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->output_type().data(), this->output_type().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "output_type");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        3, this->output_type(), target);
    +  }
    +
    +  // optional .google.protobuf.MethodOptions options = 4;
    +  if (has_options()) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        4, this->options(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto)
    +  return target;
    +}
    +
    +int MethodDescriptorProto::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string name = 1;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name());
    +    }
    +
    +    // optional string input_type = 2;
    +    if (has_input_type()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->input_type());
    +    }
    +
    +    // optional string output_type = 3;
    +    if (has_output_type()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->output_type());
    +    }
    +
    +    // optional .google.protobuf.MethodOptions options = 4;
    +    if (has_options()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +          this->options());
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const MethodDescriptorProto* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +    if (from.has_input_type()) {
    +      set_input_type(from.input_type());
    +    }
    +    if (from.has_output_type()) {
    +      set_output_type(from.output_type());
    +    }
    +    if (from.has_options()) {
    +      mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool MethodDescriptorProto::IsInitialized() const {
    +
    +  if (has_options()) {
    +    if (!this->options().IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +void MethodDescriptorProto::Swap(MethodDescriptorProto* other) {
    +  if (other != this) {
    +    std::swap(name_, other->name_);
    +    std::swap(input_type_, other->input_type_);
    +    std::swap(output_type_, other->output_type_);
    +    std::swap(options_, other->options_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = MethodDescriptorProto_descriptor_;
    +  metadata.reflection = MethodDescriptorProto_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FileOptions_OptimizeMode_descriptor_;
    +}
    +bool FileOptions_OptimizeMode_IsValid(int value) {
    +  switch(value) {
    +    case 1:
    +    case 2:
    +    case 3:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const FileOptions_OptimizeMode FileOptions::SPEED;
    +const FileOptions_OptimizeMode FileOptions::CODE_SIZE;
    +const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
    +const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
    +const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
    +const int FileOptions::OptimizeMode_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int FileOptions::kJavaPackageFieldNumber;
    +const int FileOptions::kJavaOuterClassnameFieldNumber;
    +const int FileOptions::kJavaMultipleFilesFieldNumber;
    +const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber;
    +const int FileOptions::kJavaStringCheckUtf8FieldNumber;
    +const int FileOptions::kOptimizeForFieldNumber;
    +const int FileOptions::kGoPackageFieldNumber;
    +const int FileOptions::kCcGenericServicesFieldNumber;
    +const int FileOptions::kJavaGenericServicesFieldNumber;
    +const int FileOptions::kPyGenericServicesFieldNumber;
    +const int FileOptions::kDeprecatedFieldNumber;
    +const int FileOptions::kUninterpretedOptionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +FileOptions::FileOptions()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.FileOptions)
    +}
    +
    +void FileOptions::InitAsDefaultInstance() {
    +}
    +
    +FileOptions::FileOptions(const FileOptions& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
    +}
    +
    +void FileOptions::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  java_multiple_files_ = false;
    +  java_generate_equals_and_hash_ = false;
    +  java_string_check_utf8_ = false;
    +  optimize_for_ = 1;
    +  go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  cc_generic_services_ = false;
    +  java_generic_services_ = false;
    +  py_generic_services_ = false;
    +  deprecated_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +FileOptions::~FileOptions() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.FileOptions)
    +  SharedDtor();
    +}
    +
    +void FileOptions::SharedDtor() {
    +  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete java_package_;
    +  }
    +  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete java_outer_classname_;
    +  }
    +  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete go_package_;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void FileOptions::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* FileOptions::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FileOptions_descriptor_;
    +}
    +
    +const FileOptions& FileOptions::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +FileOptions* FileOptions::default_instance_ = NULL;
    +
    +FileOptions* FileOptions::New() const {
    +  return new FileOptions;
    +}
    +
    +void FileOptions::Clear() {
    +  _extensions_.Clear();
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 255) {
    +    ZR_(java_multiple_files_, cc_generic_services_);
    +    if (has_java_package()) {
    +      if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        java_package_->clear();
    +      }
    +    }
    +    if (has_java_outer_classname()) {
    +      if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        java_outer_classname_->clear();
    +      }
    +    }
    +    optimize_for_ = 1;
    +    if (has_go_package()) {
    +      if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        go_package_->clear();
    +      }
    +    }
    +  }
    +  ZR_(java_generic_services_, deprecated_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  uninterpreted_option_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool FileOptions::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.FileOptions)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional string java_package = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_java_package()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->java_package().data(), this->java_package().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "java_package");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(66)) goto parse_java_outer_classname;
    +        break;
    +      }
    +
    +      // optional string java_outer_classname = 8;
    +      case 8: {
    +        if (tag == 66) {
    +         parse_java_outer_classname:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_java_outer_classname()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->java_outer_classname().data(), this->java_outer_classname().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "java_outer_classname");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(72)) goto parse_optimize_for;
    +        break;
    +      }
    +
    +      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    +      case 9: {
    +        if (tag == 72) {
    +         parse_optimize_for:
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
    +            set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
    +          } else {
    +            mutable_unknown_fields()->AddVarint(9, value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(80)) goto parse_java_multiple_files;
    +        break;
    +      }
    +
    +      // optional bool java_multiple_files = 10 [default = false];
    +      case 10: {
    +        if (tag == 80) {
    +         parse_java_multiple_files:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &java_multiple_files_)));
    +          set_has_java_multiple_files();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(90)) goto parse_go_package;
    +        break;
    +      }
    +
    +      // optional string go_package = 11;
    +      case 11: {
    +        if (tag == 90) {
    +         parse_go_package:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_go_package()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->go_package().data(), this->go_package().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "go_package");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(128)) goto parse_cc_generic_services;
    +        break;
    +      }
    +
    +      // optional bool cc_generic_services = 16 [default = false];
    +      case 16: {
    +        if (tag == 128) {
    +         parse_cc_generic_services:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &cc_generic_services_)));
    +          set_has_cc_generic_services();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(136)) goto parse_java_generic_services;
    +        break;
    +      }
    +
    +      // optional bool java_generic_services = 17 [default = false];
    +      case 17: {
    +        if (tag == 136) {
    +         parse_java_generic_services:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &java_generic_services_)));
    +          set_has_java_generic_services();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(144)) goto parse_py_generic_services;
    +        break;
    +      }
    +
    +      // optional bool py_generic_services = 18 [default = false];
    +      case 18: {
    +        if (tag == 144) {
    +         parse_py_generic_services:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &py_generic_services_)));
    +          set_has_py_generic_services();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash;
    +        break;
    +      }
    +
    +      // optional bool java_generate_equals_and_hash = 20 [default = false];
    +      case 20: {
    +        if (tag == 160) {
    +         parse_java_generate_equals_and_hash:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &java_generate_equals_and_hash_)));
    +          set_has_java_generate_equals_and_hash();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(184)) goto parse_deprecated;
    +        break;
    +      }
    +
    +      // optional bool deprecated = 23 [default = false];
    +      case 23: {
    +        if (tag == 184) {
    +         parse_deprecated:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &deprecated_)));
    +          set_has_deprecated();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(216)) goto parse_java_string_check_utf8;
    +        break;
    +      }
    +
    +      // optional bool java_string_check_utf8 = 27 [default = false];
    +      case 27: {
    +        if (tag == 216) {
    +         parse_java_string_check_utf8:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &java_string_check_utf8_)));
    +          set_has_java_string_check_utf8();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +      case 999: {
    +        if (tag == 7994) {
    +         parse_uninterpreted_option:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_uninterpreted_option()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        if ((8000u <= tag)) {
    +          DO_(_extensions_.ParseField(tag, input, default_instance_,
    +                                      mutable_unknown_fields()));
    +          continue;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.FileOptions)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.FileOptions)
    +  return false;
    +#undef DO_
    +}
    +
    +void FileOptions::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.FileOptions)
    +  // optional string java_package = 1;
    +  if (has_java_package()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->java_package().data(), this->java_package().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "java_package");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->java_package(), output);
    +  }
    +
    +  // optional string java_outer_classname = 8;
    +  if (has_java_outer_classname()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->java_outer_classname().data(), this->java_outer_classname().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "java_outer_classname");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      8, this->java_outer_classname(), output);
    +  }
    +
    +  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    +  if (has_optimize_for()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      9, this->optimize_for(), output);
    +  }
    +
    +  // optional bool java_multiple_files = 10 [default = false];
    +  if (has_java_multiple_files()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
    +  }
    +
    +  // optional string go_package = 11;
    +  if (has_go_package()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->go_package().data(), this->go_package().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "go_package");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      11, this->go_package(), output);
    +  }
    +
    +  // optional bool cc_generic_services = 16 [default = false];
    +  if (has_cc_generic_services()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
    +  }
    +
    +  // optional bool java_generic_services = 17 [default = false];
    +  if (has_java_generic_services()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
    +  }
    +
    +  // optional bool py_generic_services = 18 [default = false];
    +  if (has_py_generic_services()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
    +  }
    +
    +  // optional bool java_generate_equals_and_hash = 20 [default = false];
    +  if (has_java_generate_equals_and_hash()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
    +  }
    +
    +  // optional bool deprecated = 23 [default = false];
    +  if (has_deprecated()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(23, this->deprecated(), output);
    +  }
    +
    +  // optional bool java_string_check_utf8 = 27 [default = false];
    +  if (has_java_string_check_utf8()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(27, this->java_string_check_utf8(), output);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      999, this->uninterpreted_option(i), output);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  _extensions_.SerializeWithCachedSizes(
    +      1000, 536870912, output);
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.FileOptions)
    +}
    +
    +::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions)
    +  // optional string java_package = 1;
    +  if (has_java_package()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->java_package().data(), this->java_package().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "java_package");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->java_package(), target);
    +  }
    +
    +  // optional string java_outer_classname = 8;
    +  if (has_java_outer_classname()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->java_outer_classname().data(), this->java_outer_classname().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "java_outer_classname");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        8, this->java_outer_classname(), target);
    +  }
    +
    +  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    +  if (has_optimize_for()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
    +      9, this->optimize_for(), target);
    +  }
    +
    +  // optional bool java_multiple_files = 10 [default = false];
    +  if (has_java_multiple_files()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
    +  }
    +
    +  // optional string go_package = 11;
    +  if (has_go_package()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->go_package().data(), this->go_package().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "go_package");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        11, this->go_package(), target);
    +  }
    +
    +  // optional bool cc_generic_services = 16 [default = false];
    +  if (has_cc_generic_services()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
    +  }
    +
    +  // optional bool java_generic_services = 17 [default = false];
    +  if (has_java_generic_services()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
    +  }
    +
    +  // optional bool py_generic_services = 18 [default = false];
    +  if (has_py_generic_services()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
    +  }
    +
    +  // optional bool java_generate_equals_and_hash = 20 [default = false];
    +  if (has_java_generate_equals_and_hash()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
    +  }
    +
    +  // optional bool deprecated = 23 [default = false];
    +  if (has_deprecated()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(23, this->deprecated(), target);
    +  }
    +
    +  // optional bool java_string_check_utf8 = 27 [default = false];
    +  if (has_java_string_check_utf8()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(27, this->java_string_check_utf8(), target);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        999, this->uninterpreted_option(i), target);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  target = _extensions_.SerializeWithCachedSizesToArray(
    +      1000, 536870912, target);
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions)
    +  return target;
    +}
    +
    +int FileOptions::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional string java_package = 1;
    +    if (has_java_package()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->java_package());
    +    }
    +
    +    // optional string java_outer_classname = 8;
    +    if (has_java_outer_classname()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->java_outer_classname());
    +    }
    +
    +    // optional bool java_multiple_files = 10 [default = false];
    +    if (has_java_multiple_files()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional bool java_generate_equals_and_hash = 20 [default = false];
    +    if (has_java_generate_equals_and_hash()) {
    +      total_size += 2 + 1;
    +    }
    +
    +    // optional bool java_string_check_utf8 = 27 [default = false];
    +    if (has_java_string_check_utf8()) {
    +      total_size += 2 + 1;
    +    }
    +
    +    // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    +    if (has_optimize_for()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
    +    }
    +
    +    // optional string go_package = 11;
    +    if (has_go_package()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->go_package());
    +    }
    +
    +    // optional bool cc_generic_services = 16 [default = false];
    +    if (has_cc_generic_services()) {
    +      total_size += 2 + 1;
    +    }
    +
    +  }
    +  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    +    // optional bool java_generic_services = 17 [default = false];
    +    if (has_java_generic_services()) {
    +      total_size += 2 + 1;
    +    }
    +
    +    // optional bool py_generic_services = 18 [default = false];
    +    if (has_py_generic_services()) {
    +      total_size += 2 + 1;
    +    }
    +
    +    // optional bool deprecated = 23 [default = false];
    +    if (has_deprecated()) {
    +      total_size += 2 + 1;
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  total_size += 2 * this->uninterpreted_option_size();
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->uninterpreted_option(i));
    +  }
    +
    +  total_size += _extensions_.ByteSize();
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const FileOptions* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void FileOptions::MergeFrom(const FileOptions& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_java_package()) {
    +      set_java_package(from.java_package());
    +    }
    +    if (from.has_java_outer_classname()) {
    +      set_java_outer_classname(from.java_outer_classname());
    +    }
    +    if (from.has_java_multiple_files()) {
    +      set_java_multiple_files(from.java_multiple_files());
    +    }
    +    if (from.has_java_generate_equals_and_hash()) {
    +      set_java_generate_equals_and_hash(from.java_generate_equals_and_hash());
    +    }
    +    if (from.has_java_string_check_utf8()) {
    +      set_java_string_check_utf8(from.java_string_check_utf8());
    +    }
    +    if (from.has_optimize_for()) {
    +      set_optimize_for(from.optimize_for());
    +    }
    +    if (from.has_go_package()) {
    +      set_go_package(from.go_package());
    +    }
    +    if (from.has_cc_generic_services()) {
    +      set_cc_generic_services(from.cc_generic_services());
    +    }
    +  }
    +  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    +    if (from.has_java_generic_services()) {
    +      set_java_generic_services(from.java_generic_services());
    +    }
    +    if (from.has_py_generic_services()) {
    +      set_py_generic_services(from.py_generic_services());
    +    }
    +    if (from.has_deprecated()) {
    +      set_deprecated(from.deprecated());
    +    }
    +  }
    +  _extensions_.MergeFrom(from._extensions_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void FileOptions::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void FileOptions::CopyFrom(const FileOptions& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool FileOptions::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
    +
    +  if (!_extensions_.IsInitialized()) return false;  return true;
    +}
    +
    +void FileOptions::Swap(FileOptions* other) {
    +  if (other != this) {
    +    std::swap(java_package_, other->java_package_);
    +    std::swap(java_outer_classname_, other->java_outer_classname_);
    +    std::swap(java_multiple_files_, other->java_multiple_files_);
    +    std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
    +    std::swap(java_string_check_utf8_, other->java_string_check_utf8_);
    +    std::swap(optimize_for_, other->optimize_for_);
    +    std::swap(go_package_, other->go_package_);
    +    std::swap(cc_generic_services_, other->cc_generic_services_);
    +    std::swap(java_generic_services_, other->java_generic_services_);
    +    std::swap(py_generic_services_, other->py_generic_services_);
    +    std::swap(deprecated_, other->deprecated_);
    +    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +    _extensions_.Swap(&other->_extensions_);
    +  }
    +}
    +
    +::google::protobuf::Metadata FileOptions::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = FileOptions_descriptor_;
    +  metadata.reflection = FileOptions_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int MessageOptions::kMessageSetWireFormatFieldNumber;
    +const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber;
    +const int MessageOptions::kDeprecatedFieldNumber;
    +const int MessageOptions::kUninterpretedOptionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +MessageOptions::MessageOptions()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.MessageOptions)
    +}
    +
    +void MessageOptions::InitAsDefaultInstance() {
    +}
    +
    +MessageOptions::MessageOptions(const MessageOptions& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
    +}
    +
    +void MessageOptions::SharedCtor() {
    +  _cached_size_ = 0;
    +  message_set_wire_format_ = false;
    +  no_standard_descriptor_accessor_ = false;
    +  deprecated_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +MessageOptions::~MessageOptions() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions)
    +  SharedDtor();
    +}
    +
    +void MessageOptions::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void MessageOptions::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return MessageOptions_descriptor_;
    +}
    +
    +const MessageOptions& MessageOptions::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +MessageOptions* MessageOptions::default_instance_ = NULL;
    +
    +MessageOptions* MessageOptions::New() const {
    +  return new MessageOptions;
    +}
    +
    +void MessageOptions::Clear() {
    +  _extensions_.Clear();
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(message_set_wire_format_, deprecated_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  uninterpreted_option_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool MessageOptions::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.MessageOptions)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional bool message_set_wire_format = 1 [default = false];
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &message_set_wire_format_)));
    +          set_has_message_set_wire_format();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor;
    +        break;
    +      }
    +
    +      // optional bool no_standard_descriptor_accessor = 2 [default = false];
    +      case 2: {
    +        if (tag == 16) {
    +         parse_no_standard_descriptor_accessor:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &no_standard_descriptor_accessor_)));
    +          set_has_no_standard_descriptor_accessor();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_deprecated;
    +        break;
    +      }
    +
    +      // optional bool deprecated = 3 [default = false];
    +      case 3: {
    +        if (tag == 24) {
    +         parse_deprecated:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &deprecated_)));
    +          set_has_deprecated();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +      case 999: {
    +        if (tag == 7994) {
    +         parse_uninterpreted_option:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_uninterpreted_option()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        if ((8000u <= tag)) {
    +          DO_(_extensions_.ParseField(tag, input, default_instance_,
    +                                      mutable_unknown_fields()));
    +          continue;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.MessageOptions)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.MessageOptions)
    +  return false;
    +#undef DO_
    +}
    +
    +void MessageOptions::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.MessageOptions)
    +  // optional bool message_set_wire_format = 1 [default = false];
    +  if (has_message_set_wire_format()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
    +  }
    +
    +  // optional bool no_standard_descriptor_accessor = 2 [default = false];
    +  if (has_no_standard_descriptor_accessor()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
    +  }
    +
    +  // optional bool deprecated = 3 [default = false];
    +  if (has_deprecated()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      999, this->uninterpreted_option(i), output);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  _extensions_.SerializeWithCachedSizes(
    +      1000, 536870912, output);
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.MessageOptions)
    +}
    +
    +::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions)
    +  // optional bool message_set_wire_format = 1 [default = false];
    +  if (has_message_set_wire_format()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
    +  }
    +
    +  // optional bool no_standard_descriptor_accessor = 2 [default = false];
    +  if (has_no_standard_descriptor_accessor()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
    +  }
    +
    +  // optional bool deprecated = 3 [default = false];
    +  if (has_deprecated()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        999, this->uninterpreted_option(i), target);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  target = _extensions_.SerializeWithCachedSizesToArray(
    +      1000, 536870912, target);
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions)
    +  return target;
    +}
    +
    +int MessageOptions::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional bool message_set_wire_format = 1 [default = false];
    +    if (has_message_set_wire_format()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional bool no_standard_descriptor_accessor = 2 [default = false];
    +    if (has_no_standard_descriptor_accessor()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional bool deprecated = 3 [default = false];
    +    if (has_deprecated()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  total_size += 2 * this->uninterpreted_option_size();
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->uninterpreted_option(i));
    +  }
    +
    +  total_size += _extensions_.ByteSize();
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const MessageOptions* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void MessageOptions::MergeFrom(const MessageOptions& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_message_set_wire_format()) {
    +      set_message_set_wire_format(from.message_set_wire_format());
    +    }
    +    if (from.has_no_standard_descriptor_accessor()) {
    +      set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor());
    +    }
    +    if (from.has_deprecated()) {
    +      set_deprecated(from.deprecated());
    +    }
    +  }
    +  _extensions_.MergeFrom(from._extensions_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void MessageOptions::CopyFrom(const MessageOptions& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool MessageOptions::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
    +
    +  if (!_extensions_.IsInitialized()) return false;  return true;
    +}
    +
    +void MessageOptions::Swap(MessageOptions* other) {
    +  if (other != this) {
    +    std::swap(message_set_wire_format_, other->message_set_wire_format_);
    +    std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
    +    std::swap(deprecated_, other->deprecated_);
    +    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +    _extensions_.Swap(&other->_extensions_);
    +  }
    +}
    +
    +::google::protobuf::Metadata MessageOptions::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = MessageOptions_descriptor_;
    +  metadata.reflection = MessageOptions_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FieldOptions_CType_descriptor_;
    +}
    +bool FieldOptions_CType_IsValid(int value) {
    +  switch(value) {
    +    case 0:
    +    case 1:
    +    case 2:
    +      return true;
    +    default:
    +      return false;
    +  }
    +}
    +
    +#ifndef _MSC_VER
    +const FieldOptions_CType FieldOptions::STRING;
    +const FieldOptions_CType FieldOptions::CORD;
    +const FieldOptions_CType FieldOptions::STRING_PIECE;
    +const FieldOptions_CType FieldOptions::CType_MIN;
    +const FieldOptions_CType FieldOptions::CType_MAX;
    +const int FieldOptions::CType_ARRAYSIZE;
    +#endif  // _MSC_VER
    +#ifndef _MSC_VER
    +const int FieldOptions::kCtypeFieldNumber;
    +const int FieldOptions::kPackedFieldNumber;
    +const int FieldOptions::kLazyFieldNumber;
    +const int FieldOptions::kDeprecatedFieldNumber;
    +const int FieldOptions::kExperimentalMapKeyFieldNumber;
    +const int FieldOptions::kWeakFieldNumber;
    +const int FieldOptions::kUninterpretedOptionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +FieldOptions::FieldOptions()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.FieldOptions)
    +}
    +
    +void FieldOptions::InitAsDefaultInstance() {
    +}
    +
    +FieldOptions::FieldOptions(const FieldOptions& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
    +}
    +
    +void FieldOptions::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  ctype_ = 0;
    +  packed_ = false;
    +  lazy_ = false;
    +  deprecated_ = false;
    +  experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  weak_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +FieldOptions::~FieldOptions() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions)
    +  SharedDtor();
    +}
    +
    +void FieldOptions::SharedDtor() {
    +  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete experimental_map_key_;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void FieldOptions::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return FieldOptions_descriptor_;
    +}
    +
    +const FieldOptions& FieldOptions::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +FieldOptions* FieldOptions::default_instance_ = NULL;
    +
    +FieldOptions* FieldOptions::New() const {
    +  return new FieldOptions;
    +}
    +
    +void FieldOptions::Clear() {
    +  _extensions_.Clear();
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 63) {
    +    ZR_(ctype_, weak_);
    +    if (has_experimental_map_key()) {
    +      if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        experimental_map_key_->clear();
    +      }
    +    }
    +  }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  uninterpreted_option_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool FieldOptions::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.FieldOptions)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    +      case 1: {
    +        if (tag == 8) {
    +          int value;
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
    +                 input, &value)));
    +          if (::google::protobuf::FieldOptions_CType_IsValid(value)) {
    +            set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
    +          } else {
    +            mutable_unknown_fields()->AddVarint(1, value);
    +          }
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_packed;
    +        break;
    +      }
    +
    +      // optional bool packed = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_packed:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &packed_)));
    +          set_has_packed();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_deprecated;
    +        break;
    +      }
    +
    +      // optional bool deprecated = 3 [default = false];
    +      case 3: {
    +        if (tag == 24) {
    +         parse_deprecated:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &deprecated_)));
    +          set_has_deprecated();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(40)) goto parse_lazy;
    +        break;
    +      }
    +
    +      // optional bool lazy = 5 [default = false];
    +      case 5: {
    +        if (tag == 40) {
    +         parse_lazy:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &lazy_)));
    +          set_has_lazy();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(74)) goto parse_experimental_map_key;
    +        break;
    +      }
    +
    +      // optional string experimental_map_key = 9;
    +      case 9: {
    +        if (tag == 74) {
    +         parse_experimental_map_key:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_experimental_map_key()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->experimental_map_key().data(), this->experimental_map_key().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "experimental_map_key");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(80)) goto parse_weak;
    +        break;
    +      }
    +
    +      // optional bool weak = 10 [default = false];
    +      case 10: {
    +        if (tag == 80) {
    +         parse_weak:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &weak_)));
    +          set_has_weak();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +      case 999: {
    +        if (tag == 7994) {
    +         parse_uninterpreted_option:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_uninterpreted_option()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        if ((8000u <= tag)) {
    +          DO_(_extensions_.ParseField(tag, input, default_instance_,
    +                                      mutable_unknown_fields()));
    +          continue;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.FieldOptions)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.FieldOptions)
    +  return false;
    +#undef DO_
    +}
    +
    +void FieldOptions::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.FieldOptions)
    +  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    +  if (has_ctype()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteEnum(
    +      1, this->ctype(), output);
    +  }
    +
    +  // optional bool packed = 2;
    +  if (has_packed()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
    +  }
    +
    +  // optional bool deprecated = 3 [default = false];
    +  if (has_deprecated()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
    +  }
    +
    +  // optional bool lazy = 5 [default = false];
    +  if (has_lazy()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output);
    +  }
    +
    +  // optional string experimental_map_key = 9;
    +  if (has_experimental_map_key()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->experimental_map_key().data(), this->experimental_map_key().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "experimental_map_key");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      9, this->experimental_map_key(), output);
    +  }
    +
    +  // optional bool weak = 10 [default = false];
    +  if (has_weak()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      999, this->uninterpreted_option(i), output);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  _extensions_.SerializeWithCachedSizes(
    +      1000, 536870912, output);
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.FieldOptions)
    +}
    +
    +::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions)
    +  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    +  if (has_ctype()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
    +      1, this->ctype(), target);
    +  }
    +
    +  // optional bool packed = 2;
    +  if (has_packed()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
    +  }
    +
    +  // optional bool deprecated = 3 [default = false];
    +  if (has_deprecated()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
    +  }
    +
    +  // optional bool lazy = 5 [default = false];
    +  if (has_lazy()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target);
    +  }
    +
    +  // optional string experimental_map_key = 9;
    +  if (has_experimental_map_key()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->experimental_map_key().data(), this->experimental_map_key().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "experimental_map_key");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        9, this->experimental_map_key(), target);
    +  }
    +
    +  // optional bool weak = 10 [default = false];
    +  if (has_weak()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        999, this->uninterpreted_option(i), target);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  target = _extensions_.SerializeWithCachedSizesToArray(
    +      1000, 536870912, target);
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions)
    +  return target;
    +}
    +
    +int FieldOptions::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    +    if (has_ctype()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
    +    }
    +
    +    // optional bool packed = 2;
    +    if (has_packed()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional bool lazy = 5 [default = false];
    +    if (has_lazy()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional bool deprecated = 3 [default = false];
    +    if (has_deprecated()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional string experimental_map_key = 9;
    +    if (has_experimental_map_key()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->experimental_map_key());
    +    }
    +
    +    // optional bool weak = 10 [default = false];
    +    if (has_weak()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  total_size += 2 * this->uninterpreted_option_size();
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->uninterpreted_option(i));
    +  }
    +
    +  total_size += _extensions_.ByteSize();
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const FieldOptions* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void FieldOptions::MergeFrom(const FieldOptions& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_ctype()) {
    +      set_ctype(from.ctype());
    +    }
    +    if (from.has_packed()) {
    +      set_packed(from.packed());
    +    }
    +    if (from.has_lazy()) {
    +      set_lazy(from.lazy());
    +    }
    +    if (from.has_deprecated()) {
    +      set_deprecated(from.deprecated());
    +    }
    +    if (from.has_experimental_map_key()) {
    +      set_experimental_map_key(from.experimental_map_key());
    +    }
    +    if (from.has_weak()) {
    +      set_weak(from.weak());
    +    }
    +  }
    +  _extensions_.MergeFrom(from._extensions_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void FieldOptions::CopyFrom(const FieldOptions& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool FieldOptions::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
    +
    +  if (!_extensions_.IsInitialized()) return false;  return true;
    +}
    +
    +void FieldOptions::Swap(FieldOptions* other) {
    +  if (other != this) {
    +    std::swap(ctype_, other->ctype_);
    +    std::swap(packed_, other->packed_);
    +    std::swap(lazy_, other->lazy_);
    +    std::swap(deprecated_, other->deprecated_);
    +    std::swap(experimental_map_key_, other->experimental_map_key_);
    +    std::swap(weak_, other->weak_);
    +    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +    _extensions_.Swap(&other->_extensions_);
    +  }
    +}
    +
    +::google::protobuf::Metadata FieldOptions::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = FieldOptions_descriptor_;
    +  metadata.reflection = FieldOptions_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int EnumOptions::kAllowAliasFieldNumber;
    +const int EnumOptions::kDeprecatedFieldNumber;
    +const int EnumOptions::kUninterpretedOptionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +EnumOptions::EnumOptions()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.EnumOptions)
    +}
    +
    +void EnumOptions::InitAsDefaultInstance() {
    +}
    +
    +EnumOptions::EnumOptions(const EnumOptions& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
    +}
    +
    +void EnumOptions::SharedCtor() {
    +  _cached_size_ = 0;
    +  allow_alias_ = false;
    +  deprecated_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +EnumOptions::~EnumOptions() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions)
    +  SharedDtor();
    +}
    +
    +void EnumOptions::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void EnumOptions::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return EnumOptions_descriptor_;
    +}
    +
    +const EnumOptions& EnumOptions::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +EnumOptions* EnumOptions::default_instance_ = NULL;
    +
    +EnumOptions* EnumOptions::New() const {
    +  return new EnumOptions;
    +}
    +
    +void EnumOptions::Clear() {
    +  _extensions_.Clear();
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  ZR_(allow_alias_, deprecated_);
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  uninterpreted_option_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool EnumOptions::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.EnumOptions)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional bool allow_alias = 2;
    +      case 2: {
    +        if (tag == 16) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &allow_alias_)));
    +          set_has_allow_alias();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_deprecated;
    +        break;
    +      }
    +
    +      // optional bool deprecated = 3 [default = false];
    +      case 3: {
    +        if (tag == 24) {
    +         parse_deprecated:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &deprecated_)));
    +          set_has_deprecated();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +      case 999: {
    +        if (tag == 7994) {
    +         parse_uninterpreted_option:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_uninterpreted_option()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        if ((8000u <= tag)) {
    +          DO_(_extensions_.ParseField(tag, input, default_instance_,
    +                                      mutable_unknown_fields()));
    +          continue;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.EnumOptions)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumOptions)
    +  return false;
    +#undef DO_
    +}
    +
    +void EnumOptions::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumOptions)
    +  // optional bool allow_alias = 2;
    +  if (has_allow_alias()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output);
    +  }
    +
    +  // optional bool deprecated = 3 [default = false];
    +  if (has_deprecated()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      999, this->uninterpreted_option(i), output);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  _extensions_.SerializeWithCachedSizes(
    +      1000, 536870912, output);
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumOptions)
    +}
    +
    +::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions)
    +  // optional bool allow_alias = 2;
    +  if (has_allow_alias()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target);
    +  }
    +
    +  // optional bool deprecated = 3 [default = false];
    +  if (has_deprecated()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        999, this->uninterpreted_option(i), target);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  target = _extensions_.SerializeWithCachedSizesToArray(
    +      1000, 536870912, target);
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions)
    +  return target;
    +}
    +
    +int EnumOptions::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional bool allow_alias = 2;
    +    if (has_allow_alias()) {
    +      total_size += 1 + 1;
    +    }
    +
    +    // optional bool deprecated = 3 [default = false];
    +    if (has_deprecated()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  total_size += 2 * this->uninterpreted_option_size();
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->uninterpreted_option(i));
    +  }
    +
    +  total_size += _extensions_.ByteSize();
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const EnumOptions* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void EnumOptions::MergeFrom(const EnumOptions& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_allow_alias()) {
    +      set_allow_alias(from.allow_alias());
    +    }
    +    if (from.has_deprecated()) {
    +      set_deprecated(from.deprecated());
    +    }
    +  }
    +  _extensions_.MergeFrom(from._extensions_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void EnumOptions::CopyFrom(const EnumOptions& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool EnumOptions::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
    +
    +  if (!_extensions_.IsInitialized()) return false;  return true;
    +}
    +
    +void EnumOptions::Swap(EnumOptions* other) {
    +  if (other != this) {
    +    std::swap(allow_alias_, other->allow_alias_);
    +    std::swap(deprecated_, other->deprecated_);
    +    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +    _extensions_.Swap(&other->_extensions_);
    +  }
    +}
    +
    +::google::protobuf::Metadata EnumOptions::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = EnumOptions_descriptor_;
    +  metadata.reflection = EnumOptions_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int EnumValueOptions::kDeprecatedFieldNumber;
    +const int EnumValueOptions::kUninterpretedOptionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +EnumValueOptions::EnumValueOptions()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.EnumValueOptions)
    +}
    +
    +void EnumValueOptions::InitAsDefaultInstance() {
    +}
    +
    +EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
    +}
    +
    +void EnumValueOptions::SharedCtor() {
    +  _cached_size_ = 0;
    +  deprecated_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +EnumValueOptions::~EnumValueOptions() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions)
    +  SharedDtor();
    +}
    +
    +void EnumValueOptions::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void EnumValueOptions::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return EnumValueOptions_descriptor_;
    +}
    +
    +const EnumValueOptions& EnumValueOptions::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +EnumValueOptions* EnumValueOptions::default_instance_ = NULL;
    +
    +EnumValueOptions* EnumValueOptions::New() const {
    +  return new EnumValueOptions;
    +}
    +
    +void EnumValueOptions::Clear() {
    +  _extensions_.Clear();
    +  deprecated_ = false;
    +  uninterpreted_option_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool EnumValueOptions::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueOptions)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional bool deprecated = 1 [default = false];
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &deprecated_)));
    +          set_has_deprecated();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +      case 999: {
    +        if (tag == 7994) {
    +         parse_uninterpreted_option:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_uninterpreted_option()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        if ((8000u <= tag)) {
    +          DO_(_extensions_.ParseField(tag, input, default_instance_,
    +                                      mutable_unknown_fields()));
    +          continue;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueOptions)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueOptions)
    +  return false;
    +#undef DO_
    +}
    +
    +void EnumValueOptions::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueOptions)
    +  // optional bool deprecated = 1 [default = false];
    +  if (has_deprecated()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->deprecated(), output);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      999, this->uninterpreted_option(i), output);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  _extensions_.SerializeWithCachedSizes(
    +      1000, 536870912, output);
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueOptions)
    +}
    +
    +::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions)
    +  // optional bool deprecated = 1 [default = false];
    +  if (has_deprecated()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->deprecated(), target);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        999, this->uninterpreted_option(i), target);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  target = _extensions_.SerializeWithCachedSizesToArray(
    +      1000, 536870912, target);
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions)
    +  return target;
    +}
    +
    +int EnumValueOptions::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional bool deprecated = 1 [default = false];
    +    if (has_deprecated()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  total_size += 2 * this->uninterpreted_option_size();
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->uninterpreted_option(i));
    +  }
    +
    +  total_size += _extensions_.ByteSize();
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const EnumValueOptions* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_deprecated()) {
    +      set_deprecated(from.deprecated());
    +    }
    +  }
    +  _extensions_.MergeFrom(from._extensions_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool EnumValueOptions::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
    +
    +  if (!_extensions_.IsInitialized()) return false;  return true;
    +}
    +
    +void EnumValueOptions::Swap(EnumValueOptions* other) {
    +  if (other != this) {
    +    std::swap(deprecated_, other->deprecated_);
    +    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +    _extensions_.Swap(&other->_extensions_);
    +  }
    +}
    +
    +::google::protobuf::Metadata EnumValueOptions::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = EnumValueOptions_descriptor_;
    +  metadata.reflection = EnumValueOptions_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int ServiceOptions::kDeprecatedFieldNumber;
    +const int ServiceOptions::kUninterpretedOptionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +ServiceOptions::ServiceOptions()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.ServiceOptions)
    +}
    +
    +void ServiceOptions::InitAsDefaultInstance() {
    +}
    +
    +ServiceOptions::ServiceOptions(const ServiceOptions& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
    +}
    +
    +void ServiceOptions::SharedCtor() {
    +  _cached_size_ = 0;
    +  deprecated_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +ServiceOptions::~ServiceOptions() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions)
    +  SharedDtor();
    +}
    +
    +void ServiceOptions::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void ServiceOptions::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return ServiceOptions_descriptor_;
    +}
    +
    +const ServiceOptions& ServiceOptions::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +ServiceOptions* ServiceOptions::default_instance_ = NULL;
    +
    +ServiceOptions* ServiceOptions::New() const {
    +  return new ServiceOptions;
    +}
    +
    +void ServiceOptions::Clear() {
    +  _extensions_.Clear();
    +  deprecated_ = false;
    +  uninterpreted_option_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool ServiceOptions::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.ServiceOptions)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional bool deprecated = 33 [default = false];
    +      case 33: {
    +        if (tag == 264) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &deprecated_)));
    +          set_has_deprecated();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +      case 999: {
    +        if (tag == 7994) {
    +         parse_uninterpreted_option:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_uninterpreted_option()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        if ((8000u <= tag)) {
    +          DO_(_extensions_.ParseField(tag, input, default_instance_,
    +                                      mutable_unknown_fields()));
    +          continue;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.ServiceOptions)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceOptions)
    +  return false;
    +#undef DO_
    +}
    +
    +void ServiceOptions::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceOptions)
    +  // optional bool deprecated = 33 [default = false];
    +  if (has_deprecated()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      999, this->uninterpreted_option(i), output);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  _extensions_.SerializeWithCachedSizes(
    +      1000, 536870912, output);
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceOptions)
    +}
    +
    +::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions)
    +  // optional bool deprecated = 33 [default = false];
    +  if (has_deprecated()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        999, this->uninterpreted_option(i), target);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  target = _extensions_.SerializeWithCachedSizesToArray(
    +      1000, 536870912, target);
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions)
    +  return target;
    +}
    +
    +int ServiceOptions::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional bool deprecated = 33 [default = false];
    +    if (has_deprecated()) {
    +      total_size += 2 + 1;
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  total_size += 2 * this->uninterpreted_option_size();
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->uninterpreted_option(i));
    +  }
    +
    +  total_size += _extensions_.ByteSize();
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const ServiceOptions* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void ServiceOptions::MergeFrom(const ServiceOptions& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_deprecated()) {
    +      set_deprecated(from.deprecated());
    +    }
    +  }
    +  _extensions_.MergeFrom(from._extensions_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void ServiceOptions::CopyFrom(const ServiceOptions& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool ServiceOptions::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
    +
    +  if (!_extensions_.IsInitialized()) return false;  return true;
    +}
    +
    +void ServiceOptions::Swap(ServiceOptions* other) {
    +  if (other != this) {
    +    std::swap(deprecated_, other->deprecated_);
    +    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +    _extensions_.Swap(&other->_extensions_);
    +  }
    +}
    +
    +::google::protobuf::Metadata ServiceOptions::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = ServiceOptions_descriptor_;
    +  metadata.reflection = ServiceOptions_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int MethodOptions::kDeprecatedFieldNumber;
    +const int MethodOptions::kUninterpretedOptionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +MethodOptions::MethodOptions()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.MethodOptions)
    +}
    +
    +void MethodOptions::InitAsDefaultInstance() {
    +}
    +
    +MethodOptions::MethodOptions(const MethodOptions& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
    +}
    +
    +void MethodOptions::SharedCtor() {
    +  _cached_size_ = 0;
    +  deprecated_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +MethodOptions::~MethodOptions() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions)
    +  SharedDtor();
    +}
    +
    +void MethodOptions::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void MethodOptions::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return MethodOptions_descriptor_;
    +}
    +
    +const MethodOptions& MethodOptions::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +MethodOptions* MethodOptions::default_instance_ = NULL;
    +
    +MethodOptions* MethodOptions::New() const {
    +  return new MethodOptions;
    +}
    +
    +void MethodOptions::Clear() {
    +  _extensions_.Clear();
    +  deprecated_ = false;
    +  uninterpreted_option_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool MethodOptions::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.MethodOptions)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional bool deprecated = 33 [default = false];
    +      case 33: {
    +        if (tag == 264) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &deprecated_)));
    +          set_has_deprecated();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        break;
    +      }
    +
    +      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +      case 999: {
    +        if (tag == 7994) {
    +         parse_uninterpreted_option:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_uninterpreted_option()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        if ((8000u <= tag)) {
    +          DO_(_extensions_.ParseField(tag, input, default_instance_,
    +                                      mutable_unknown_fields()));
    +          continue;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.MethodOptions)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.MethodOptions)
    +  return false;
    +#undef DO_
    +}
    +
    +void MethodOptions::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.MethodOptions)
    +  // optional bool deprecated = 33 [default = false];
    +  if (has_deprecated()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      999, this->uninterpreted_option(i), output);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  _extensions_.SerializeWithCachedSizes(
    +      1000, 536870912, output);
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.MethodOptions)
    +}
    +
    +::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions)
    +  // optional bool deprecated = 33 [default = false];
    +  if (has_deprecated()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
    +  }
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        999, this->uninterpreted_option(i), target);
    +  }
    +
    +  // Extension range [1000, 536870912)
    +  target = _extensions_.SerializeWithCachedSizesToArray(
    +      1000, 536870912, target);
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions)
    +  return target;
    +}
    +
    +int MethodOptions::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional bool deprecated = 33 [default = false];
    +    if (has_deprecated()) {
    +      total_size += 2 + 1;
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  total_size += 2 * this->uninterpreted_option_size();
    +  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->uninterpreted_option(i));
    +  }
    +
    +  total_size += _extensions_.ByteSize();
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const MethodOptions* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void MethodOptions::MergeFrom(const MethodOptions& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_deprecated()) {
    +      set_deprecated(from.deprecated());
    +    }
    +  }
    +  _extensions_.MergeFrom(from._extensions_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void MethodOptions::CopyFrom(const MethodOptions& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool MethodOptions::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
    +
    +  if (!_extensions_.IsInitialized()) return false;  return true;
    +}
    +
    +void MethodOptions::Swap(MethodOptions* other) {
    +  if (other != this) {
    +    std::swap(deprecated_, other->deprecated_);
    +    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +    _extensions_.Swap(&other->_extensions_);
    +  }
    +}
    +
    +::google::protobuf::Metadata MethodOptions::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = MethodOptions_descriptor_;
    +  metadata.reflection = MethodOptions_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int UninterpretedOption_NamePart::kNamePartFieldNumber;
    +const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
    +#endif  // !_MSC_VER
    +
    +UninterpretedOption_NamePart::UninterpretedOption_NamePart()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption.NamePart)
    +}
    +
    +void UninterpretedOption_NamePart::InitAsDefaultInstance() {
    +}
    +
    +UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
    +}
    +
    +void UninterpretedOption_NamePart::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  is_extension_ = false;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart)
    +  SharedDtor();
    +}
    +
    +void UninterpretedOption_NamePart::SharedDtor() {
    +  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_part_;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void UninterpretedOption_NamePart::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return UninterpretedOption_NamePart_descriptor_;
    +}
    +
    +const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL;
    +
    +UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const {
    +  return new UninterpretedOption_NamePart;
    +}
    +
    +void UninterpretedOption_NamePart::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    if (has_name_part()) {
    +      if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_part_->clear();
    +      }
    +    }
    +    is_extension_ = false;
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption.NamePart)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // required string name_part = 1;
    +      case 1: {
    +        if (tag == 10) {
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_name_part()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->name_part().data(), this->name_part().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "name_part");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(16)) goto parse_is_extension;
    +        break;
    +      }
    +
    +      // required bool is_extension = 2;
    +      case 2: {
    +        if (tag == 16) {
    +         parse_is_extension:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
    +                 input, &is_extension_)));
    +          set_has_is_extension();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption.NamePart)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption.NamePart)
    +  return false;
    +#undef DO_
    +}
    +
    +void UninterpretedOption_NamePart::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption.NamePart)
    +  // required string name_part = 1;
    +  if (has_name_part()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name_part().data(), this->name_part().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name_part");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      1, this->name_part(), output);
    +  }
    +
    +  // required bool is_extension = 2;
    +  if (has_is_extension()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption.NamePart)
    +}
    +
    +::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart)
    +  // required string name_part = 1;
    +  if (has_name_part()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->name_part().data(), this->name_part().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "name_part");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        1, this->name_part(), target);
    +  }
    +
    +  // required bool is_extension = 2;
    +  if (has_is_extension()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart)
    +  return target;
    +}
    +
    +int UninterpretedOption_NamePart::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // required string name_part = 1;
    +    if (has_name_part()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->name_part());
    +    }
    +
    +    // required bool is_extension = 2;
    +    if (has_is_extension()) {
    +      total_size += 1 + 1;
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const UninterpretedOption_NamePart* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_name_part()) {
    +      set_name_part(from.name_part());
    +    }
    +    if (from.has_is_extension()) {
    +      set_is_extension(from.is_extension());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void UninterpretedOption_NamePart::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool UninterpretedOption_NamePart::IsInitialized() const {
    +  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
    +
    +  return true;
    +}
    +
    +void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) {
    +  if (other != this) {
    +    std::swap(name_part_, other->name_part_);
    +    std::swap(is_extension_, other->is_extension_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = UninterpretedOption_NamePart_descriptor_;
    +  metadata.reflection = UninterpretedOption_NamePart_reflection_;
    +  return metadata;
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int UninterpretedOption::kNameFieldNumber;
    +const int UninterpretedOption::kIdentifierValueFieldNumber;
    +const int UninterpretedOption::kPositiveIntValueFieldNumber;
    +const int UninterpretedOption::kNegativeIntValueFieldNumber;
    +const int UninterpretedOption::kDoubleValueFieldNumber;
    +const int UninterpretedOption::kStringValueFieldNumber;
    +const int UninterpretedOption::kAggregateValueFieldNumber;
    +#endif  // !_MSC_VER
    +
    +UninterpretedOption::UninterpretedOption()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption)
    +}
    +
    +void UninterpretedOption::InitAsDefaultInstance() {
    +}
    +
    +UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
    +}
    +
    +void UninterpretedOption::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  positive_int_value_ = GOOGLE_ULONGLONG(0);
    +  negative_int_value_ = GOOGLE_LONGLONG(0);
    +  double_value_ = 0;
    +  string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +UninterpretedOption::~UninterpretedOption() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption)
    +  SharedDtor();
    +}
    +
    +void UninterpretedOption::SharedDtor() {
    +  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete identifier_value_;
    +  }
    +  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete string_value_;
    +  }
    +  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete aggregate_value_;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void UninterpretedOption::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return UninterpretedOption_descriptor_;
    +}
    +
    +const UninterpretedOption& UninterpretedOption::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +UninterpretedOption* UninterpretedOption::default_instance_ = NULL;
    +
    +UninterpretedOption* UninterpretedOption::New() const {
    +  return new UninterpretedOption;
    +}
    +
    +void UninterpretedOption::Clear() {
    +#define OFFSET_OF_FIELD_(f) (reinterpret_cast(      \
    +  &reinterpret_cast(16)->f) - \
    +   reinterpret_cast(16))
    +
    +#define ZR_(first, last) do {                              \
    +    size_t f = OFFSET_OF_FIELD_(first);                    \
    +    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
    +    ::memset(&first, 0, n);                                \
    +  } while (0)
    +
    +  if (_has_bits_[0 / 32] & 126) {
    +    ZR_(positive_int_value_, double_value_);
    +    if (has_identifier_value()) {
    +      if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        identifier_value_->clear();
    +      }
    +    }
    +    if (has_string_value()) {
    +      if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        string_value_->clear();
    +      }
    +    }
    +    if (has_aggregate_value()) {
    +      if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        aggregate_value_->clear();
    +      }
    +    }
    +  }
    +
    +#undef OFFSET_OF_FIELD_
    +#undef ZR_
    +
    +  name_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool UninterpretedOption::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_name:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_name()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_name;
    +        if (input->ExpectTag(26)) goto parse_identifier_value;
    +        break;
    +      }
    +
    +      // optional string identifier_value = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_identifier_value:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_identifier_value()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->identifier_value().data(), this->identifier_value().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "identifier_value");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(32)) goto parse_positive_int_value;
    +        break;
    +      }
    +
    +      // optional uint64 positive_int_value = 4;
    +      case 4: {
    +        if (tag == 32) {
    +         parse_positive_int_value:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
    +                 input, &positive_int_value_)));
    +          set_has_positive_int_value();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(40)) goto parse_negative_int_value;
    +        break;
    +      }
    +
    +      // optional int64 negative_int_value = 5;
    +      case 5: {
    +        if (tag == 40) {
    +         parse_negative_int_value:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
    +                 input, &negative_int_value_)));
    +          set_has_negative_int_value();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(49)) goto parse_double_value;
    +        break;
    +      }
    +
    +      // optional double double_value = 6;
    +      case 6: {
    +        if (tag == 49) {
    +         parse_double_value:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
    +                 input, &double_value_)));
    +          set_has_double_value();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(58)) goto parse_string_value;
    +        break;
    +      }
    +
    +      // optional bytes string_value = 7;
    +      case 7: {
    +        if (tag == 58) {
    +         parse_string_value:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
    +                input, this->mutable_string_value()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(66)) goto parse_aggregate_value;
    +        break;
    +      }
    +
    +      // optional string aggregate_value = 8;
    +      case 8: {
    +        if (tag == 66) {
    +         parse_aggregate_value:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_aggregate_value()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->aggregate_value().data(), this->aggregate_value().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "aggregate_value");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption)
    +  return false;
    +#undef DO_
    +}
    +
    +void UninterpretedOption::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption)
    +  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
    +  for (int i = 0; i < this->name_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      2, this->name(i), output);
    +  }
    +
    +  // optional string identifier_value = 3;
    +  if (has_identifier_value()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->identifier_value().data(), this->identifier_value().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "identifier_value");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      3, this->identifier_value(), output);
    +  }
    +
    +  // optional uint64 positive_int_value = 4;
    +  if (has_positive_int_value()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
    +  }
    +
    +  // optional int64 negative_int_value = 5;
    +  if (has_negative_int_value()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
    +  }
    +
    +  // optional double double_value = 6;
    +  if (has_double_value()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
    +  }
    +
    +  // optional bytes string_value = 7;
    +  if (has_string_value()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
    +      7, this->string_value(), output);
    +  }
    +
    +  // optional string aggregate_value = 8;
    +  if (has_aggregate_value()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->aggregate_value().data(), this->aggregate_value().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "aggregate_value");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      8, this->aggregate_value(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption)
    +}
    +
    +::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption)
    +  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
    +  for (int i = 0; i < this->name_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        2, this->name(i), target);
    +  }
    +
    +  // optional string identifier_value = 3;
    +  if (has_identifier_value()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->identifier_value().data(), this->identifier_value().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "identifier_value");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        3, this->identifier_value(), target);
    +  }
    +
    +  // optional uint64 positive_int_value = 4;
    +  if (has_positive_int_value()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
    +  }
    +
    +  // optional int64 negative_int_value = 5;
    +  if (has_negative_int_value()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
    +  }
    +
    +  // optional double double_value = 6;
    +  if (has_double_value()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
    +  }
    +
    +  // optional bytes string_value = 7;
    +  if (has_string_value()) {
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
    +        7, this->string_value(), target);
    +  }
    +
    +  // optional string aggregate_value = 8;
    +  if (has_aggregate_value()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->aggregate_value().data(), this->aggregate_value().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "aggregate_value");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        8, this->aggregate_value(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption)
    +  return target;
    +}
    +
    +int UninterpretedOption::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    +    // optional string identifier_value = 3;
    +    if (has_identifier_value()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->identifier_value());
    +    }
    +
    +    // optional uint64 positive_int_value = 4;
    +    if (has_positive_int_value()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt64Size(
    +          this->positive_int_value());
    +    }
    +
    +    // optional int64 negative_int_value = 5;
    +    if (has_negative_int_value()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int64Size(
    +          this->negative_int_value());
    +    }
    +
    +    // optional double double_value = 6;
    +    if (has_double_value()) {
    +      total_size += 1 + 8;
    +    }
    +
    +    // optional bytes string_value = 7;
    +    if (has_string_value()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::BytesSize(
    +          this->string_value());
    +    }
    +
    +    // optional string aggregate_value = 8;
    +    if (has_aggregate_value()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->aggregate_value());
    +    }
    +
    +  }
    +  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
    +  total_size += 1 * this->name_size();
    +  for (int i = 0; i < this->name_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->name(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const UninterpretedOption* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  name_.MergeFrom(from.name_);
    +  if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    +    if (from.has_identifier_value()) {
    +      set_identifier_value(from.identifier_value());
    +    }
    +    if (from.has_positive_int_value()) {
    +      set_positive_int_value(from.positive_int_value());
    +    }
    +    if (from.has_negative_int_value()) {
    +      set_negative_int_value(from.negative_int_value());
    +    }
    +    if (from.has_double_value()) {
    +      set_double_value(from.double_value());
    +    }
    +    if (from.has_string_value()) {
    +      set_string_value(from.string_value());
    +    }
    +    if (from.has_aggregate_value()) {
    +      set_aggregate_value(from.aggregate_value());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void UninterpretedOption::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool UninterpretedOption::IsInitialized() const {
    +
    +  if (!::google::protobuf::internal::AllAreInitialized(this->name())) return false;
    +  return true;
    +}
    +
    +void UninterpretedOption::Swap(UninterpretedOption* other) {
    +  if (other != this) {
    +    name_.Swap(&other->name_);
    +    std::swap(identifier_value_, other->identifier_value_);
    +    std::swap(positive_int_value_, other->positive_int_value_);
    +    std::swap(negative_int_value_, other->negative_int_value_);
    +    std::swap(double_value_, other->double_value_);
    +    std::swap(string_value_, other->string_value_);
    +    std::swap(aggregate_value_, other->aggregate_value_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata UninterpretedOption::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = UninterpretedOption_descriptor_;
    +  metadata.reflection = UninterpretedOption_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int SourceCodeInfo_Location::kPathFieldNumber;
    +const int SourceCodeInfo_Location::kSpanFieldNumber;
    +const int SourceCodeInfo_Location::kLeadingCommentsFieldNumber;
    +const int SourceCodeInfo_Location::kTrailingCommentsFieldNumber;
    +#endif  // !_MSC_VER
    +
    +SourceCodeInfo_Location::SourceCodeInfo_Location()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo.Location)
    +}
    +
    +void SourceCodeInfo_Location::InitAsDefaultInstance() {
    +}
    +
    +SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
    +}
    +
    +void SourceCodeInfo_Location::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +SourceCodeInfo_Location::~SourceCodeInfo_Location() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location)
    +  SharedDtor();
    +}
    +
    +void SourceCodeInfo_Location::SharedDtor() {
    +  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete leading_comments_;
    +  }
    +  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete trailing_comments_;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void SourceCodeInfo_Location::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return SourceCodeInfo_Location_descriptor_;
    +}
    +
    +const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL;
    +
    +SourceCodeInfo_Location* SourceCodeInfo_Location::New() const {
    +  return new SourceCodeInfo_Location;
    +}
    +
    +void SourceCodeInfo_Location::Clear() {
    +  if (_has_bits_[0 / 32] & 12) {
    +    if (has_leading_comments()) {
    +      if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        leading_comments_->clear();
    +      }
    +    }
    +    if (has_trailing_comments()) {
    +      if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        trailing_comments_->clear();
    +      }
    +    }
    +  }
    +  path_.Clear();
    +  span_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool SourceCodeInfo_Location::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo.Location)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // repeated int32 path = 1 [packed = true];
    +      case 1: {
    +        if (tag == 10) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, this->mutable_path())));
    +        } else if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 1, 10, input, this->mutable_path())));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_span;
    +        break;
    +      }
    +
    +      // repeated int32 span = 2 [packed = true];
    +      case 2: {
    +        if (tag == 18) {
    +         parse_span:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 input, this->mutable_span())));
    +        } else if (tag == 16) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
    +                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
    +                 1, 18, input, this->mutable_span())));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(26)) goto parse_leading_comments;
    +        break;
    +      }
    +
    +      // optional string leading_comments = 3;
    +      case 3: {
    +        if (tag == 26) {
    +         parse_leading_comments:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_leading_comments()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->leading_comments().data(), this->leading_comments().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "leading_comments");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_trailing_comments;
    +        break;
    +      }
    +
    +      // optional string trailing_comments = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_trailing_comments:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
    +                input, this->mutable_trailing_comments()));
    +          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +            this->trailing_comments().data(), this->trailing_comments().length(),
    +            ::google::protobuf::internal::WireFormat::PARSE,
    +            "trailing_comments");
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.SourceCodeInfo.Location)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo.Location)
    +  return false;
    +#undef DO_
    +}
    +
    +void SourceCodeInfo_Location::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo.Location)
    +  // repeated int32 path = 1 [packed = true];
    +  if (this->path_size() > 0) {
    +    ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    +    output->WriteVarint32(_path_cached_byte_size_);
    +  }
    +  for (int i = 0; i < this->path_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
    +      this->path(i), output);
    +  }
    +
    +  // repeated int32 span = 2 [packed = true];
    +  if (this->span_size() > 0) {
    +    ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    +    output->WriteVarint32(_span_cached_byte_size_);
    +  }
    +  for (int i = 0; i < this->span_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
    +      this->span(i), output);
    +  }
    +
    +  // optional string leading_comments = 3;
    +  if (has_leading_comments()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->leading_comments().data(), this->leading_comments().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "leading_comments");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      3, this->leading_comments(), output);
    +  }
    +
    +  // optional string trailing_comments = 4;
    +  if (has_trailing_comments()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->trailing_comments().data(), this->trailing_comments().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "trailing_comments");
    +    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
    +      4, this->trailing_comments(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo.Location)
    +}
    +
    +::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location)
    +  // repeated int32 path = 1 [packed = true];
    +  if (this->path_size() > 0) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
    +      1,
    +      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
    +      target);
    +    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
    +      _path_cached_byte_size_, target);
    +  }
    +  for (int i = 0; i < this->path_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteInt32NoTagToArray(this->path(i), target);
    +  }
    +
    +  // repeated int32 span = 2 [packed = true];
    +  if (this->span_size() > 0) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
    +      2,
    +      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
    +      target);
    +    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
    +      _span_cached_byte_size_, target);
    +  }
    +  for (int i = 0; i < this->span_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteInt32NoTagToArray(this->span(i), target);
    +  }
    +
    +  // optional string leading_comments = 3;
    +  if (has_leading_comments()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->leading_comments().data(), this->leading_comments().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "leading_comments");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        3, this->leading_comments(), target);
    +  }
    +
    +  // optional string trailing_comments = 4;
    +  if (has_trailing_comments()) {
    +    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
    +      this->trailing_comments().data(), this->trailing_comments().length(),
    +      ::google::protobuf::internal::WireFormat::SERIALIZE,
    +      "trailing_comments");
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
    +        4, this->trailing_comments(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location)
    +  return target;
    +}
    +
    +int SourceCodeInfo_Location::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[2 / 32] & (0xffu << (2 % 32))) {
    +    // optional string leading_comments = 3;
    +    if (has_leading_comments()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->leading_comments());
    +    }
    +
    +    // optional string trailing_comments = 4;
    +    if (has_trailing_comments()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::StringSize(
    +          this->trailing_comments());
    +    }
    +
    +  }
    +  // repeated int32 path = 1 [packed = true];
    +  {
    +    int data_size = 0;
    +    for (int i = 0; i < this->path_size(); i++) {
    +      data_size += ::google::protobuf::internal::WireFormatLite::
    +        Int32Size(this->path(i));
    +    }
    +    if (data_size > 0) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    +    }
    +    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +    _path_cached_byte_size_ = data_size;
    +    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +    total_size += data_size;
    +  }
    +
    +  // repeated int32 span = 2 [packed = true];
    +  {
    +    int data_size = 0;
    +    for (int i = 0; i < this->span_size(); i++) {
    +      data_size += ::google::protobuf::internal::WireFormatLite::
    +        Int32Size(this->span(i));
    +    }
    +    if (data_size > 0) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    +    }
    +    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +    _span_cached_byte_size_ = data_size;
    +    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +    total_size += data_size;
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const SourceCodeInfo_Location* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  path_.MergeFrom(from.path_);
    +  span_.MergeFrom(from.span_);
    +  if (from._has_bits_[2 / 32] & (0xffu << (2 % 32))) {
    +    if (from.has_leading_comments()) {
    +      set_leading_comments(from.leading_comments());
    +    }
    +    if (from.has_trailing_comments()) {
    +      set_trailing_comments(from.trailing_comments());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool SourceCodeInfo_Location::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) {
    +  if (other != this) {
    +    path_.Swap(&other->path_);
    +    span_.Swap(&other->span_);
    +    std::swap(leading_comments_, other->leading_comments_);
    +    std::swap(trailing_comments_, other->trailing_comments_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = SourceCodeInfo_Location_descriptor_;
    +  metadata.reflection = SourceCodeInfo_Location_reflection_;
    +  return metadata;
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +#ifndef _MSC_VER
    +const int SourceCodeInfo::kLocationFieldNumber;
    +#endif  // !_MSC_VER
    +
    +SourceCodeInfo::SourceCodeInfo()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo)
    +}
    +
    +void SourceCodeInfo::InitAsDefaultInstance() {
    +}
    +
    +SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
    +}
    +
    +void SourceCodeInfo::SharedCtor() {
    +  _cached_size_ = 0;
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +SourceCodeInfo::~SourceCodeInfo() {
    +  // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo)
    +  SharedDtor();
    +}
    +
    +void SourceCodeInfo::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void SourceCodeInfo::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return SourceCodeInfo_descriptor_;
    +}
    +
    +const SourceCodeInfo& SourceCodeInfo::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  return *default_instance_;
    +}
    +
    +SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL;
    +
    +SourceCodeInfo* SourceCodeInfo::New() const {
    +  return new SourceCodeInfo;
    +}
    +
    +void SourceCodeInfo::Clear() {
    +  location_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool SourceCodeInfo::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
    +      case 1: {
    +        if (tag == 10) {
    +         parse_location:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_location()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(10)) goto parse_location;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:google.protobuf.SourceCodeInfo)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo)
    +  return false;
    +#undef DO_
    +}
    +
    +void SourceCodeInfo::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo)
    +  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
    +  for (int i = 0; i < this->location_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      1, this->location(i), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo)
    +}
    +
    +::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo)
    +  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
    +  for (int i = 0; i < this->location_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        1, this->location(i), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo)
    +  return target;
    +}
    +
    +int SourceCodeInfo::ByteSize() const {
    +  int total_size = 0;
    +
    +  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
    +  total_size += 1 * this->location_size();
    +  for (int i = 0; i < this->location_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->location(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const SourceCodeInfo* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  location_.MergeFrom(from.location_);
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool SourceCodeInfo::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void SourceCodeInfo::Swap(SourceCodeInfo* other) {
    +  if (other != this) {
    +    location_.Swap(&other->location_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = SourceCodeInfo_descriptor_;
    +  metadata.reflection = SourceCodeInfo_reflection_;
    +  return metadata;
    +}
    +
    +
    +// @@protoc_insertion_point(namespace_scope)
    +
    +}  // namespace protobuf
    +}  // namespace google
    +
    +// @@protoc_insertion_point(global_scope)
    diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h
    new file mode 100644
    index 000000000000..45521812c359
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h
    @@ -0,0 +1,6761 @@
    +// Generated by the protocol buffer compiler.  DO NOT EDIT!
    +// source: google/protobuf/descriptor.proto
    +
    +#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
    +#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
    +
    +#include 
    +
    +#include 
    +
    +#if GOOGLE_PROTOBUF_VERSION < 2006000
    +#error This file was generated by a newer version of protoc which is
    +#error incompatible with your Protocol Buffer headers.  Please update
    +#error your headers.
    +#endif
    +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
    +#error This file was generated by an older version of protoc which is
    +#error incompatible with your Protocol Buffer headers.  Please
    +#error regenerate this file with a newer version of protoc.
    +#endif
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +// @@protoc_insertion_point(includes)
    +
    +namespace google {
    +namespace protobuf {
    +
    +// Internal implementation detail -- do not call these.
    +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +class FileDescriptorSet;
    +class FileDescriptorProto;
    +class DescriptorProto;
    +class DescriptorProto_ExtensionRange;
    +class FieldDescriptorProto;
    +class OneofDescriptorProto;
    +class EnumDescriptorProto;
    +class EnumValueDescriptorProto;
    +class ServiceDescriptorProto;
    +class MethodDescriptorProto;
    +class FileOptions;
    +class MessageOptions;
    +class FieldOptions;
    +class EnumOptions;
    +class EnumValueOptions;
    +class ServiceOptions;
    +class MethodOptions;
    +class UninterpretedOption;
    +class UninterpretedOption_NamePart;
    +class SourceCodeInfo;
    +class SourceCodeInfo_Location;
    +
    +enum FieldDescriptorProto_Type {
    +  FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
    +  FieldDescriptorProto_Type_TYPE_FLOAT = 2,
    +  FieldDescriptorProto_Type_TYPE_INT64 = 3,
    +  FieldDescriptorProto_Type_TYPE_UINT64 = 4,
    +  FieldDescriptorProto_Type_TYPE_INT32 = 5,
    +  FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
    +  FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
    +  FieldDescriptorProto_Type_TYPE_BOOL = 8,
    +  FieldDescriptorProto_Type_TYPE_STRING = 9,
    +  FieldDescriptorProto_Type_TYPE_GROUP = 10,
    +  FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
    +  FieldDescriptorProto_Type_TYPE_BYTES = 12,
    +  FieldDescriptorProto_Type_TYPE_UINT32 = 13,
    +  FieldDescriptorProto_Type_TYPE_ENUM = 14,
    +  FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
    +  FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
    +  FieldDescriptorProto_Type_TYPE_SINT32 = 17,
    +  FieldDescriptorProto_Type_TYPE_SINT64 = 18
    +};
    +LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value);
    +const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
    +const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
    +const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1;
    +
    +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor();
    +inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) {
    +  return ::google::protobuf::internal::NameOfEnum(
    +    FieldDescriptorProto_Type_descriptor(), value);
    +}
    +inline bool FieldDescriptorProto_Type_Parse(
    +    const ::std::string& name, FieldDescriptorProto_Type* value) {
    +  return ::google::protobuf::internal::ParseNamedEnum(
    +    FieldDescriptorProto_Type_descriptor(), name, value);
    +}
    +enum FieldDescriptorProto_Label {
    +  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
    +  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
    +  FieldDescriptorProto_Label_LABEL_REPEATED = 3
    +};
    +LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value);
    +const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
    +const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
    +const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1;
    +
    +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor();
    +inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) {
    +  return ::google::protobuf::internal::NameOfEnum(
    +    FieldDescriptorProto_Label_descriptor(), value);
    +}
    +inline bool FieldDescriptorProto_Label_Parse(
    +    const ::std::string& name, FieldDescriptorProto_Label* value) {
    +  return ::google::protobuf::internal::ParseNamedEnum(
    +    FieldDescriptorProto_Label_descriptor(), name, value);
    +}
    +enum FileOptions_OptimizeMode {
    +  FileOptions_OptimizeMode_SPEED = 1,
    +  FileOptions_OptimizeMode_CODE_SIZE = 2,
    +  FileOptions_OptimizeMode_LITE_RUNTIME = 3
    +};
    +LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value);
    +const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED;
    +const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME;
    +const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1;
    +
    +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor();
    +inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) {
    +  return ::google::protobuf::internal::NameOfEnum(
    +    FileOptions_OptimizeMode_descriptor(), value);
    +}
    +inline bool FileOptions_OptimizeMode_Parse(
    +    const ::std::string& name, FileOptions_OptimizeMode* value) {
    +  return ::google::protobuf::internal::ParseNamedEnum(
    +    FileOptions_OptimizeMode_descriptor(), name, value);
    +}
    +enum FieldOptions_CType {
    +  FieldOptions_CType_STRING = 0,
    +  FieldOptions_CType_CORD = 1,
    +  FieldOptions_CType_STRING_PIECE = 2
    +};
    +LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value);
    +const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING;
    +const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
    +const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1;
    +
    +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor();
    +inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) {
    +  return ::google::protobuf::internal::NameOfEnum(
    +    FieldOptions_CType_descriptor(), value);
    +}
    +inline bool FieldOptions_CType_Parse(
    +    const ::std::string& name, FieldOptions_CType* value) {
    +  return ::google::protobuf::internal::ParseNamedEnum(
    +    FieldOptions_CType_descriptor(), name, value);
    +}
    +// ===================================================================
    +
    +class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message {
    + public:
    +  FileDescriptorSet();
    +  virtual ~FileDescriptorSet();
    +
    +  FileDescriptorSet(const FileDescriptorSet& from);
    +
    +  inline FileDescriptorSet& operator=(const FileDescriptorSet& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const FileDescriptorSet& default_instance();
    +
    +  void Swap(FileDescriptorSet* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  FileDescriptorSet* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const FileDescriptorSet& from);
    +  void MergeFrom(const FileDescriptorSet& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // repeated .google.protobuf.FileDescriptorProto file = 1;
    +  inline int file_size() const;
    +  inline void clear_file();
    +  static const int kFileFieldNumber = 1;
    +  inline const ::google::protobuf::FileDescriptorProto& file(int index) const;
    +  inline ::google::protobuf::FileDescriptorProto* mutable_file(int index);
    +  inline ::google::protobuf::FileDescriptorProto* add_file();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
    +      file() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
    +      mutable_file();
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
    + private:
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static FileDescriptorSet* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message {
    + public:
    +  FileDescriptorProto();
    +  virtual ~FileDescriptorProto();
    +
    +  FileDescriptorProto(const FileDescriptorProto& from);
    +
    +  inline FileDescriptorProto& operator=(const FileDescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const FileDescriptorProto& default_instance();
    +
    +  void Swap(FileDescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  FileDescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const FileDescriptorProto& from);
    +  void MergeFrom(const FileDescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // optional string package = 2;
    +  inline bool has_package() const;
    +  inline void clear_package();
    +  static const int kPackageFieldNumber = 2;
    +  inline const ::std::string& package() const;
    +  inline void set_package(const ::std::string& value);
    +  inline void set_package(const char* value);
    +  inline void set_package(const char* value, size_t size);
    +  inline ::std::string* mutable_package();
    +  inline ::std::string* release_package();
    +  inline void set_allocated_package(::std::string* package);
    +
    +  // repeated string dependency = 3;
    +  inline int dependency_size() const;
    +  inline void clear_dependency();
    +  static const int kDependencyFieldNumber = 3;
    +  inline const ::std::string& dependency(int index) const;
    +  inline ::std::string* mutable_dependency(int index);
    +  inline void set_dependency(int index, const ::std::string& value);
    +  inline void set_dependency(int index, const char* value);
    +  inline void set_dependency(int index, const char* value, size_t size);
    +  inline ::std::string* add_dependency();
    +  inline void add_dependency(const ::std::string& value);
    +  inline void add_dependency(const char* value);
    +  inline void add_dependency(const char* value, size_t size);
    +  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
    +
    +  // repeated int32 public_dependency = 10;
    +  inline int public_dependency_size() const;
    +  inline void clear_public_dependency();
    +  static const int kPublicDependencyFieldNumber = 10;
    +  inline ::google::protobuf::int32 public_dependency(int index) const;
    +  inline void set_public_dependency(int index, ::google::protobuf::int32 value);
    +  inline void add_public_dependency(::google::protobuf::int32 value);
    +  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +      public_dependency() const;
    +  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +      mutable_public_dependency();
    +
    +  // repeated int32 weak_dependency = 11;
    +  inline int weak_dependency_size() const;
    +  inline void clear_weak_dependency();
    +  static const int kWeakDependencyFieldNumber = 11;
    +  inline ::google::protobuf::int32 weak_dependency(int index) const;
    +  inline void set_weak_dependency(int index, ::google::protobuf::int32 value);
    +  inline void add_weak_dependency(::google::protobuf::int32 value);
    +  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +      weak_dependency() const;
    +  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +      mutable_weak_dependency();
    +
    +  // repeated .google.protobuf.DescriptorProto message_type = 4;
    +  inline int message_type_size() const;
    +  inline void clear_message_type();
    +  static const int kMessageTypeFieldNumber = 4;
    +  inline const ::google::protobuf::DescriptorProto& message_type(int index) const;
    +  inline ::google::protobuf::DescriptorProto* mutable_message_type(int index);
    +  inline ::google::protobuf::DescriptorProto* add_message_type();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
    +      message_type() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
    +      mutable_message_type();
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
    +  inline int enum_type_size() const;
    +  inline void clear_enum_type();
    +  static const int kEnumTypeFieldNumber = 5;
    +  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
    +  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
    +  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
    +      enum_type() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
    +      mutable_enum_type();
    +
    +  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
    +  inline int service_size() const;
    +  inline void clear_service();
    +  static const int kServiceFieldNumber = 6;
    +  inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
    +  inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
    +  inline ::google::protobuf::ServiceDescriptorProto* add_service();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
    +      service() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
    +      mutable_service();
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
    +  inline int extension_size() const;
    +  inline void clear_extension();
    +  static const int kExtensionFieldNumber = 7;
    +  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
    +  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
    +  inline ::google::protobuf::FieldDescriptorProto* add_extension();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
    +      extension() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
    +      mutable_extension();
    +
    +  // optional .google.protobuf.FileOptions options = 8;
    +  inline bool has_options() const;
    +  inline void clear_options();
    +  static const int kOptionsFieldNumber = 8;
    +  inline const ::google::protobuf::FileOptions& options() const;
    +  inline ::google::protobuf::FileOptions* mutable_options();
    +  inline ::google::protobuf::FileOptions* release_options();
    +  inline void set_allocated_options(::google::protobuf::FileOptions* options);
    +
    +  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    +  inline bool has_source_code_info() const;
    +  inline void clear_source_code_info();
    +  static const int kSourceCodeInfoFieldNumber = 9;
    +  inline const ::google::protobuf::SourceCodeInfo& source_code_info() const;
    +  inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
    +  inline ::google::protobuf::SourceCodeInfo* release_source_code_info();
    +  inline void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_package();
    +  inline void clear_has_package();
    +  inline void set_has_options();
    +  inline void clear_has_options();
    +  inline void set_has_source_code_info();
    +  inline void clear_has_source_code_info();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::std::string* package_;
    +  ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
    +  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_;
    +  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
    +  ::google::protobuf::FileOptions* options_;
    +  ::google::protobuf::SourceCodeInfo* source_code_info_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static FileDescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message {
    + public:
    +  DescriptorProto_ExtensionRange();
    +  virtual ~DescriptorProto_ExtensionRange();
    +
    +  DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);
    +
    +  inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const DescriptorProto_ExtensionRange& default_instance();
    +
    +  void Swap(DescriptorProto_ExtensionRange* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  DescriptorProto_ExtensionRange* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const DescriptorProto_ExtensionRange& from);
    +  void MergeFrom(const DescriptorProto_ExtensionRange& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional int32 start = 1;
    +  inline bool has_start() const;
    +  inline void clear_start();
    +  static const int kStartFieldNumber = 1;
    +  inline ::google::protobuf::int32 start() const;
    +  inline void set_start(::google::protobuf::int32 value);
    +
    +  // optional int32 end = 2;
    +  inline bool has_end() const;
    +  inline void clear_end();
    +  static const int kEndFieldNumber = 2;
    +  inline ::google::protobuf::int32 end() const;
    +  inline void set_end(::google::protobuf::int32 value);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
    + private:
    +  inline void set_has_start();
    +  inline void clear_has_start();
    +  inline void set_has_end();
    +  inline void clear_has_end();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::int32 start_;
    +  ::google::protobuf::int32 end_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static DescriptorProto_ExtensionRange* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
    + public:
    +  DescriptorProto();
    +  virtual ~DescriptorProto();
    +
    +  DescriptorProto(const DescriptorProto& from);
    +
    +  inline DescriptorProto& operator=(const DescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const DescriptorProto& default_instance();
    +
    +  void Swap(DescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  DescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const DescriptorProto& from);
    +  void MergeFrom(const DescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef DescriptorProto_ExtensionRange ExtensionRange;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // repeated .google.protobuf.FieldDescriptorProto field = 2;
    +  inline int field_size() const;
    +  inline void clear_field();
    +  static const int kFieldFieldNumber = 2;
    +  inline const ::google::protobuf::FieldDescriptorProto& field(int index) const;
    +  inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
    +  inline ::google::protobuf::FieldDescriptorProto* add_field();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
    +      field() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
    +      mutable_field();
    +
    +  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
    +  inline int extension_size() const;
    +  inline void clear_extension();
    +  static const int kExtensionFieldNumber = 6;
    +  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
    +  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
    +  inline ::google::protobuf::FieldDescriptorProto* add_extension();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
    +      extension() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
    +      mutable_extension();
    +
    +  // repeated .google.protobuf.DescriptorProto nested_type = 3;
    +  inline int nested_type_size() const;
    +  inline void clear_nested_type();
    +  static const int kNestedTypeFieldNumber = 3;
    +  inline const ::google::protobuf::DescriptorProto& nested_type(int index) const;
    +  inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index);
    +  inline ::google::protobuf::DescriptorProto* add_nested_type();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
    +      nested_type() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
    +      mutable_nested_type();
    +
    +  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
    +  inline int enum_type_size() const;
    +  inline void clear_enum_type();
    +  static const int kEnumTypeFieldNumber = 4;
    +  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
    +  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
    +  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
    +      enum_type() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
    +      mutable_enum_type();
    +
    +  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
    +  inline int extension_range_size() const;
    +  inline void clear_extension_range();
    +  static const int kExtensionRangeFieldNumber = 5;
    +  inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
    +  inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
    +  inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
    +      extension_range() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
    +      mutable_extension_range();
    +
    +  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
    +  inline int oneof_decl_size() const;
    +  inline void clear_oneof_decl();
    +  static const int kOneofDeclFieldNumber = 8;
    +  inline const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
    +  inline ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
    +  inline ::google::protobuf::OneofDescriptorProto* add_oneof_decl();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
    +      oneof_decl() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
    +      mutable_oneof_decl();
    +
    +  // optional .google.protobuf.MessageOptions options = 7;
    +  inline bool has_options() const;
    +  inline void clear_options();
    +  static const int kOptionsFieldNumber = 7;
    +  inline const ::google::protobuf::MessageOptions& options() const;
    +  inline ::google::protobuf::MessageOptions* mutable_options();
    +  inline ::google::protobuf::MessageOptions* release_options();
    +  inline void set_allocated_options(::google::protobuf::MessageOptions* options);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_options();
    +  inline void clear_has_options();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
    +  ::google::protobuf::MessageOptions* options_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static DescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message {
    + public:
    +  FieldDescriptorProto();
    +  virtual ~FieldDescriptorProto();
    +
    +  FieldDescriptorProto(const FieldDescriptorProto& from);
    +
    +  inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const FieldDescriptorProto& default_instance();
    +
    +  void Swap(FieldDescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  FieldDescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const FieldDescriptorProto& from);
    +  void MergeFrom(const FieldDescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef FieldDescriptorProto_Type Type;
    +  static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
    +  static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
    +  static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
    +  static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
    +  static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
    +  static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
    +  static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
    +  static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
    +  static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
    +  static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
    +  static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
    +  static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
    +  static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
    +  static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
    +  static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
    +  static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
    +  static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
    +  static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
    +  static inline bool Type_IsValid(int value) {
    +    return FieldDescriptorProto_Type_IsValid(value);
    +  }
    +  static const Type Type_MIN =
    +    FieldDescriptorProto_Type_Type_MIN;
    +  static const Type Type_MAX =
    +    FieldDescriptorProto_Type_Type_MAX;
    +  static const int Type_ARRAYSIZE =
    +    FieldDescriptorProto_Type_Type_ARRAYSIZE;
    +  static inline const ::google::protobuf::EnumDescriptor*
    +  Type_descriptor() {
    +    return FieldDescriptorProto_Type_descriptor();
    +  }
    +  static inline const ::std::string& Type_Name(Type value) {
    +    return FieldDescriptorProto_Type_Name(value);
    +  }
    +  static inline bool Type_Parse(const ::std::string& name,
    +      Type* value) {
    +    return FieldDescriptorProto_Type_Parse(name, value);
    +  }
    +
    +  typedef FieldDescriptorProto_Label Label;
    +  static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
    +  static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
    +  static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
    +  static inline bool Label_IsValid(int value) {
    +    return FieldDescriptorProto_Label_IsValid(value);
    +  }
    +  static const Label Label_MIN =
    +    FieldDescriptorProto_Label_Label_MIN;
    +  static const Label Label_MAX =
    +    FieldDescriptorProto_Label_Label_MAX;
    +  static const int Label_ARRAYSIZE =
    +    FieldDescriptorProto_Label_Label_ARRAYSIZE;
    +  static inline const ::google::protobuf::EnumDescriptor*
    +  Label_descriptor() {
    +    return FieldDescriptorProto_Label_descriptor();
    +  }
    +  static inline const ::std::string& Label_Name(Label value) {
    +    return FieldDescriptorProto_Label_Name(value);
    +  }
    +  static inline bool Label_Parse(const ::std::string& name,
    +      Label* value) {
    +    return FieldDescriptorProto_Label_Parse(name, value);
    +  }
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // optional int32 number = 3;
    +  inline bool has_number() const;
    +  inline void clear_number();
    +  static const int kNumberFieldNumber = 3;
    +  inline ::google::protobuf::int32 number() const;
    +  inline void set_number(::google::protobuf::int32 value);
    +
    +  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    +  inline bool has_label() const;
    +  inline void clear_label();
    +  static const int kLabelFieldNumber = 4;
    +  inline ::google::protobuf::FieldDescriptorProto_Label label() const;
    +  inline void set_label(::google::protobuf::FieldDescriptorProto_Label value);
    +
    +  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    +  inline bool has_type() const;
    +  inline void clear_type();
    +  static const int kTypeFieldNumber = 5;
    +  inline ::google::protobuf::FieldDescriptorProto_Type type() const;
    +  inline void set_type(::google::protobuf::FieldDescriptorProto_Type value);
    +
    +  // optional string type_name = 6;
    +  inline bool has_type_name() const;
    +  inline void clear_type_name();
    +  static const int kTypeNameFieldNumber = 6;
    +  inline const ::std::string& type_name() const;
    +  inline void set_type_name(const ::std::string& value);
    +  inline void set_type_name(const char* value);
    +  inline void set_type_name(const char* value, size_t size);
    +  inline ::std::string* mutable_type_name();
    +  inline ::std::string* release_type_name();
    +  inline void set_allocated_type_name(::std::string* type_name);
    +
    +  // optional string extendee = 2;
    +  inline bool has_extendee() const;
    +  inline void clear_extendee();
    +  static const int kExtendeeFieldNumber = 2;
    +  inline const ::std::string& extendee() const;
    +  inline void set_extendee(const ::std::string& value);
    +  inline void set_extendee(const char* value);
    +  inline void set_extendee(const char* value, size_t size);
    +  inline ::std::string* mutable_extendee();
    +  inline ::std::string* release_extendee();
    +  inline void set_allocated_extendee(::std::string* extendee);
    +
    +  // optional string default_value = 7;
    +  inline bool has_default_value() const;
    +  inline void clear_default_value();
    +  static const int kDefaultValueFieldNumber = 7;
    +  inline const ::std::string& default_value() const;
    +  inline void set_default_value(const ::std::string& value);
    +  inline void set_default_value(const char* value);
    +  inline void set_default_value(const char* value, size_t size);
    +  inline ::std::string* mutable_default_value();
    +  inline ::std::string* release_default_value();
    +  inline void set_allocated_default_value(::std::string* default_value);
    +
    +  // optional int32 oneof_index = 9;
    +  inline bool has_oneof_index() const;
    +  inline void clear_oneof_index();
    +  static const int kOneofIndexFieldNumber = 9;
    +  inline ::google::protobuf::int32 oneof_index() const;
    +  inline void set_oneof_index(::google::protobuf::int32 value);
    +
    +  // optional .google.protobuf.FieldOptions options = 8;
    +  inline bool has_options() const;
    +  inline void clear_options();
    +  static const int kOptionsFieldNumber = 8;
    +  inline const ::google::protobuf::FieldOptions& options() const;
    +  inline ::google::protobuf::FieldOptions* mutable_options();
    +  inline ::google::protobuf::FieldOptions* release_options();
    +  inline void set_allocated_options(::google::protobuf::FieldOptions* options);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_number();
    +  inline void clear_has_number();
    +  inline void set_has_label();
    +  inline void clear_has_label();
    +  inline void set_has_type();
    +  inline void clear_has_type();
    +  inline void set_has_type_name();
    +  inline void clear_has_type_name();
    +  inline void set_has_extendee();
    +  inline void clear_has_extendee();
    +  inline void set_has_default_value();
    +  inline void clear_has_default_value();
    +  inline void set_has_oneof_index();
    +  inline void clear_has_oneof_index();
    +  inline void set_has_options();
    +  inline void clear_has_options();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::google::protobuf::int32 number_;
    +  int label_;
    +  ::std::string* type_name_;
    +  ::std::string* extendee_;
    +  int type_;
    +  ::google::protobuf::int32 oneof_index_;
    +  ::std::string* default_value_;
    +  ::google::protobuf::FieldOptions* options_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static FieldDescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message {
    + public:
    +  OneofDescriptorProto();
    +  virtual ~OneofDescriptorProto();
    +
    +  OneofDescriptorProto(const OneofDescriptorProto& from);
    +
    +  inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const OneofDescriptorProto& default_instance();
    +
    +  void Swap(OneofDescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  OneofDescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const OneofDescriptorProto& from);
    +  void MergeFrom(const OneofDescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static OneofDescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message {
    + public:
    +  EnumDescriptorProto();
    +  virtual ~EnumDescriptorProto();
    +
    +  EnumDescriptorProto(const EnumDescriptorProto& from);
    +
    +  inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const EnumDescriptorProto& default_instance();
    +
    +  void Swap(EnumDescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  EnumDescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const EnumDescriptorProto& from);
    +  void MergeFrom(const EnumDescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
    +  inline int value_size() const;
    +  inline void clear_value();
    +  static const int kValueFieldNumber = 2;
    +  inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
    +  inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
    +  inline ::google::protobuf::EnumValueDescriptorProto* add_value();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
    +      value() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
    +      mutable_value();
    +
    +  // optional .google.protobuf.EnumOptions options = 3;
    +  inline bool has_options() const;
    +  inline void clear_options();
    +  static const int kOptionsFieldNumber = 3;
    +  inline const ::google::protobuf::EnumOptions& options() const;
    +  inline ::google::protobuf::EnumOptions* mutable_options();
    +  inline ::google::protobuf::EnumOptions* release_options();
    +  inline void set_allocated_options(::google::protobuf::EnumOptions* options);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_options();
    +  inline void clear_has_options();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
    +  ::google::protobuf::EnumOptions* options_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static EnumDescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message {
    + public:
    +  EnumValueDescriptorProto();
    +  virtual ~EnumValueDescriptorProto();
    +
    +  EnumValueDescriptorProto(const EnumValueDescriptorProto& from);
    +
    +  inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const EnumValueDescriptorProto& default_instance();
    +
    +  void Swap(EnumValueDescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  EnumValueDescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const EnumValueDescriptorProto& from);
    +  void MergeFrom(const EnumValueDescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // optional int32 number = 2;
    +  inline bool has_number() const;
    +  inline void clear_number();
    +  static const int kNumberFieldNumber = 2;
    +  inline ::google::protobuf::int32 number() const;
    +  inline void set_number(::google::protobuf::int32 value);
    +
    +  // optional .google.protobuf.EnumValueOptions options = 3;
    +  inline bool has_options() const;
    +  inline void clear_options();
    +  static const int kOptionsFieldNumber = 3;
    +  inline const ::google::protobuf::EnumValueOptions& options() const;
    +  inline ::google::protobuf::EnumValueOptions* mutable_options();
    +  inline ::google::protobuf::EnumValueOptions* release_options();
    +  inline void set_allocated_options(::google::protobuf::EnumValueOptions* options);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_number();
    +  inline void clear_has_number();
    +  inline void set_has_options();
    +  inline void clear_has_options();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::google::protobuf::EnumValueOptions* options_;
    +  ::google::protobuf::int32 number_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static EnumValueDescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message {
    + public:
    +  ServiceDescriptorProto();
    +  virtual ~ServiceDescriptorProto();
    +
    +  ServiceDescriptorProto(const ServiceDescriptorProto& from);
    +
    +  inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const ServiceDescriptorProto& default_instance();
    +
    +  void Swap(ServiceDescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ServiceDescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const ServiceDescriptorProto& from);
    +  void MergeFrom(const ServiceDescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // repeated .google.protobuf.MethodDescriptorProto method = 2;
    +  inline int method_size() const;
    +  inline void clear_method();
    +  static const int kMethodFieldNumber = 2;
    +  inline const ::google::protobuf::MethodDescriptorProto& method(int index) const;
    +  inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
    +  inline ::google::protobuf::MethodDescriptorProto* add_method();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
    +      method() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
    +      mutable_method();
    +
    +  // optional .google.protobuf.ServiceOptions options = 3;
    +  inline bool has_options() const;
    +  inline void clear_options();
    +  static const int kOptionsFieldNumber = 3;
    +  inline const ::google::protobuf::ServiceOptions& options() const;
    +  inline ::google::protobuf::ServiceOptions* mutable_options();
    +  inline ::google::protobuf::ServiceOptions* release_options();
    +  inline void set_allocated_options(::google::protobuf::ServiceOptions* options);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_options();
    +  inline void clear_has_options();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
    +  ::google::protobuf::ServiceOptions* options_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ServiceDescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message {
    + public:
    +  MethodDescriptorProto();
    +  virtual ~MethodDescriptorProto();
    +
    +  MethodDescriptorProto(const MethodDescriptorProto& from);
    +
    +  inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const MethodDescriptorProto& default_instance();
    +
    +  void Swap(MethodDescriptorProto* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  MethodDescriptorProto* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const MethodDescriptorProto& from);
    +  void MergeFrom(const MethodDescriptorProto& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string name = 1;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 1;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const char* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // optional string input_type = 2;
    +  inline bool has_input_type() const;
    +  inline void clear_input_type();
    +  static const int kInputTypeFieldNumber = 2;
    +  inline const ::std::string& input_type() const;
    +  inline void set_input_type(const ::std::string& value);
    +  inline void set_input_type(const char* value);
    +  inline void set_input_type(const char* value, size_t size);
    +  inline ::std::string* mutable_input_type();
    +  inline ::std::string* release_input_type();
    +  inline void set_allocated_input_type(::std::string* input_type);
    +
    +  // optional string output_type = 3;
    +  inline bool has_output_type() const;
    +  inline void clear_output_type();
    +  static const int kOutputTypeFieldNumber = 3;
    +  inline const ::std::string& output_type() const;
    +  inline void set_output_type(const ::std::string& value);
    +  inline void set_output_type(const char* value);
    +  inline void set_output_type(const char* value, size_t size);
    +  inline ::std::string* mutable_output_type();
    +  inline ::std::string* release_output_type();
    +  inline void set_allocated_output_type(::std::string* output_type);
    +
    +  // optional .google.protobuf.MethodOptions options = 4;
    +  inline bool has_options() const;
    +  inline void clear_options();
    +  static const int kOptionsFieldNumber = 4;
    +  inline const ::google::protobuf::MethodOptions& options() const;
    +  inline ::google::protobuf::MethodOptions* mutable_options();
    +  inline ::google::protobuf::MethodOptions* release_options();
    +  inline void set_allocated_options(::google::protobuf::MethodOptions* options);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
    + private:
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +  inline void set_has_input_type();
    +  inline void clear_has_input_type();
    +  inline void set_has_output_type();
    +  inline void clear_has_output_type();
    +  inline void set_has_options();
    +  inline void clear_has_options();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_;
    +  ::std::string* input_type_;
    +  ::std::string* output_type_;
    +  ::google::protobuf::MethodOptions* options_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static MethodDescriptorProto* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
    + public:
    +  FileOptions();
    +  virtual ~FileOptions();
    +
    +  FileOptions(const FileOptions& from);
    +
    +  inline FileOptions& operator=(const FileOptions& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const FileOptions& default_instance();
    +
    +  void Swap(FileOptions* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  FileOptions* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const FileOptions& from);
    +  void MergeFrom(const FileOptions& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef FileOptions_OptimizeMode OptimizeMode;
    +  static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED;
    +  static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE;
    +  static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME;
    +  static inline bool OptimizeMode_IsValid(int value) {
    +    return FileOptions_OptimizeMode_IsValid(value);
    +  }
    +  static const OptimizeMode OptimizeMode_MIN =
    +    FileOptions_OptimizeMode_OptimizeMode_MIN;
    +  static const OptimizeMode OptimizeMode_MAX =
    +    FileOptions_OptimizeMode_OptimizeMode_MAX;
    +  static const int OptimizeMode_ARRAYSIZE =
    +    FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE;
    +  static inline const ::google::protobuf::EnumDescriptor*
    +  OptimizeMode_descriptor() {
    +    return FileOptions_OptimizeMode_descriptor();
    +  }
    +  static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) {
    +    return FileOptions_OptimizeMode_Name(value);
    +  }
    +  static inline bool OptimizeMode_Parse(const ::std::string& name,
    +      OptimizeMode* value) {
    +    return FileOptions_OptimizeMode_Parse(name, value);
    +  }
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional string java_package = 1;
    +  inline bool has_java_package() const;
    +  inline void clear_java_package();
    +  static const int kJavaPackageFieldNumber = 1;
    +  inline const ::std::string& java_package() const;
    +  inline void set_java_package(const ::std::string& value);
    +  inline void set_java_package(const char* value);
    +  inline void set_java_package(const char* value, size_t size);
    +  inline ::std::string* mutable_java_package();
    +  inline ::std::string* release_java_package();
    +  inline void set_allocated_java_package(::std::string* java_package);
    +
    +  // optional string java_outer_classname = 8;
    +  inline bool has_java_outer_classname() const;
    +  inline void clear_java_outer_classname();
    +  static const int kJavaOuterClassnameFieldNumber = 8;
    +  inline const ::std::string& java_outer_classname() const;
    +  inline void set_java_outer_classname(const ::std::string& value);
    +  inline void set_java_outer_classname(const char* value);
    +  inline void set_java_outer_classname(const char* value, size_t size);
    +  inline ::std::string* mutable_java_outer_classname();
    +  inline ::std::string* release_java_outer_classname();
    +  inline void set_allocated_java_outer_classname(::std::string* java_outer_classname);
    +
    +  // optional bool java_multiple_files = 10 [default = false];
    +  inline bool has_java_multiple_files() const;
    +  inline void clear_java_multiple_files();
    +  static const int kJavaMultipleFilesFieldNumber = 10;
    +  inline bool java_multiple_files() const;
    +  inline void set_java_multiple_files(bool value);
    +
    +  // optional bool java_generate_equals_and_hash = 20 [default = false];
    +  inline bool has_java_generate_equals_and_hash() const;
    +  inline void clear_java_generate_equals_and_hash();
    +  static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
    +  inline bool java_generate_equals_and_hash() const;
    +  inline void set_java_generate_equals_and_hash(bool value);
    +
    +  // optional bool java_string_check_utf8 = 27 [default = false];
    +  inline bool has_java_string_check_utf8() const;
    +  inline void clear_java_string_check_utf8();
    +  static const int kJavaStringCheckUtf8FieldNumber = 27;
    +  inline bool java_string_check_utf8() const;
    +  inline void set_java_string_check_utf8(bool value);
    +
    +  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    +  inline bool has_optimize_for() const;
    +  inline void clear_optimize_for();
    +  static const int kOptimizeForFieldNumber = 9;
    +  inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
    +  inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
    +
    +  // optional string go_package = 11;
    +  inline bool has_go_package() const;
    +  inline void clear_go_package();
    +  static const int kGoPackageFieldNumber = 11;
    +  inline const ::std::string& go_package() const;
    +  inline void set_go_package(const ::std::string& value);
    +  inline void set_go_package(const char* value);
    +  inline void set_go_package(const char* value, size_t size);
    +  inline ::std::string* mutable_go_package();
    +  inline ::std::string* release_go_package();
    +  inline void set_allocated_go_package(::std::string* go_package);
    +
    +  // optional bool cc_generic_services = 16 [default = false];
    +  inline bool has_cc_generic_services() const;
    +  inline void clear_cc_generic_services();
    +  static const int kCcGenericServicesFieldNumber = 16;
    +  inline bool cc_generic_services() const;
    +  inline void set_cc_generic_services(bool value);
    +
    +  // optional bool java_generic_services = 17 [default = false];
    +  inline bool has_java_generic_services() const;
    +  inline void clear_java_generic_services();
    +  static const int kJavaGenericServicesFieldNumber = 17;
    +  inline bool java_generic_services() const;
    +  inline void set_java_generic_services(bool value);
    +
    +  // optional bool py_generic_services = 18 [default = false];
    +  inline bool has_py_generic_services() const;
    +  inline void clear_py_generic_services();
    +  static const int kPyGenericServicesFieldNumber = 18;
    +  inline bool py_generic_services() const;
    +  inline void set_py_generic_services(bool value);
    +
    +  // optional bool deprecated = 23 [default = false];
    +  inline bool has_deprecated() const;
    +  inline void clear_deprecated();
    +  static const int kDeprecatedFieldNumber = 23;
    +  inline bool deprecated() const;
    +  inline void set_deprecated(bool value);
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  inline int uninterpreted_option_size() const;
    +  inline void clear_uninterpreted_option();
    +  static const int kUninterpretedOptionFieldNumber = 999;
    +  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
    +  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
    +  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +      uninterpreted_option() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +      mutable_uninterpreted_option();
    +
    +  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
    +  // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
    + private:
    +  inline void set_has_java_package();
    +  inline void clear_has_java_package();
    +  inline void set_has_java_outer_classname();
    +  inline void clear_has_java_outer_classname();
    +  inline void set_has_java_multiple_files();
    +  inline void clear_has_java_multiple_files();
    +  inline void set_has_java_generate_equals_and_hash();
    +  inline void clear_has_java_generate_equals_and_hash();
    +  inline void set_has_java_string_check_utf8();
    +  inline void clear_has_java_string_check_utf8();
    +  inline void set_has_optimize_for();
    +  inline void clear_has_optimize_for();
    +  inline void set_has_go_package();
    +  inline void clear_has_go_package();
    +  inline void set_has_cc_generic_services();
    +  inline void clear_has_cc_generic_services();
    +  inline void set_has_java_generic_services();
    +  inline void clear_has_java_generic_services();
    +  inline void set_has_py_generic_services();
    +  inline void clear_has_py_generic_services();
    +  inline void set_has_deprecated();
    +  inline void clear_has_deprecated();
    +
    +  ::google::protobuf::internal::ExtensionSet _extensions_;
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* java_package_;
    +  ::std::string* java_outer_classname_;
    +  bool java_multiple_files_;
    +  bool java_generate_equals_and_hash_;
    +  bool java_string_check_utf8_;
    +  bool cc_generic_services_;
    +  int optimize_for_;
    +  ::std::string* go_package_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    +  bool java_generic_services_;
    +  bool py_generic_services_;
    +  bool deprecated_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static FileOptions* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
    + public:
    +  MessageOptions();
    +  virtual ~MessageOptions();
    +
    +  MessageOptions(const MessageOptions& from);
    +
    +  inline MessageOptions& operator=(const MessageOptions& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const MessageOptions& default_instance();
    +
    +  void Swap(MessageOptions* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  MessageOptions* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const MessageOptions& from);
    +  void MergeFrom(const MessageOptions& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bool message_set_wire_format = 1 [default = false];
    +  inline bool has_message_set_wire_format() const;
    +  inline void clear_message_set_wire_format();
    +  static const int kMessageSetWireFormatFieldNumber = 1;
    +  inline bool message_set_wire_format() const;
    +  inline void set_message_set_wire_format(bool value);
    +
    +  // optional bool no_standard_descriptor_accessor = 2 [default = false];
    +  inline bool has_no_standard_descriptor_accessor() const;
    +  inline void clear_no_standard_descriptor_accessor();
    +  static const int kNoStandardDescriptorAccessorFieldNumber = 2;
    +  inline bool no_standard_descriptor_accessor() const;
    +  inline void set_no_standard_descriptor_accessor(bool value);
    +
    +  // optional bool deprecated = 3 [default = false];
    +  inline bool has_deprecated() const;
    +  inline void clear_deprecated();
    +  static const int kDeprecatedFieldNumber = 3;
    +  inline bool deprecated() const;
    +  inline void set_deprecated(bool value);
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  inline int uninterpreted_option_size() const;
    +  inline void clear_uninterpreted_option();
    +  static const int kUninterpretedOptionFieldNumber = 999;
    +  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
    +  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
    +  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +      uninterpreted_option() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +      mutable_uninterpreted_option();
    +
    +  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
    +  // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
    + private:
    +  inline void set_has_message_set_wire_format();
    +  inline void clear_has_message_set_wire_format();
    +  inline void set_has_no_standard_descriptor_accessor();
    +  inline void clear_has_no_standard_descriptor_accessor();
    +  inline void set_has_deprecated();
    +  inline void clear_has_deprecated();
    +
    +  ::google::protobuf::internal::ExtensionSet _extensions_;
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    +  bool message_set_wire_format_;
    +  bool no_standard_descriptor_accessor_;
    +  bool deprecated_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static MessageOptions* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
    + public:
    +  FieldOptions();
    +  virtual ~FieldOptions();
    +
    +  FieldOptions(const FieldOptions& from);
    +
    +  inline FieldOptions& operator=(const FieldOptions& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const FieldOptions& default_instance();
    +
    +  void Swap(FieldOptions* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  FieldOptions* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const FieldOptions& from);
    +  void MergeFrom(const FieldOptions& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef FieldOptions_CType CType;
    +  static const CType STRING = FieldOptions_CType_STRING;
    +  static const CType CORD = FieldOptions_CType_CORD;
    +  static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE;
    +  static inline bool CType_IsValid(int value) {
    +    return FieldOptions_CType_IsValid(value);
    +  }
    +  static const CType CType_MIN =
    +    FieldOptions_CType_CType_MIN;
    +  static const CType CType_MAX =
    +    FieldOptions_CType_CType_MAX;
    +  static const int CType_ARRAYSIZE =
    +    FieldOptions_CType_CType_ARRAYSIZE;
    +  static inline const ::google::protobuf::EnumDescriptor*
    +  CType_descriptor() {
    +    return FieldOptions_CType_descriptor();
    +  }
    +  static inline const ::std::string& CType_Name(CType value) {
    +    return FieldOptions_CType_Name(value);
    +  }
    +  static inline bool CType_Parse(const ::std::string& name,
    +      CType* value) {
    +    return FieldOptions_CType_Parse(name, value);
    +  }
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    +  inline bool has_ctype() const;
    +  inline void clear_ctype();
    +  static const int kCtypeFieldNumber = 1;
    +  inline ::google::protobuf::FieldOptions_CType ctype() const;
    +  inline void set_ctype(::google::protobuf::FieldOptions_CType value);
    +
    +  // optional bool packed = 2;
    +  inline bool has_packed() const;
    +  inline void clear_packed();
    +  static const int kPackedFieldNumber = 2;
    +  inline bool packed() const;
    +  inline void set_packed(bool value);
    +
    +  // optional bool lazy = 5 [default = false];
    +  inline bool has_lazy() const;
    +  inline void clear_lazy();
    +  static const int kLazyFieldNumber = 5;
    +  inline bool lazy() const;
    +  inline void set_lazy(bool value);
    +
    +  // optional bool deprecated = 3 [default = false];
    +  inline bool has_deprecated() const;
    +  inline void clear_deprecated();
    +  static const int kDeprecatedFieldNumber = 3;
    +  inline bool deprecated() const;
    +  inline void set_deprecated(bool value);
    +
    +  // optional string experimental_map_key = 9;
    +  inline bool has_experimental_map_key() const;
    +  inline void clear_experimental_map_key();
    +  static const int kExperimentalMapKeyFieldNumber = 9;
    +  inline const ::std::string& experimental_map_key() const;
    +  inline void set_experimental_map_key(const ::std::string& value);
    +  inline void set_experimental_map_key(const char* value);
    +  inline void set_experimental_map_key(const char* value, size_t size);
    +  inline ::std::string* mutable_experimental_map_key();
    +  inline ::std::string* release_experimental_map_key();
    +  inline void set_allocated_experimental_map_key(::std::string* experimental_map_key);
    +
    +  // optional bool weak = 10 [default = false];
    +  inline bool has_weak() const;
    +  inline void clear_weak();
    +  static const int kWeakFieldNumber = 10;
    +  inline bool weak() const;
    +  inline void set_weak(bool value);
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  inline int uninterpreted_option_size() const;
    +  inline void clear_uninterpreted_option();
    +  static const int kUninterpretedOptionFieldNumber = 999;
    +  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
    +  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
    +  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +      uninterpreted_option() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +      mutable_uninterpreted_option();
    +
    +  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
    +  // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
    + private:
    +  inline void set_has_ctype();
    +  inline void clear_has_ctype();
    +  inline void set_has_packed();
    +  inline void clear_has_packed();
    +  inline void set_has_lazy();
    +  inline void clear_has_lazy();
    +  inline void set_has_deprecated();
    +  inline void clear_has_deprecated();
    +  inline void set_has_experimental_map_key();
    +  inline void clear_has_experimental_map_key();
    +  inline void set_has_weak();
    +  inline void clear_has_weak();
    +
    +  ::google::protobuf::internal::ExtensionSet _extensions_;
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  int ctype_;
    +  bool packed_;
    +  bool lazy_;
    +  bool deprecated_;
    +  bool weak_;
    +  ::std::string* experimental_map_key_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static FieldOptions* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
    + public:
    +  EnumOptions();
    +  virtual ~EnumOptions();
    +
    +  EnumOptions(const EnumOptions& from);
    +
    +  inline EnumOptions& operator=(const EnumOptions& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const EnumOptions& default_instance();
    +
    +  void Swap(EnumOptions* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  EnumOptions* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const EnumOptions& from);
    +  void MergeFrom(const EnumOptions& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bool allow_alias = 2;
    +  inline bool has_allow_alias() const;
    +  inline void clear_allow_alias();
    +  static const int kAllowAliasFieldNumber = 2;
    +  inline bool allow_alias() const;
    +  inline void set_allow_alias(bool value);
    +
    +  // optional bool deprecated = 3 [default = false];
    +  inline bool has_deprecated() const;
    +  inline void clear_deprecated();
    +  static const int kDeprecatedFieldNumber = 3;
    +  inline bool deprecated() const;
    +  inline void set_deprecated(bool value);
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  inline int uninterpreted_option_size() const;
    +  inline void clear_uninterpreted_option();
    +  static const int kUninterpretedOptionFieldNumber = 999;
    +  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
    +  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
    +  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +      uninterpreted_option() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +      mutable_uninterpreted_option();
    +
    +  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
    +  // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
    + private:
    +  inline void set_has_allow_alias();
    +  inline void clear_has_allow_alias();
    +  inline void set_has_deprecated();
    +  inline void clear_has_deprecated();
    +
    +  ::google::protobuf::internal::ExtensionSet _extensions_;
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    +  bool allow_alias_;
    +  bool deprecated_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static EnumOptions* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
    + public:
    +  EnumValueOptions();
    +  virtual ~EnumValueOptions();
    +
    +  EnumValueOptions(const EnumValueOptions& from);
    +
    +  inline EnumValueOptions& operator=(const EnumValueOptions& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const EnumValueOptions& default_instance();
    +
    +  void Swap(EnumValueOptions* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  EnumValueOptions* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const EnumValueOptions& from);
    +  void MergeFrom(const EnumValueOptions& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bool deprecated = 1 [default = false];
    +  inline bool has_deprecated() const;
    +  inline void clear_deprecated();
    +  static const int kDeprecatedFieldNumber = 1;
    +  inline bool deprecated() const;
    +  inline void set_deprecated(bool value);
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  inline int uninterpreted_option_size() const;
    +  inline void clear_uninterpreted_option();
    +  static const int kUninterpretedOptionFieldNumber = 999;
    +  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
    +  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
    +  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +      uninterpreted_option() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +      mutable_uninterpreted_option();
    +
    +  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
    +  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
    + private:
    +  inline void set_has_deprecated();
    +  inline void clear_has_deprecated();
    +
    +  ::google::protobuf::internal::ExtensionSet _extensions_;
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    +  bool deprecated_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static EnumValueOptions* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
    + public:
    +  ServiceOptions();
    +  virtual ~ServiceOptions();
    +
    +  ServiceOptions(const ServiceOptions& from);
    +
    +  inline ServiceOptions& operator=(const ServiceOptions& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const ServiceOptions& default_instance();
    +
    +  void Swap(ServiceOptions* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  ServiceOptions* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const ServiceOptions& from);
    +  void MergeFrom(const ServiceOptions& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bool deprecated = 33 [default = false];
    +  inline bool has_deprecated() const;
    +  inline void clear_deprecated();
    +  static const int kDeprecatedFieldNumber = 33;
    +  inline bool deprecated() const;
    +  inline void set_deprecated(bool value);
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  inline int uninterpreted_option_size() const;
    +  inline void clear_uninterpreted_option();
    +  static const int kUninterpretedOptionFieldNumber = 999;
    +  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
    +  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
    +  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +      uninterpreted_option() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +      mutable_uninterpreted_option();
    +
    +  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
    +  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
    + private:
    +  inline void set_has_deprecated();
    +  inline void clear_has_deprecated();
    +
    +  ::google::protobuf::internal::ExtensionSet _extensions_;
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    +  bool deprecated_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static ServiceOptions* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
    + public:
    +  MethodOptions();
    +  virtual ~MethodOptions();
    +
    +  MethodOptions(const MethodOptions& from);
    +
    +  inline MethodOptions& operator=(const MethodOptions& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const MethodOptions& default_instance();
    +
    +  void Swap(MethodOptions* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  MethodOptions* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const MethodOptions& from);
    +  void MergeFrom(const MethodOptions& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional bool deprecated = 33 [default = false];
    +  inline bool has_deprecated() const;
    +  inline void clear_deprecated();
    +  static const int kDeprecatedFieldNumber = 33;
    +  inline bool deprecated() const;
    +  inline void set_deprecated(bool value);
    +
    +  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +  inline int uninterpreted_option_size() const;
    +  inline void clear_uninterpreted_option();
    +  static const int kUninterpretedOptionFieldNumber = 999;
    +  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
    +  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
    +  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +      uninterpreted_option() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +      mutable_uninterpreted_option();
    +
    +  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
    +  // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
    + private:
    +  inline void set_has_deprecated();
    +  inline void clear_has_deprecated();
    +
    +  ::google::protobuf::internal::ExtensionSet _extensions_;
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    +  bool deprecated_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static MethodOptions* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message {
    + public:
    +  UninterpretedOption_NamePart();
    +  virtual ~UninterpretedOption_NamePart();
    +
    +  UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);
    +
    +  inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const UninterpretedOption_NamePart& default_instance();
    +
    +  void Swap(UninterpretedOption_NamePart* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  UninterpretedOption_NamePart* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const UninterpretedOption_NamePart& from);
    +  void MergeFrom(const UninterpretedOption_NamePart& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // required string name_part = 1;
    +  inline bool has_name_part() const;
    +  inline void clear_name_part();
    +  static const int kNamePartFieldNumber = 1;
    +  inline const ::std::string& name_part() const;
    +  inline void set_name_part(const ::std::string& value);
    +  inline void set_name_part(const char* value);
    +  inline void set_name_part(const char* value, size_t size);
    +  inline ::std::string* mutable_name_part();
    +  inline ::std::string* release_name_part();
    +  inline void set_allocated_name_part(::std::string* name_part);
    +
    +  // required bool is_extension = 2;
    +  inline bool has_is_extension() const;
    +  inline void clear_is_extension();
    +  static const int kIsExtensionFieldNumber = 2;
    +  inline bool is_extension() const;
    +  inline void set_is_extension(bool value);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
    + private:
    +  inline void set_has_name_part();
    +  inline void clear_has_name_part();
    +  inline void set_has_is_extension();
    +  inline void clear_has_is_extension();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::std::string* name_part_;
    +  bool is_extension_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static UninterpretedOption_NamePart* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message {
    + public:
    +  UninterpretedOption();
    +  virtual ~UninterpretedOption();
    +
    +  UninterpretedOption(const UninterpretedOption& from);
    +
    +  inline UninterpretedOption& operator=(const UninterpretedOption& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const UninterpretedOption& default_instance();
    +
    +  void Swap(UninterpretedOption* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  UninterpretedOption* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const UninterpretedOption& from);
    +  void MergeFrom(const UninterpretedOption& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef UninterpretedOption_NamePart NamePart;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
    +  inline int name_size() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 2;
    +  inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
    +  inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
    +  inline ::google::protobuf::UninterpretedOption_NamePart* add_name();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
    +      name() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
    +      mutable_name();
    +
    +  // optional string identifier_value = 3;
    +  inline bool has_identifier_value() const;
    +  inline void clear_identifier_value();
    +  static const int kIdentifierValueFieldNumber = 3;
    +  inline const ::std::string& identifier_value() const;
    +  inline void set_identifier_value(const ::std::string& value);
    +  inline void set_identifier_value(const char* value);
    +  inline void set_identifier_value(const char* value, size_t size);
    +  inline ::std::string* mutable_identifier_value();
    +  inline ::std::string* release_identifier_value();
    +  inline void set_allocated_identifier_value(::std::string* identifier_value);
    +
    +  // optional uint64 positive_int_value = 4;
    +  inline bool has_positive_int_value() const;
    +  inline void clear_positive_int_value();
    +  static const int kPositiveIntValueFieldNumber = 4;
    +  inline ::google::protobuf::uint64 positive_int_value() const;
    +  inline void set_positive_int_value(::google::protobuf::uint64 value);
    +
    +  // optional int64 negative_int_value = 5;
    +  inline bool has_negative_int_value() const;
    +  inline void clear_negative_int_value();
    +  static const int kNegativeIntValueFieldNumber = 5;
    +  inline ::google::protobuf::int64 negative_int_value() const;
    +  inline void set_negative_int_value(::google::protobuf::int64 value);
    +
    +  // optional double double_value = 6;
    +  inline bool has_double_value() const;
    +  inline void clear_double_value();
    +  static const int kDoubleValueFieldNumber = 6;
    +  inline double double_value() const;
    +  inline void set_double_value(double value);
    +
    +  // optional bytes string_value = 7;
    +  inline bool has_string_value() const;
    +  inline void clear_string_value();
    +  static const int kStringValueFieldNumber = 7;
    +  inline const ::std::string& string_value() const;
    +  inline void set_string_value(const ::std::string& value);
    +  inline void set_string_value(const char* value);
    +  inline void set_string_value(const void* value, size_t size);
    +  inline ::std::string* mutable_string_value();
    +  inline ::std::string* release_string_value();
    +  inline void set_allocated_string_value(::std::string* string_value);
    +
    +  // optional string aggregate_value = 8;
    +  inline bool has_aggregate_value() const;
    +  inline void clear_aggregate_value();
    +  static const int kAggregateValueFieldNumber = 8;
    +  inline const ::std::string& aggregate_value() const;
    +  inline void set_aggregate_value(const ::std::string& value);
    +  inline void set_aggregate_value(const char* value);
    +  inline void set_aggregate_value(const char* value, size_t size);
    +  inline ::std::string* mutable_aggregate_value();
    +  inline ::std::string* release_aggregate_value();
    +  inline void set_allocated_aggregate_value(::std::string* aggregate_value);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
    + private:
    +  inline void set_has_identifier_value();
    +  inline void clear_has_identifier_value();
    +  inline void set_has_positive_int_value();
    +  inline void clear_has_positive_int_value();
    +  inline void set_has_negative_int_value();
    +  inline void clear_has_negative_int_value();
    +  inline void set_has_double_value();
    +  inline void clear_has_double_value();
    +  inline void set_has_string_value();
    +  inline void clear_has_string_value();
    +  inline void set_has_aggregate_value();
    +  inline void clear_has_aggregate_value();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
    +  ::std::string* identifier_value_;
    +  ::google::protobuf::uint64 positive_int_value_;
    +  ::google::protobuf::int64 negative_int_value_;
    +  double double_value_;
    +  ::std::string* string_value_;
    +  ::std::string* aggregate_value_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static UninterpretedOption* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message {
    + public:
    +  SourceCodeInfo_Location();
    +  virtual ~SourceCodeInfo_Location();
    +
    +  SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
    +
    +  inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const SourceCodeInfo_Location& default_instance();
    +
    +  void Swap(SourceCodeInfo_Location* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  SourceCodeInfo_Location* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const SourceCodeInfo_Location& from);
    +  void MergeFrom(const SourceCodeInfo_Location& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // repeated int32 path = 1 [packed = true];
    +  inline int path_size() const;
    +  inline void clear_path();
    +  static const int kPathFieldNumber = 1;
    +  inline ::google::protobuf::int32 path(int index) const;
    +  inline void set_path(int index, ::google::protobuf::int32 value);
    +  inline void add_path(::google::protobuf::int32 value);
    +  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +      path() const;
    +  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +      mutable_path();
    +
    +  // repeated int32 span = 2 [packed = true];
    +  inline int span_size() const;
    +  inline void clear_span();
    +  static const int kSpanFieldNumber = 2;
    +  inline ::google::protobuf::int32 span(int index) const;
    +  inline void set_span(int index, ::google::protobuf::int32 value);
    +  inline void add_span(::google::protobuf::int32 value);
    +  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +      span() const;
    +  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +      mutable_span();
    +
    +  // optional string leading_comments = 3;
    +  inline bool has_leading_comments() const;
    +  inline void clear_leading_comments();
    +  static const int kLeadingCommentsFieldNumber = 3;
    +  inline const ::std::string& leading_comments() const;
    +  inline void set_leading_comments(const ::std::string& value);
    +  inline void set_leading_comments(const char* value);
    +  inline void set_leading_comments(const char* value, size_t size);
    +  inline ::std::string* mutable_leading_comments();
    +  inline ::std::string* release_leading_comments();
    +  inline void set_allocated_leading_comments(::std::string* leading_comments);
    +
    +  // optional string trailing_comments = 4;
    +  inline bool has_trailing_comments() const;
    +  inline void clear_trailing_comments();
    +  static const int kTrailingCommentsFieldNumber = 4;
    +  inline const ::std::string& trailing_comments() const;
    +  inline void set_trailing_comments(const ::std::string& value);
    +  inline void set_trailing_comments(const char* value);
    +  inline void set_trailing_comments(const char* value, size_t size);
    +  inline ::std::string* mutable_trailing_comments();
    +  inline ::std::string* release_trailing_comments();
    +  inline void set_allocated_trailing_comments(::std::string* trailing_comments);
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
    + private:
    +  inline void set_has_leading_comments();
    +  inline void clear_has_leading_comments();
    +  inline void set_has_trailing_comments();
    +  inline void clear_has_trailing_comments();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
    +  mutable int _path_cached_byte_size_;
    +  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
    +  mutable int _span_cached_byte_size_;
    +  ::std::string* leading_comments_;
    +  ::std::string* trailing_comments_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static SourceCodeInfo_Location* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
    + public:
    +  SourceCodeInfo();
    +  virtual ~SourceCodeInfo();
    +
    +  SourceCodeInfo(const SourceCodeInfo& from);
    +
    +  inline SourceCodeInfo& operator=(const SourceCodeInfo& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const SourceCodeInfo& default_instance();
    +
    +  void Swap(SourceCodeInfo* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  SourceCodeInfo* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const SourceCodeInfo& from);
    +  void MergeFrom(const SourceCodeInfo& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  typedef SourceCodeInfo_Location Location;
    +
    +  // accessors -------------------------------------------------------
    +
    +  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
    +  inline int location_size() const;
    +  inline void clear_location();
    +  static const int kLocationFieldNumber = 1;
    +  inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
    +  inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
    +  inline ::google::protobuf::SourceCodeInfo_Location* add_location();
    +  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
    +      location() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
    +      mutable_location();
    +
    +  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
    + private:
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
    +  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
    +  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static SourceCodeInfo* default_instance_;
    +};
    +// ===================================================================
    +
    +
    +// ===================================================================
    +
    +// FileDescriptorSet
    +
    +// repeated .google.protobuf.FileDescriptorProto file = 1;
    +inline int FileDescriptorSet::file_size() const {
    +  return file_.size();
    +}
    +inline void FileDescriptorSet::clear_file() {
    +  file_.Clear();
    +}
    +inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
    +  return file_.Get(index);
    +}
    +inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
    +  return file_.Mutable(index);
    +}
    +inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
    +  return file_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
    +FileDescriptorSet::file() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
    +  return file_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
    +FileDescriptorSet::mutable_file() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
    +  return &file_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// FileDescriptorProto
    +
    +// optional string name = 1;
    +inline bool FileDescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void FileDescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void FileDescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void FileDescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& FileDescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name)
    +  return *name_;
    +}
    +inline void FileDescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
    +}
    +inline void FileDescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
    +}
    +inline void FileDescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name)
    +}
    +inline ::std::string* FileDescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* FileDescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FileDescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name)
    +}
    +
    +// optional string package = 2;
    +inline bool FileDescriptorProto::has_package() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void FileDescriptorProto::set_has_package() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void FileDescriptorProto::clear_has_package() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void FileDescriptorProto::clear_package() {
    +  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    package_->clear();
    +  }
    +  clear_has_package();
    +}
    +inline const ::std::string& FileDescriptorProto::package() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package)
    +  return *package_;
    +}
    +inline void FileDescriptorProto::set_package(const ::std::string& value) {
    +  set_has_package();
    +  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    package_ = new ::std::string;
    +  }
    +  package_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
    +}
    +inline void FileDescriptorProto::set_package(const char* value) {
    +  set_has_package();
    +  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    package_ = new ::std::string;
    +  }
    +  package_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
    +}
    +inline void FileDescriptorProto::set_package(const char* value, size_t size) {
    +  set_has_package();
    +  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    package_ = new ::std::string;
    +  }
    +  package_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package)
    +}
    +inline ::std::string* FileDescriptorProto::mutable_package() {
    +  set_has_package();
    +  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    package_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
    +  return package_;
    +}
    +inline ::std::string* FileDescriptorProto::release_package() {
    +  clear_has_package();
    +  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = package_;
    +    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FileDescriptorProto::set_allocated_package(::std::string* package) {
    +  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete package_;
    +  }
    +  if (package) {
    +    set_has_package();
    +    package_ = package;
    +  } else {
    +    clear_has_package();
    +    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package)
    +}
    +
    +// repeated string dependency = 3;
    +inline int FileDescriptorProto::dependency_size() const {
    +  return dependency_.size();
    +}
    +inline void FileDescriptorProto::clear_dependency() {
    +  dependency_.Clear();
    +}
    +inline const ::std::string& FileDescriptorProto::dependency(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
    +  return dependency_.Get(index);
    +}
    +inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
    +  return dependency_.Mutable(index);
    +}
    +inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
    +  dependency_.Mutable(index)->assign(value);
    +}
    +inline void FileDescriptorProto::set_dependency(int index, const char* value) {
    +  dependency_.Mutable(index)->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
    +}
    +inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
    +  dependency_.Mutable(index)->assign(
    +    reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
    +}
    +inline ::std::string* FileDescriptorProto::add_dependency() {
    +  return dependency_.Add();
    +}
    +inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
    +  dependency_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
    +}
    +inline void FileDescriptorProto::add_dependency(const char* value) {
    +  dependency_.Add()->assign(value);
    +  // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
    +}
    +inline void FileDescriptorProto::add_dependency(const char* value, size_t size) {
    +  dependency_.Add()->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
    +FileDescriptorProto::dependency() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
    +  return dependency_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::std::string>*
    +FileDescriptorProto::mutable_dependency() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
    +  return &dependency_;
    +}
    +
    +// repeated int32 public_dependency = 10;
    +inline int FileDescriptorProto::public_dependency_size() const {
    +  return public_dependency_.size();
    +}
    +inline void FileDescriptorProto::clear_public_dependency() {
    +  public_dependency_.Clear();
    +}
    +inline ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.public_dependency)
    +  return public_dependency_.Get(index);
    +}
    +inline void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) {
    +  public_dependency_.Set(index, value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency)
    +}
    +inline void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) {
    +  public_dependency_.Add(value);
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency)
    +}
    +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +FileDescriptorProto::public_dependency() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency)
    +  return public_dependency_;
    +}
    +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +FileDescriptorProto::mutable_public_dependency() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency)
    +  return &public_dependency_;
    +}
    +
    +// repeated int32 weak_dependency = 11;
    +inline int FileDescriptorProto::weak_dependency_size() const {
    +  return weak_dependency_.size();
    +}
    +inline void FileDescriptorProto::clear_weak_dependency() {
    +  weak_dependency_.Clear();
    +}
    +inline ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.weak_dependency)
    +  return weak_dependency_.Get(index);
    +}
    +inline void FileDescriptorProto::set_weak_dependency(int index, ::google::protobuf::int32 value) {
    +  weak_dependency_.Set(index, value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency)
    +}
    +inline void FileDescriptorProto::add_weak_dependency(::google::protobuf::int32 value) {
    +  weak_dependency_.Add(value);
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency)
    +}
    +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +FileDescriptorProto::weak_dependency() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency)
    +  return weak_dependency_;
    +}
    +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +FileDescriptorProto::mutable_weak_dependency() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency)
    +  return &weak_dependency_;
    +}
    +
    +// repeated .google.protobuf.DescriptorProto message_type = 4;
    +inline int FileDescriptorProto::message_type_size() const {
    +  return message_type_.size();
    +}
    +inline void FileDescriptorProto::clear_message_type() {
    +  message_type_.Clear();
    +}
    +inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type)
    +  return message_type_.Get(index);
    +}
    +inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type)
    +  return message_type_.Mutable(index);
    +}
    +inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
    +  return message_type_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
    +FileDescriptorProto::message_type() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
    +  return message_type_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
    +FileDescriptorProto::mutable_message_type() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
    +  return &message_type_;
    +}
    +
    +// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
    +inline int FileDescriptorProto::enum_type_size() const {
    +  return enum_type_.size();
    +}
    +inline void FileDescriptorProto::clear_enum_type() {
    +  enum_type_.Clear();
    +}
    +inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type)
    +  return enum_type_.Get(index);
    +}
    +inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type)
    +  return enum_type_.Mutable(index);
    +}
    +inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
    +  return enum_type_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
    +FileDescriptorProto::enum_type() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
    +  return enum_type_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
    +FileDescriptorProto::mutable_enum_type() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
    +  return &enum_type_;
    +}
    +
    +// repeated .google.protobuf.ServiceDescriptorProto service = 6;
    +inline int FileDescriptorProto::service_size() const {
    +  return service_.size();
    +}
    +inline void FileDescriptorProto::clear_service() {
    +  service_.Clear();
    +}
    +inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service)
    +  return service_.Get(index);
    +}
    +inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
    +  return service_.Mutable(index);
    +}
    +inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
    +  return service_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
    +FileDescriptorProto::service() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
    +  return service_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
    +FileDescriptorProto::mutable_service() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
    +  return &service_;
    +}
    +
    +// repeated .google.protobuf.FieldDescriptorProto extension = 7;
    +inline int FileDescriptorProto::extension_size() const {
    +  return extension_.size();
    +}
    +inline void FileDescriptorProto::clear_extension() {
    +  extension_.Clear();
    +}
    +inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension)
    +  return extension_.Get(index);
    +}
    +inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
    +  return extension_.Mutable(index);
    +}
    +inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
    +  return extension_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
    +FileDescriptorProto::extension() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
    +  return extension_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
    +FileDescriptorProto::mutable_extension() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
    +  return &extension_;
    +}
    +
    +// optional .google.protobuf.FileOptions options = 8;
    +inline bool FileDescriptorProto::has_options() const {
    +  return (_has_bits_[0] & 0x00000200u) != 0;
    +}
    +inline void FileDescriptorProto::set_has_options() {
    +  _has_bits_[0] |= 0x00000200u;
    +}
    +inline void FileDescriptorProto::clear_has_options() {
    +  _has_bits_[0] &= ~0x00000200u;
    +}
    +inline void FileDescriptorProto::clear_options() {
    +  if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
    +  clear_has_options();
    +}
    +inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
    +  return options_ != NULL ? *options_ : *default_instance_->options_;
    +}
    +inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
    +  set_has_options();
    +  if (options_ == NULL) options_ = new ::google::protobuf::FileOptions;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
    +  return options_;
    +}
    +inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
    +  clear_has_options();
    +  ::google::protobuf::FileOptions* temp = options_;
    +  options_ = NULL;
    +  return temp;
    +}
    +inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
    +  delete options_;
    +  options_ = options;
    +  if (options) {
    +    set_has_options();
    +  } else {
    +    clear_has_options();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
    +}
    +
    +// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    +inline bool FileDescriptorProto::has_source_code_info() const {
    +  return (_has_bits_[0] & 0x00000400u) != 0;
    +}
    +inline void FileDescriptorProto::set_has_source_code_info() {
    +  _has_bits_[0] |= 0x00000400u;
    +}
    +inline void FileDescriptorProto::clear_has_source_code_info() {
    +  _has_bits_[0] &= ~0x00000400u;
    +}
    +inline void FileDescriptorProto::clear_source_code_info() {
    +  if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
    +  clear_has_source_code_info();
    +}
    +inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
    +  return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
    +}
    +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
    +  set_has_source_code_info();
    +  if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
    +  return source_code_info_;
    +}
    +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
    +  clear_has_source_code_info();
    +  ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
    +  source_code_info_ = NULL;
    +  return temp;
    +}
    +inline void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
    +  delete source_code_info_;
    +  source_code_info_ = source_code_info;
    +  if (source_code_info) {
    +    set_has_source_code_info();
    +  } else {
    +    clear_has_source_code_info();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// DescriptorProto_ExtensionRange
    +
    +// optional int32 start = 1;
    +inline bool DescriptorProto_ExtensionRange::has_start() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void DescriptorProto_ExtensionRange::set_has_start() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void DescriptorProto_ExtensionRange::clear_has_start() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void DescriptorProto_ExtensionRange::clear_start() {
    +  start_ = 0;
    +  clear_has_start();
    +}
    +inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
    +  return start_;
    +}
    +inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
    +  set_has_start();
    +  start_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
    +}
    +
    +// optional int32 end = 2;
    +inline bool DescriptorProto_ExtensionRange::has_end() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void DescriptorProto_ExtensionRange::set_has_end() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void DescriptorProto_ExtensionRange::clear_has_end() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void DescriptorProto_ExtensionRange::clear_end() {
    +  end_ = 0;
    +  clear_has_end();
    +}
    +inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end)
    +  return end_;
    +}
    +inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
    +  set_has_end();
    +  end_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// DescriptorProto
    +
    +// optional string name = 1;
    +inline bool DescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void DescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void DescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void DescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& DescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name)
    +  return *name_;
    +}
    +inline void DescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
    +}
    +inline void DescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
    +}
    +inline void DescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name)
    +}
    +inline ::std::string* DescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* DescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void DescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name)
    +}
    +
    +// repeated .google.protobuf.FieldDescriptorProto field = 2;
    +inline int DescriptorProto::field_size() const {
    +  return field_.size();
    +}
    +inline void DescriptorProto::clear_field() {
    +  field_.Clear();
    +}
    +inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
    +  return field_.Get(index);
    +}
    +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
    +  return field_.Mutable(index);
    +}
    +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
    +  return field_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
    +DescriptorProto::field() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
    +  return field_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
    +DescriptorProto::mutable_field() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
    +  return &field_;
    +}
    +
    +// repeated .google.protobuf.FieldDescriptorProto extension = 6;
    +inline int DescriptorProto::extension_size() const {
    +  return extension_.size();
    +}
    +inline void DescriptorProto::clear_extension() {
    +  extension_.Clear();
    +}
    +inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension)
    +  return extension_.Get(index);
    +}
    +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
    +  return extension_.Mutable(index);
    +}
    +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
    +  return extension_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
    +DescriptorProto::extension() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
    +  return extension_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
    +DescriptorProto::mutable_extension() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
    +  return &extension_;
    +}
    +
    +// repeated .google.protobuf.DescriptorProto nested_type = 3;
    +inline int DescriptorProto::nested_type_size() const {
    +  return nested_type_.size();
    +}
    +inline void DescriptorProto::clear_nested_type() {
    +  nested_type_.Clear();
    +}
    +inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type)
    +  return nested_type_.Get(index);
    +}
    +inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type)
    +  return nested_type_.Mutable(index);
    +}
    +inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
    +  return nested_type_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
    +DescriptorProto::nested_type() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
    +  return nested_type_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
    +DescriptorProto::mutable_nested_type() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
    +  return &nested_type_;
    +}
    +
    +// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
    +inline int DescriptorProto::enum_type_size() const {
    +  return enum_type_.size();
    +}
    +inline void DescriptorProto::clear_enum_type() {
    +  enum_type_.Clear();
    +}
    +inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type)
    +  return enum_type_.Get(index);
    +}
    +inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type)
    +  return enum_type_.Mutable(index);
    +}
    +inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
    +  return enum_type_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
    +DescriptorProto::enum_type() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
    +  return enum_type_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
    +DescriptorProto::mutable_enum_type() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
    +  return &enum_type_;
    +}
    +
    +// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
    +inline int DescriptorProto::extension_range_size() const {
    +  return extension_range_.size();
    +}
    +inline void DescriptorProto::clear_extension_range() {
    +  extension_range_.Clear();
    +}
    +inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range)
    +  return extension_range_.Get(index);
    +}
    +inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range)
    +  return extension_range_.Mutable(index);
    +}
    +inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
    +  return extension_range_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
    +DescriptorProto::extension_range() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
    +  return extension_range_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
    +DescriptorProto::mutable_extension_range() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
    +  return &extension_range_;
    +}
    +
    +// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
    +inline int DescriptorProto::oneof_decl_size() const {
    +  return oneof_decl_.size();
    +}
    +inline void DescriptorProto::clear_oneof_decl() {
    +  oneof_decl_.Clear();
    +}
    +inline const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
    +  return oneof_decl_.Get(index);
    +}
    +inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
    +  return oneof_decl_.Mutable(index);
    +}
    +inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
    +  return oneof_decl_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
    +DescriptorProto::oneof_decl() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
    +  return oneof_decl_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
    +DescriptorProto::mutable_oneof_decl() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
    +  return &oneof_decl_;
    +}
    +
    +// optional .google.protobuf.MessageOptions options = 7;
    +inline bool DescriptorProto::has_options() const {
    +  return (_has_bits_[0] & 0x00000080u) != 0;
    +}
    +inline void DescriptorProto::set_has_options() {
    +  _has_bits_[0] |= 0x00000080u;
    +}
    +inline void DescriptorProto::clear_has_options() {
    +  _has_bits_[0] &= ~0x00000080u;
    +}
    +inline void DescriptorProto::clear_options() {
    +  if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
    +  clear_has_options();
    +}
    +inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
    +  return options_ != NULL ? *options_ : *default_instance_->options_;
    +}
    +inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
    +  set_has_options();
    +  if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
    +  return options_;
    +}
    +inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
    +  clear_has_options();
    +  ::google::protobuf::MessageOptions* temp = options_;
    +  options_ = NULL;
    +  return temp;
    +}
    +inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
    +  delete options_;
    +  options_ = options;
    +  if (options) {
    +    set_has_options();
    +  } else {
    +    clear_has_options();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// FieldDescriptorProto
    +
    +// optional string name = 1;
    +inline bool FieldDescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void FieldDescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void FieldDescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& FieldDescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name)
    +  return *name_;
    +}
    +inline void FieldDescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
    +}
    +inline void FieldDescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
    +}
    +inline void FieldDescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name)
    +}
    +inline ::std::string* FieldDescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* FieldDescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FieldDescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name)
    +}
    +
    +// optional int32 number = 3;
    +inline bool FieldDescriptorProto::has_number() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_number() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void FieldDescriptorProto::clear_has_number() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void FieldDescriptorProto::clear_number() {
    +  number_ = 0;
    +  clear_has_number();
    +}
    +inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
    +  return number_;
    +}
    +inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
    +  set_has_number();
    +  number_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
    +}
    +
    +// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    +inline bool FieldDescriptorProto::has_label() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_label() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void FieldDescriptorProto::clear_has_label() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void FieldDescriptorProto::clear_label() {
    +  label_ = 1;
    +  clear_has_label();
    +}
    +inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
    +  return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
    +}
    +inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
    +  assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
    +  set_has_label();
    +  label_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
    +}
    +
    +// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    +inline bool FieldDescriptorProto::has_type() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_type() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void FieldDescriptorProto::clear_has_type() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void FieldDescriptorProto::clear_type() {
    +  type_ = 1;
    +  clear_has_type();
    +}
    +inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
    +  return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
    +}
    +inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
    +  assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
    +  set_has_type();
    +  type_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
    +}
    +
    +// optional string type_name = 6;
    +inline bool FieldDescriptorProto::has_type_name() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_type_name() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void FieldDescriptorProto::clear_has_type_name() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void FieldDescriptorProto::clear_type_name() {
    +  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    type_name_->clear();
    +  }
    +  clear_has_type_name();
    +}
    +inline const ::std::string& FieldDescriptorProto::type_name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name)
    +  return *type_name_;
    +}
    +inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
    +  set_has_type_name();
    +  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    type_name_ = new ::std::string;
    +  }
    +  type_name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
    +}
    +inline void FieldDescriptorProto::set_type_name(const char* value) {
    +  set_has_type_name();
    +  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    type_name_ = new ::std::string;
    +  }
    +  type_name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name)
    +}
    +inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
    +  set_has_type_name();
    +  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    type_name_ = new ::std::string;
    +  }
    +  type_name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name)
    +}
    +inline ::std::string* FieldDescriptorProto::mutable_type_name() {
    +  set_has_type_name();
    +  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    type_name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
    +  return type_name_;
    +}
    +inline ::std::string* FieldDescriptorProto::release_type_name() {
    +  clear_has_type_name();
    +  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = type_name_;
    +    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) {
    +  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete type_name_;
    +  }
    +  if (type_name) {
    +    set_has_type_name();
    +    type_name_ = type_name;
    +  } else {
    +    clear_has_type_name();
    +    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name)
    +}
    +
    +// optional string extendee = 2;
    +inline bool FieldDescriptorProto::has_extendee() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_extendee() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void FieldDescriptorProto::clear_has_extendee() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void FieldDescriptorProto::clear_extendee() {
    +  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    extendee_->clear();
    +  }
    +  clear_has_extendee();
    +}
    +inline const ::std::string& FieldDescriptorProto::extendee() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee)
    +  return *extendee_;
    +}
    +inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
    +  set_has_extendee();
    +  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    extendee_ = new ::std::string;
    +  }
    +  extendee_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
    +}
    +inline void FieldDescriptorProto::set_extendee(const char* value) {
    +  set_has_extendee();
    +  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    extendee_ = new ::std::string;
    +  }
    +  extendee_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
    +}
    +inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
    +  set_has_extendee();
    +  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    extendee_ = new ::std::string;
    +  }
    +  extendee_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee)
    +}
    +inline ::std::string* FieldDescriptorProto::mutable_extendee() {
    +  set_has_extendee();
    +  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    extendee_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
    +  return extendee_;
    +}
    +inline ::std::string* FieldDescriptorProto::release_extendee() {
    +  clear_has_extendee();
    +  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = extendee_;
    +    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) {
    +  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete extendee_;
    +  }
    +  if (extendee) {
    +    set_has_extendee();
    +    extendee_ = extendee;
    +  } else {
    +    clear_has_extendee();
    +    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee)
    +}
    +
    +// optional string default_value = 7;
    +inline bool FieldDescriptorProto::has_default_value() const {
    +  return (_has_bits_[0] & 0x00000040u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_default_value() {
    +  _has_bits_[0] |= 0x00000040u;
    +}
    +inline void FieldDescriptorProto::clear_has_default_value() {
    +  _has_bits_[0] &= ~0x00000040u;
    +}
    +inline void FieldDescriptorProto::clear_default_value() {
    +  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    default_value_->clear();
    +  }
    +  clear_has_default_value();
    +}
    +inline const ::std::string& FieldDescriptorProto::default_value() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value)
    +  return *default_value_;
    +}
    +inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
    +  set_has_default_value();
    +  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    default_value_ = new ::std::string;
    +  }
    +  default_value_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
    +}
    +inline void FieldDescriptorProto::set_default_value(const char* value) {
    +  set_has_default_value();
    +  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    default_value_ = new ::std::string;
    +  }
    +  default_value_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value)
    +}
    +inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
    +  set_has_default_value();
    +  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    default_value_ = new ::std::string;
    +  }
    +  default_value_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value)
    +}
    +inline ::std::string* FieldDescriptorProto::mutable_default_value() {
    +  set_has_default_value();
    +  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    default_value_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
    +  return default_value_;
    +}
    +inline ::std::string* FieldDescriptorProto::release_default_value() {
    +  clear_has_default_value();
    +  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = default_value_;
    +    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) {
    +  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete default_value_;
    +  }
    +  if (default_value) {
    +    set_has_default_value();
    +    default_value_ = default_value;
    +  } else {
    +    clear_has_default_value();
    +    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value)
    +}
    +
    +// optional int32 oneof_index = 9;
    +inline bool FieldDescriptorProto::has_oneof_index() const {
    +  return (_has_bits_[0] & 0x00000080u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_oneof_index() {
    +  _has_bits_[0] |= 0x00000080u;
    +}
    +inline void FieldDescriptorProto::clear_has_oneof_index() {
    +  _has_bits_[0] &= ~0x00000080u;
    +}
    +inline void FieldDescriptorProto::clear_oneof_index() {
    +  oneof_index_ = 0;
    +  clear_has_oneof_index();
    +}
    +inline ::google::protobuf::int32 FieldDescriptorProto::oneof_index() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index)
    +  return oneof_index_;
    +}
    +inline void FieldDescriptorProto::set_oneof_index(::google::protobuf::int32 value) {
    +  set_has_oneof_index();
    +  oneof_index_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
    +}
    +
    +// optional .google.protobuf.FieldOptions options = 8;
    +inline bool FieldDescriptorProto::has_options() const {
    +  return (_has_bits_[0] & 0x00000100u) != 0;
    +}
    +inline void FieldDescriptorProto::set_has_options() {
    +  _has_bits_[0] |= 0x00000100u;
    +}
    +inline void FieldDescriptorProto::clear_has_options() {
    +  _has_bits_[0] &= ~0x00000100u;
    +}
    +inline void FieldDescriptorProto::clear_options() {
    +  if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
    +  clear_has_options();
    +}
    +inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
    +  return options_ != NULL ? *options_ : *default_instance_->options_;
    +}
    +inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
    +  set_has_options();
    +  if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
    +  return options_;
    +}
    +inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
    +  clear_has_options();
    +  ::google::protobuf::FieldOptions* temp = options_;
    +  options_ = NULL;
    +  return temp;
    +}
    +inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
    +  delete options_;
    +  options_ = options;
    +  if (options) {
    +    set_has_options();
    +  } else {
    +    clear_has_options();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// OneofDescriptorProto
    +
    +// optional string name = 1;
    +inline bool OneofDescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void OneofDescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void OneofDescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void OneofDescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& OneofDescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name)
    +  return *name_;
    +}
    +inline void OneofDescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
    +}
    +inline void OneofDescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
    +}
    +inline void OneofDescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name)
    +}
    +inline ::std::string* OneofDescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* OneofDescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void OneofDescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// EnumDescriptorProto
    +
    +// optional string name = 1;
    +inline bool EnumDescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void EnumDescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void EnumDescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void EnumDescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& EnumDescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name)
    +  return *name_;
    +}
    +inline void EnumDescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
    +}
    +inline void EnumDescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
    +}
    +inline void EnumDescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name)
    +}
    +inline ::std::string* EnumDescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* EnumDescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void EnumDescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name)
    +}
    +
    +// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
    +inline int EnumDescriptorProto::value_size() const {
    +  return value_.size();
    +}
    +inline void EnumDescriptorProto::clear_value() {
    +  value_.Clear();
    +}
    +inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
    +  return value_.Get(index);
    +}
    +inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
    +  return value_.Mutable(index);
    +}
    +inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
    +  return value_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
    +EnumDescriptorProto::value() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
    +  return value_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
    +EnumDescriptorProto::mutable_value() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
    +  return &value_;
    +}
    +
    +// optional .google.protobuf.EnumOptions options = 3;
    +inline bool EnumDescriptorProto::has_options() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void EnumDescriptorProto::set_has_options() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void EnumDescriptorProto::clear_has_options() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void EnumDescriptorProto::clear_options() {
    +  if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
    +  clear_has_options();
    +}
    +inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
    +  return options_ != NULL ? *options_ : *default_instance_->options_;
    +}
    +inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
    +  set_has_options();
    +  if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
    +  return options_;
    +}
    +inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
    +  clear_has_options();
    +  ::google::protobuf::EnumOptions* temp = options_;
    +  options_ = NULL;
    +  return temp;
    +}
    +inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
    +  delete options_;
    +  options_ = options;
    +  if (options) {
    +    set_has_options();
    +  } else {
    +    clear_has_options();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// EnumValueDescriptorProto
    +
    +// optional string name = 1;
    +inline bool EnumValueDescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void EnumValueDescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void EnumValueDescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void EnumValueDescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& EnumValueDescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name)
    +  return *name_;
    +}
    +inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
    +}
    +inline void EnumValueDescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
    +}
    +inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name)
    +}
    +inline ::std::string* EnumValueDescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* EnumValueDescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name)
    +}
    +
    +// optional int32 number = 2;
    +inline bool EnumValueDescriptorProto::has_number() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void EnumValueDescriptorProto::set_has_number() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void EnumValueDescriptorProto::clear_has_number() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void EnumValueDescriptorProto::clear_number() {
    +  number_ = 0;
    +  clear_has_number();
    +}
    +inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
    +  return number_;
    +}
    +inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
    +  set_has_number();
    +  number_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
    +}
    +
    +// optional .google.protobuf.EnumValueOptions options = 3;
    +inline bool EnumValueDescriptorProto::has_options() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void EnumValueDescriptorProto::set_has_options() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void EnumValueDescriptorProto::clear_has_options() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void EnumValueDescriptorProto::clear_options() {
    +  if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
    +  clear_has_options();
    +}
    +inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
    +  return options_ != NULL ? *options_ : *default_instance_->options_;
    +}
    +inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
    +  set_has_options();
    +  if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
    +  return options_;
    +}
    +inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
    +  clear_has_options();
    +  ::google::protobuf::EnumValueOptions* temp = options_;
    +  options_ = NULL;
    +  return temp;
    +}
    +inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
    +  delete options_;
    +  options_ = options;
    +  if (options) {
    +    set_has_options();
    +  } else {
    +    clear_has_options();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ServiceDescriptorProto
    +
    +// optional string name = 1;
    +inline bool ServiceDescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ServiceDescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ServiceDescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ServiceDescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& ServiceDescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name)
    +  return *name_;
    +}
    +inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
    +}
    +inline void ServiceDescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
    +}
    +inline void ServiceDescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name)
    +}
    +inline ::std::string* ServiceDescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* ServiceDescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name)
    +}
    +
    +// repeated .google.protobuf.MethodDescriptorProto method = 2;
    +inline int ServiceDescriptorProto::method_size() const {
    +  return method_.size();
    +}
    +inline void ServiceDescriptorProto::clear_method() {
    +  method_.Clear();
    +}
    +inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
    +  return method_.Get(index);
    +}
    +inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
    +  return method_.Mutable(index);
    +}
    +inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
    +  return method_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
    +ServiceDescriptorProto::method() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
    +  return method_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
    +ServiceDescriptorProto::mutable_method() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
    +  return &method_;
    +}
    +
    +// optional .google.protobuf.ServiceOptions options = 3;
    +inline bool ServiceDescriptorProto::has_options() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void ServiceDescriptorProto::set_has_options() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void ServiceDescriptorProto::clear_has_options() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void ServiceDescriptorProto::clear_options() {
    +  if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
    +  clear_has_options();
    +}
    +inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
    +  return options_ != NULL ? *options_ : *default_instance_->options_;
    +}
    +inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
    +  set_has_options();
    +  if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
    +  return options_;
    +}
    +inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
    +  clear_has_options();
    +  ::google::protobuf::ServiceOptions* temp = options_;
    +  options_ = NULL;
    +  return temp;
    +}
    +inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
    +  delete options_;
    +  options_ = options;
    +  if (options) {
    +    set_has_options();
    +  } else {
    +    clear_has_options();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// MethodDescriptorProto
    +
    +// optional string name = 1;
    +inline bool MethodDescriptorProto::has_name() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void MethodDescriptorProto::set_has_name() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void MethodDescriptorProto::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void MethodDescriptorProto::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& MethodDescriptorProto::name() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name)
    +  return *name_;
    +}
    +inline void MethodDescriptorProto::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
    +}
    +inline void MethodDescriptorProto::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
    +}
    +inline void MethodDescriptorProto::set_name(const char* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name)
    +}
    +inline ::std::string* MethodDescriptorProto::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
    +  return name_;
    +}
    +inline ::std::string* MethodDescriptorProto::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void MethodDescriptorProto::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name)
    +}
    +
    +// optional string input_type = 2;
    +inline bool MethodDescriptorProto::has_input_type() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void MethodDescriptorProto::set_has_input_type() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void MethodDescriptorProto::clear_has_input_type() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void MethodDescriptorProto::clear_input_type() {
    +  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    input_type_->clear();
    +  }
    +  clear_has_input_type();
    +}
    +inline const ::std::string& MethodDescriptorProto::input_type() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type)
    +  return *input_type_;
    +}
    +inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
    +  set_has_input_type();
    +  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    input_type_ = new ::std::string;
    +  }
    +  input_type_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
    +}
    +inline void MethodDescriptorProto::set_input_type(const char* value) {
    +  set_has_input_type();
    +  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    input_type_ = new ::std::string;
    +  }
    +  input_type_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type)
    +}
    +inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
    +  set_has_input_type();
    +  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    input_type_ = new ::std::string;
    +  }
    +  input_type_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type)
    +}
    +inline ::std::string* MethodDescriptorProto::mutable_input_type() {
    +  set_has_input_type();
    +  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    input_type_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
    +  return input_type_;
    +}
    +inline ::std::string* MethodDescriptorProto::release_input_type() {
    +  clear_has_input_type();
    +  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = input_type_;
    +    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) {
    +  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete input_type_;
    +  }
    +  if (input_type) {
    +    set_has_input_type();
    +    input_type_ = input_type;
    +  } else {
    +    clear_has_input_type();
    +    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type)
    +}
    +
    +// optional string output_type = 3;
    +inline bool MethodDescriptorProto::has_output_type() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void MethodDescriptorProto::set_has_output_type() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void MethodDescriptorProto::clear_has_output_type() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void MethodDescriptorProto::clear_output_type() {
    +  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    output_type_->clear();
    +  }
    +  clear_has_output_type();
    +}
    +inline const ::std::string& MethodDescriptorProto::output_type() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type)
    +  return *output_type_;
    +}
    +inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
    +  set_has_output_type();
    +  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    output_type_ = new ::std::string;
    +  }
    +  output_type_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
    +}
    +inline void MethodDescriptorProto::set_output_type(const char* value) {
    +  set_has_output_type();
    +  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    output_type_ = new ::std::string;
    +  }
    +  output_type_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type)
    +}
    +inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
    +  set_has_output_type();
    +  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    output_type_ = new ::std::string;
    +  }
    +  output_type_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type)
    +}
    +inline ::std::string* MethodDescriptorProto::mutable_output_type() {
    +  set_has_output_type();
    +  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    output_type_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
    +  return output_type_;
    +}
    +inline ::std::string* MethodDescriptorProto::release_output_type() {
    +  clear_has_output_type();
    +  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = output_type_;
    +    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) {
    +  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete output_type_;
    +  }
    +  if (output_type) {
    +    set_has_output_type();
    +    output_type_ = output_type;
    +  } else {
    +    clear_has_output_type();
    +    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type)
    +}
    +
    +// optional .google.protobuf.MethodOptions options = 4;
    +inline bool MethodDescriptorProto::has_options() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void MethodDescriptorProto::set_has_options() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void MethodDescriptorProto::clear_has_options() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void MethodDescriptorProto::clear_options() {
    +  if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
    +  clear_has_options();
    +}
    +inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
    +  return options_ != NULL ? *options_ : *default_instance_->options_;
    +}
    +inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
    +  set_has_options();
    +  if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions;
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
    +  return options_;
    +}
    +inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
    +  clear_has_options();
    +  ::google::protobuf::MethodOptions* temp = options_;
    +  options_ = NULL;
    +  return temp;
    +}
    +inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
    +  delete options_;
    +  options_ = options;
    +  if (options) {
    +    set_has_options();
    +  } else {
    +    clear_has_options();
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// FileOptions
    +
    +// optional string java_package = 1;
    +inline bool FileOptions::has_java_package() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void FileOptions::set_has_java_package() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void FileOptions::clear_has_java_package() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void FileOptions::clear_java_package() {
    +  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_package_->clear();
    +  }
    +  clear_has_java_package();
    +}
    +inline const ::std::string& FileOptions::java_package() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
    +  return *java_package_;
    +}
    +inline void FileOptions::set_java_package(const ::std::string& value) {
    +  set_has_java_package();
    +  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_package_ = new ::std::string;
    +  }
    +  java_package_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
    +}
    +inline void FileOptions::set_java_package(const char* value) {
    +  set_has_java_package();
    +  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_package_ = new ::std::string;
    +  }
    +  java_package_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package)
    +}
    +inline void FileOptions::set_java_package(const char* value, size_t size) {
    +  set_has_java_package();
    +  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_package_ = new ::std::string;
    +  }
    +  java_package_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package)
    +}
    +inline ::std::string* FileOptions::mutable_java_package() {
    +  set_has_java_package();
    +  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_package_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
    +  return java_package_;
    +}
    +inline ::std::string* FileOptions::release_java_package() {
    +  clear_has_java_package();
    +  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = java_package_;
    +    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FileOptions::set_allocated_java_package(::std::string* java_package) {
    +  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete java_package_;
    +  }
    +  if (java_package) {
    +    set_has_java_package();
    +    java_package_ = java_package;
    +  } else {
    +    clear_has_java_package();
    +    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
    +}
    +
    +// optional string java_outer_classname = 8;
    +inline bool FileOptions::has_java_outer_classname() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void FileOptions::set_has_java_outer_classname() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void FileOptions::clear_has_java_outer_classname() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void FileOptions::clear_java_outer_classname() {
    +  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_outer_classname_->clear();
    +  }
    +  clear_has_java_outer_classname();
    +}
    +inline const ::std::string& FileOptions::java_outer_classname() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname)
    +  return *java_outer_classname_;
    +}
    +inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
    +  set_has_java_outer_classname();
    +  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_outer_classname_ = new ::std::string;
    +  }
    +  java_outer_classname_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
    +}
    +inline void FileOptions::set_java_outer_classname(const char* value) {
    +  set_has_java_outer_classname();
    +  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_outer_classname_ = new ::std::string;
    +  }
    +  java_outer_classname_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname)
    +}
    +inline void FileOptions::set_java_outer_classname(const char* value, size_t size) {
    +  set_has_java_outer_classname();
    +  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_outer_classname_ = new ::std::string;
    +  }
    +  java_outer_classname_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname)
    +}
    +inline ::std::string* FileOptions::mutable_java_outer_classname() {
    +  set_has_java_outer_classname();
    +  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    java_outer_classname_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
    +  return java_outer_classname_;
    +}
    +inline ::std::string* FileOptions::release_java_outer_classname() {
    +  clear_has_java_outer_classname();
    +  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = java_outer_classname_;
    +    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) {
    +  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete java_outer_classname_;
    +  }
    +  if (java_outer_classname) {
    +    set_has_java_outer_classname();
    +    java_outer_classname_ = java_outer_classname;
    +  } else {
    +    clear_has_java_outer_classname();
    +    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname)
    +}
    +
    +// optional bool java_multiple_files = 10 [default = false];
    +inline bool FileOptions::has_java_multiple_files() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void FileOptions::set_has_java_multiple_files() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void FileOptions::clear_has_java_multiple_files() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void FileOptions::clear_java_multiple_files() {
    +  java_multiple_files_ = false;
    +  clear_has_java_multiple_files();
    +}
    +inline bool FileOptions::java_multiple_files() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files)
    +  return java_multiple_files_;
    +}
    +inline void FileOptions::set_java_multiple_files(bool value) {
    +  set_has_java_multiple_files();
    +  java_multiple_files_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
    +}
    +
    +// optional bool java_generate_equals_and_hash = 20 [default = false];
    +inline bool FileOptions::has_java_generate_equals_and_hash() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void FileOptions::set_has_java_generate_equals_and_hash() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void FileOptions::clear_has_java_generate_equals_and_hash() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void FileOptions::clear_java_generate_equals_and_hash() {
    +  java_generate_equals_and_hash_ = false;
    +  clear_has_java_generate_equals_and_hash();
    +}
    +inline bool FileOptions::java_generate_equals_and_hash() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash)
    +  return java_generate_equals_and_hash_;
    +}
    +inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
    +  set_has_java_generate_equals_and_hash();
    +  java_generate_equals_and_hash_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
    +}
    +
    +// optional bool java_string_check_utf8 = 27 [default = false];
    +inline bool FileOptions::has_java_string_check_utf8() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void FileOptions::set_has_java_string_check_utf8() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void FileOptions::clear_has_java_string_check_utf8() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void FileOptions::clear_java_string_check_utf8() {
    +  java_string_check_utf8_ = false;
    +  clear_has_java_string_check_utf8();
    +}
    +inline bool FileOptions::java_string_check_utf8() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8)
    +  return java_string_check_utf8_;
    +}
    +inline void FileOptions::set_java_string_check_utf8(bool value) {
    +  set_has_java_string_check_utf8();
    +  java_string_check_utf8_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
    +}
    +
    +// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    +inline bool FileOptions::has_optimize_for() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void FileOptions::set_has_optimize_for() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void FileOptions::clear_has_optimize_for() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void FileOptions::clear_optimize_for() {
    +  optimize_for_ = 1;
    +  clear_has_optimize_for();
    +}
    +inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
    +  return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
    +}
    +inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
    +  assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
    +  set_has_optimize_for();
    +  optimize_for_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
    +}
    +
    +// optional string go_package = 11;
    +inline bool FileOptions::has_go_package() const {
    +  return (_has_bits_[0] & 0x00000040u) != 0;
    +}
    +inline void FileOptions::set_has_go_package() {
    +  _has_bits_[0] |= 0x00000040u;
    +}
    +inline void FileOptions::clear_has_go_package() {
    +  _has_bits_[0] &= ~0x00000040u;
    +}
    +inline void FileOptions::clear_go_package() {
    +  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    go_package_->clear();
    +  }
    +  clear_has_go_package();
    +}
    +inline const ::std::string& FileOptions::go_package() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package)
    +  return *go_package_;
    +}
    +inline void FileOptions::set_go_package(const ::std::string& value) {
    +  set_has_go_package();
    +  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    go_package_ = new ::std::string;
    +  }
    +  go_package_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
    +}
    +inline void FileOptions::set_go_package(const char* value) {
    +  set_has_go_package();
    +  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    go_package_ = new ::std::string;
    +  }
    +  go_package_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package)
    +}
    +inline void FileOptions::set_go_package(const char* value, size_t size) {
    +  set_has_go_package();
    +  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    go_package_ = new ::std::string;
    +  }
    +  go_package_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package)
    +}
    +inline ::std::string* FileOptions::mutable_go_package() {
    +  set_has_go_package();
    +  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    go_package_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
    +  return go_package_;
    +}
    +inline ::std::string* FileOptions::release_go_package() {
    +  clear_has_go_package();
    +  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = go_package_;
    +    go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FileOptions::set_allocated_go_package(::std::string* go_package) {
    +  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete go_package_;
    +  }
    +  if (go_package) {
    +    set_has_go_package();
    +    go_package_ = go_package;
    +  } else {
    +    clear_has_go_package();
    +    go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package)
    +}
    +
    +// optional bool cc_generic_services = 16 [default = false];
    +inline bool FileOptions::has_cc_generic_services() const {
    +  return (_has_bits_[0] & 0x00000080u) != 0;
    +}
    +inline void FileOptions::set_has_cc_generic_services() {
    +  _has_bits_[0] |= 0x00000080u;
    +}
    +inline void FileOptions::clear_has_cc_generic_services() {
    +  _has_bits_[0] &= ~0x00000080u;
    +}
    +inline void FileOptions::clear_cc_generic_services() {
    +  cc_generic_services_ = false;
    +  clear_has_cc_generic_services();
    +}
    +inline bool FileOptions::cc_generic_services() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
    +  return cc_generic_services_;
    +}
    +inline void FileOptions::set_cc_generic_services(bool value) {
    +  set_has_cc_generic_services();
    +  cc_generic_services_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
    +}
    +
    +// optional bool java_generic_services = 17 [default = false];
    +inline bool FileOptions::has_java_generic_services() const {
    +  return (_has_bits_[0] & 0x00000100u) != 0;
    +}
    +inline void FileOptions::set_has_java_generic_services() {
    +  _has_bits_[0] |= 0x00000100u;
    +}
    +inline void FileOptions::clear_has_java_generic_services() {
    +  _has_bits_[0] &= ~0x00000100u;
    +}
    +inline void FileOptions::clear_java_generic_services() {
    +  java_generic_services_ = false;
    +  clear_has_java_generic_services();
    +}
    +inline bool FileOptions::java_generic_services() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
    +  return java_generic_services_;
    +}
    +inline void FileOptions::set_java_generic_services(bool value) {
    +  set_has_java_generic_services();
    +  java_generic_services_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
    +}
    +
    +// optional bool py_generic_services = 18 [default = false];
    +inline bool FileOptions::has_py_generic_services() const {
    +  return (_has_bits_[0] & 0x00000200u) != 0;
    +}
    +inline void FileOptions::set_has_py_generic_services() {
    +  _has_bits_[0] |= 0x00000200u;
    +}
    +inline void FileOptions::clear_has_py_generic_services() {
    +  _has_bits_[0] &= ~0x00000200u;
    +}
    +inline void FileOptions::clear_py_generic_services() {
    +  py_generic_services_ = false;
    +  clear_has_py_generic_services();
    +}
    +inline bool FileOptions::py_generic_services() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
    +  return py_generic_services_;
    +}
    +inline void FileOptions::set_py_generic_services(bool value) {
    +  set_has_py_generic_services();
    +  py_generic_services_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
    +}
    +
    +// optional bool deprecated = 23 [default = false];
    +inline bool FileOptions::has_deprecated() const {
    +  return (_has_bits_[0] & 0x00000400u) != 0;
    +}
    +inline void FileOptions::set_has_deprecated() {
    +  _has_bits_[0] |= 0x00000400u;
    +}
    +inline void FileOptions::clear_has_deprecated() {
    +  _has_bits_[0] &= ~0x00000400u;
    +}
    +inline void FileOptions::clear_deprecated() {
    +  deprecated_ = false;
    +  clear_has_deprecated();
    +}
    +inline bool FileOptions::deprecated() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated)
    +  return deprecated_;
    +}
    +inline void FileOptions::set_deprecated(bool value) {
    +  set_has_deprecated();
    +  deprecated_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
    +}
    +
    +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +inline int FileOptions::uninterpreted_option_size() const {
    +  return uninterpreted_option_.size();
    +}
    +inline void FileOptions::clear_uninterpreted_option() {
    +  uninterpreted_option_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
    +  return uninterpreted_option_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
    +  return uninterpreted_option_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
    +  return uninterpreted_option_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +FileOptions::uninterpreted_option() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
    +  return uninterpreted_option_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +FileOptions::mutable_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
    +  return &uninterpreted_option_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// MessageOptions
    +
    +// optional bool message_set_wire_format = 1 [default = false];
    +inline bool MessageOptions::has_message_set_wire_format() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void MessageOptions::set_has_message_set_wire_format() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void MessageOptions::clear_has_message_set_wire_format() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void MessageOptions::clear_message_set_wire_format() {
    +  message_set_wire_format_ = false;
    +  clear_has_message_set_wire_format();
    +}
    +inline bool MessageOptions::message_set_wire_format() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format)
    +  return message_set_wire_format_;
    +}
    +inline void MessageOptions::set_message_set_wire_format(bool value) {
    +  set_has_message_set_wire_format();
    +  message_set_wire_format_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
    +}
    +
    +// optional bool no_standard_descriptor_accessor = 2 [default = false];
    +inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void MessageOptions::set_has_no_standard_descriptor_accessor() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void MessageOptions::clear_has_no_standard_descriptor_accessor() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void MessageOptions::clear_no_standard_descriptor_accessor() {
    +  no_standard_descriptor_accessor_ = false;
    +  clear_has_no_standard_descriptor_accessor();
    +}
    +inline bool MessageOptions::no_standard_descriptor_accessor() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
    +  return no_standard_descriptor_accessor_;
    +}
    +inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
    +  set_has_no_standard_descriptor_accessor();
    +  no_standard_descriptor_accessor_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
    +}
    +
    +// optional bool deprecated = 3 [default = false];
    +inline bool MessageOptions::has_deprecated() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void MessageOptions::set_has_deprecated() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void MessageOptions::clear_has_deprecated() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void MessageOptions::clear_deprecated() {
    +  deprecated_ = false;
    +  clear_has_deprecated();
    +}
    +inline bool MessageOptions::deprecated() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
    +  return deprecated_;
    +}
    +inline void MessageOptions::set_deprecated(bool value) {
    +  set_has_deprecated();
    +  deprecated_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
    +}
    +
    +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +inline int MessageOptions::uninterpreted_option_size() const {
    +  return uninterpreted_option_.size();
    +}
    +inline void MessageOptions::clear_uninterpreted_option() {
    +  uninterpreted_option_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option)
    +  return uninterpreted_option_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option)
    +  return uninterpreted_option_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
    +  return uninterpreted_option_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +MessageOptions::uninterpreted_option() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
    +  return uninterpreted_option_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +MessageOptions::mutable_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
    +  return &uninterpreted_option_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// FieldOptions
    +
    +// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    +inline bool FieldOptions::has_ctype() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void FieldOptions::set_has_ctype() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void FieldOptions::clear_has_ctype() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void FieldOptions::clear_ctype() {
    +  ctype_ = 0;
    +  clear_has_ctype();
    +}
    +inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
    +  return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
    +}
    +inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
    +  assert(::google::protobuf::FieldOptions_CType_IsValid(value));
    +  set_has_ctype();
    +  ctype_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
    +}
    +
    +// optional bool packed = 2;
    +inline bool FieldOptions::has_packed() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void FieldOptions::set_has_packed() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void FieldOptions::clear_has_packed() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void FieldOptions::clear_packed() {
    +  packed_ = false;
    +  clear_has_packed();
    +}
    +inline bool FieldOptions::packed() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed)
    +  return packed_;
    +}
    +inline void FieldOptions::set_packed(bool value) {
    +  set_has_packed();
    +  packed_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
    +}
    +
    +// optional bool lazy = 5 [default = false];
    +inline bool FieldOptions::has_lazy() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void FieldOptions::set_has_lazy() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void FieldOptions::clear_has_lazy() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void FieldOptions::clear_lazy() {
    +  lazy_ = false;
    +  clear_has_lazy();
    +}
    +inline bool FieldOptions::lazy() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy)
    +  return lazy_;
    +}
    +inline void FieldOptions::set_lazy(bool value) {
    +  set_has_lazy();
    +  lazy_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
    +}
    +
    +// optional bool deprecated = 3 [default = false];
    +inline bool FieldOptions::has_deprecated() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void FieldOptions::set_has_deprecated() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void FieldOptions::clear_has_deprecated() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void FieldOptions::clear_deprecated() {
    +  deprecated_ = false;
    +  clear_has_deprecated();
    +}
    +inline bool FieldOptions::deprecated() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated)
    +  return deprecated_;
    +}
    +inline void FieldOptions::set_deprecated(bool value) {
    +  set_has_deprecated();
    +  deprecated_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
    +}
    +
    +// optional string experimental_map_key = 9;
    +inline bool FieldOptions::has_experimental_map_key() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void FieldOptions::set_has_experimental_map_key() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void FieldOptions::clear_has_experimental_map_key() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void FieldOptions::clear_experimental_map_key() {
    +  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    experimental_map_key_->clear();
    +  }
    +  clear_has_experimental_map_key();
    +}
    +inline const ::std::string& FieldOptions::experimental_map_key() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.experimental_map_key)
    +  return *experimental_map_key_;
    +}
    +inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
    +  set_has_experimental_map_key();
    +  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    experimental_map_key_ = new ::std::string;
    +  }
    +  experimental_map_key_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.experimental_map_key)
    +}
    +inline void FieldOptions::set_experimental_map_key(const char* value) {
    +  set_has_experimental_map_key();
    +  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    experimental_map_key_ = new ::std::string;
    +  }
    +  experimental_map_key_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldOptions.experimental_map_key)
    +}
    +inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) {
    +  set_has_experimental_map_key();
    +  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    experimental_map_key_ = new ::std::string;
    +  }
    +  experimental_map_key_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldOptions.experimental_map_key)
    +}
    +inline ::std::string* FieldOptions::mutable_experimental_map_key() {
    +  set_has_experimental_map_key();
    +  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    experimental_map_key_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.experimental_map_key)
    +  return experimental_map_key_;
    +}
    +inline ::std::string* FieldOptions::release_experimental_map_key() {
    +  clear_has_experimental_map_key();
    +  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = experimental_map_key_;
    +    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void FieldOptions::set_allocated_experimental_map_key(::std::string* experimental_map_key) {
    +  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete experimental_map_key_;
    +  }
    +  if (experimental_map_key) {
    +    set_has_experimental_map_key();
    +    experimental_map_key_ = experimental_map_key;
    +  } else {
    +    clear_has_experimental_map_key();
    +    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.experimental_map_key)
    +}
    +
    +// optional bool weak = 10 [default = false];
    +inline bool FieldOptions::has_weak() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void FieldOptions::set_has_weak() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void FieldOptions::clear_has_weak() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void FieldOptions::clear_weak() {
    +  weak_ = false;
    +  clear_has_weak();
    +}
    +inline bool FieldOptions::weak() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak)
    +  return weak_;
    +}
    +inline void FieldOptions::set_weak(bool value) {
    +  set_has_weak();
    +  weak_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
    +}
    +
    +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +inline int FieldOptions::uninterpreted_option_size() const {
    +  return uninterpreted_option_.size();
    +}
    +inline void FieldOptions::clear_uninterpreted_option() {
    +  uninterpreted_option_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option)
    +  return uninterpreted_option_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option)
    +  return uninterpreted_option_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
    +  return uninterpreted_option_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +FieldOptions::uninterpreted_option() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
    +  return uninterpreted_option_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +FieldOptions::mutable_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
    +  return &uninterpreted_option_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// EnumOptions
    +
    +// optional bool allow_alias = 2;
    +inline bool EnumOptions::has_allow_alias() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void EnumOptions::set_has_allow_alias() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void EnumOptions::clear_has_allow_alias() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void EnumOptions::clear_allow_alias() {
    +  allow_alias_ = false;
    +  clear_has_allow_alias();
    +}
    +inline bool EnumOptions::allow_alias() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
    +  return allow_alias_;
    +}
    +inline void EnumOptions::set_allow_alias(bool value) {
    +  set_has_allow_alias();
    +  allow_alias_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
    +}
    +
    +// optional bool deprecated = 3 [default = false];
    +inline bool EnumOptions::has_deprecated() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void EnumOptions::set_has_deprecated() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void EnumOptions::clear_has_deprecated() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void EnumOptions::clear_deprecated() {
    +  deprecated_ = false;
    +  clear_has_deprecated();
    +}
    +inline bool EnumOptions::deprecated() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated)
    +  return deprecated_;
    +}
    +inline void EnumOptions::set_deprecated(bool value) {
    +  set_has_deprecated();
    +  deprecated_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
    +}
    +
    +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +inline int EnumOptions::uninterpreted_option_size() const {
    +  return uninterpreted_option_.size();
    +}
    +inline void EnumOptions::clear_uninterpreted_option() {
    +  uninterpreted_option_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option)
    +  return uninterpreted_option_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option)
    +  return uninterpreted_option_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
    +  return uninterpreted_option_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +EnumOptions::uninterpreted_option() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
    +  return uninterpreted_option_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +EnumOptions::mutable_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
    +  return &uninterpreted_option_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// EnumValueOptions
    +
    +// optional bool deprecated = 1 [default = false];
    +inline bool EnumValueOptions::has_deprecated() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void EnumValueOptions::set_has_deprecated() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void EnumValueOptions::clear_has_deprecated() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void EnumValueOptions::clear_deprecated() {
    +  deprecated_ = false;
    +  clear_has_deprecated();
    +}
    +inline bool EnumValueOptions::deprecated() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
    +  return deprecated_;
    +}
    +inline void EnumValueOptions::set_deprecated(bool value) {
    +  set_has_deprecated();
    +  deprecated_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
    +}
    +
    +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +inline int EnumValueOptions::uninterpreted_option_size() const {
    +  return uninterpreted_option_.size();
    +}
    +inline void EnumValueOptions::clear_uninterpreted_option() {
    +  uninterpreted_option_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option)
    +  return uninterpreted_option_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option)
    +  return uninterpreted_option_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
    +  return uninterpreted_option_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +EnumValueOptions::uninterpreted_option() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
    +  return uninterpreted_option_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +EnumValueOptions::mutable_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
    +  return &uninterpreted_option_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// ServiceOptions
    +
    +// optional bool deprecated = 33 [default = false];
    +inline bool ServiceOptions::has_deprecated() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void ServiceOptions::set_has_deprecated() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void ServiceOptions::clear_has_deprecated() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void ServiceOptions::clear_deprecated() {
    +  deprecated_ = false;
    +  clear_has_deprecated();
    +}
    +inline bool ServiceOptions::deprecated() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
    +  return deprecated_;
    +}
    +inline void ServiceOptions::set_deprecated(bool value) {
    +  set_has_deprecated();
    +  deprecated_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
    +}
    +
    +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +inline int ServiceOptions::uninterpreted_option_size() const {
    +  return uninterpreted_option_.size();
    +}
    +inline void ServiceOptions::clear_uninterpreted_option() {
    +  uninterpreted_option_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option)
    +  return uninterpreted_option_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option)
    +  return uninterpreted_option_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
    +  return uninterpreted_option_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +ServiceOptions::uninterpreted_option() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
    +  return uninterpreted_option_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +ServiceOptions::mutable_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
    +  return &uninterpreted_option_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// MethodOptions
    +
    +// optional bool deprecated = 33 [default = false];
    +inline bool MethodOptions::has_deprecated() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void MethodOptions::set_has_deprecated() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void MethodOptions::clear_has_deprecated() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void MethodOptions::clear_deprecated() {
    +  deprecated_ = false;
    +  clear_has_deprecated();
    +}
    +inline bool MethodOptions::deprecated() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
    +  return deprecated_;
    +}
    +inline void MethodOptions::set_deprecated(bool value) {
    +  set_has_deprecated();
    +  deprecated_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
    +}
    +
    +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
    +inline int MethodOptions::uninterpreted_option_size() const {
    +  return uninterpreted_option_.size();
    +}
    +inline void MethodOptions::clear_uninterpreted_option() {
    +  uninterpreted_option_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
    +  return uninterpreted_option_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
    +  return uninterpreted_option_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
    +  return uninterpreted_option_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
    +MethodOptions::uninterpreted_option() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
    +  return uninterpreted_option_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
    +MethodOptions::mutable_uninterpreted_option() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
    +  return &uninterpreted_option_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// UninterpretedOption_NamePart
    +
    +// required string name_part = 1;
    +inline bool UninterpretedOption_NamePart::has_name_part() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void UninterpretedOption_NamePart::set_has_name_part() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void UninterpretedOption_NamePart::clear_has_name_part() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void UninterpretedOption_NamePart::clear_name_part() {
    +  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_part_->clear();
    +  }
    +  clear_has_name_part();
    +}
    +inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
    +  return *name_part_;
    +}
    +inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
    +  set_has_name_part();
    +  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_part_ = new ::std::string;
    +  }
    +  name_part_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
    +}
    +inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
    +  set_has_name_part();
    +  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_part_ = new ::std::string;
    +  }
    +  name_part_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part)
    +}
    +inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
    +  set_has_name_part();
    +  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_part_ = new ::std::string;
    +  }
    +  name_part_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part)
    +}
    +inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
    +  set_has_name_part();
    +  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_part_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
    +  return name_part_;
    +}
    +inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
    +  clear_has_name_part();
    +  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_part_;
    +    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
    +  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_part_;
    +  }
    +  if (name_part) {
    +    set_has_name_part();
    +    name_part_ = name_part;
    +  } else {
    +    clear_has_name_part();
    +    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
    +}
    +
    +// required bool is_extension = 2;
    +inline bool UninterpretedOption_NamePart::has_is_extension() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void UninterpretedOption_NamePart::set_has_is_extension() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void UninterpretedOption_NamePart::clear_has_is_extension() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void UninterpretedOption_NamePart::clear_is_extension() {
    +  is_extension_ = false;
    +  clear_has_is_extension();
    +}
    +inline bool UninterpretedOption_NamePart::is_extension() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
    +  return is_extension_;
    +}
    +inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
    +  set_has_is_extension();
    +  is_extension_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// UninterpretedOption
    +
    +// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
    +inline int UninterpretedOption::name_size() const {
    +  return name_.size();
    +}
    +inline void UninterpretedOption::clear_name() {
    +  name_.Clear();
    +}
    +inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
    +  return name_.Get(index);
    +}
    +inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
    +  return name_.Mutable(index);
    +}
    +inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
    +  return name_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
    +UninterpretedOption::name() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
    +  return name_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
    +UninterpretedOption::mutable_name() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
    +  return &name_;
    +}
    +
    +// optional string identifier_value = 3;
    +inline bool UninterpretedOption::has_identifier_value() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void UninterpretedOption::set_has_identifier_value() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void UninterpretedOption::clear_has_identifier_value() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void UninterpretedOption::clear_identifier_value() {
    +  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    identifier_value_->clear();
    +  }
    +  clear_has_identifier_value();
    +}
    +inline const ::std::string& UninterpretedOption::identifier_value() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value)
    +  return *identifier_value_;
    +}
    +inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
    +  set_has_identifier_value();
    +  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    identifier_value_ = new ::std::string;
    +  }
    +  identifier_value_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
    +}
    +inline void UninterpretedOption::set_identifier_value(const char* value) {
    +  set_has_identifier_value();
    +  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    identifier_value_ = new ::std::string;
    +  }
    +  identifier_value_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value)
    +}
    +inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
    +  set_has_identifier_value();
    +  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    identifier_value_ = new ::std::string;
    +  }
    +  identifier_value_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value)
    +}
    +inline ::std::string* UninterpretedOption::mutable_identifier_value() {
    +  set_has_identifier_value();
    +  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    identifier_value_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
    +  return identifier_value_;
    +}
    +inline ::std::string* UninterpretedOption::release_identifier_value() {
    +  clear_has_identifier_value();
    +  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = identifier_value_;
    +    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) {
    +  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete identifier_value_;
    +  }
    +  if (identifier_value) {
    +    set_has_identifier_value();
    +    identifier_value_ = identifier_value;
    +  } else {
    +    clear_has_identifier_value();
    +    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value)
    +}
    +
    +// optional uint64 positive_int_value = 4;
    +inline bool UninterpretedOption::has_positive_int_value() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void UninterpretedOption::set_has_positive_int_value() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void UninterpretedOption::clear_has_positive_int_value() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void UninterpretedOption::clear_positive_int_value() {
    +  positive_int_value_ = GOOGLE_ULONGLONG(0);
    +  clear_has_positive_int_value();
    +}
    +inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value)
    +  return positive_int_value_;
    +}
    +inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
    +  set_has_positive_int_value();
    +  positive_int_value_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
    +}
    +
    +// optional int64 negative_int_value = 5;
    +inline bool UninterpretedOption::has_negative_int_value() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void UninterpretedOption::set_has_negative_int_value() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void UninterpretedOption::clear_has_negative_int_value() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void UninterpretedOption::clear_negative_int_value() {
    +  negative_int_value_ = GOOGLE_LONGLONG(0);
    +  clear_has_negative_int_value();
    +}
    +inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value)
    +  return negative_int_value_;
    +}
    +inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
    +  set_has_negative_int_value();
    +  negative_int_value_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
    +}
    +
    +// optional double double_value = 6;
    +inline bool UninterpretedOption::has_double_value() const {
    +  return (_has_bits_[0] & 0x00000010u) != 0;
    +}
    +inline void UninterpretedOption::set_has_double_value() {
    +  _has_bits_[0] |= 0x00000010u;
    +}
    +inline void UninterpretedOption::clear_has_double_value() {
    +  _has_bits_[0] &= ~0x00000010u;
    +}
    +inline void UninterpretedOption::clear_double_value() {
    +  double_value_ = 0;
    +  clear_has_double_value();
    +}
    +inline double UninterpretedOption::double_value() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value)
    +  return double_value_;
    +}
    +inline void UninterpretedOption::set_double_value(double value) {
    +  set_has_double_value();
    +  double_value_ = value;
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
    +}
    +
    +// optional bytes string_value = 7;
    +inline bool UninterpretedOption::has_string_value() const {
    +  return (_has_bits_[0] & 0x00000020u) != 0;
    +}
    +inline void UninterpretedOption::set_has_string_value() {
    +  _has_bits_[0] |= 0x00000020u;
    +}
    +inline void UninterpretedOption::clear_has_string_value() {
    +  _has_bits_[0] &= ~0x00000020u;
    +}
    +inline void UninterpretedOption::clear_string_value() {
    +  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    string_value_->clear();
    +  }
    +  clear_has_string_value();
    +}
    +inline const ::std::string& UninterpretedOption::string_value() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value)
    +  return *string_value_;
    +}
    +inline void UninterpretedOption::set_string_value(const ::std::string& value) {
    +  set_has_string_value();
    +  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    string_value_ = new ::std::string;
    +  }
    +  string_value_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
    +}
    +inline void UninterpretedOption::set_string_value(const char* value) {
    +  set_has_string_value();
    +  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    string_value_ = new ::std::string;
    +  }
    +  string_value_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value)
    +}
    +inline void UninterpretedOption::set_string_value(const void* value, size_t size) {
    +  set_has_string_value();
    +  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    string_value_ = new ::std::string;
    +  }
    +  string_value_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value)
    +}
    +inline ::std::string* UninterpretedOption::mutable_string_value() {
    +  set_has_string_value();
    +  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    string_value_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
    +  return string_value_;
    +}
    +inline ::std::string* UninterpretedOption::release_string_value() {
    +  clear_has_string_value();
    +  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = string_value_;
    +    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) {
    +  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete string_value_;
    +  }
    +  if (string_value) {
    +    set_has_string_value();
    +    string_value_ = string_value;
    +  } else {
    +    clear_has_string_value();
    +    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value)
    +}
    +
    +// optional string aggregate_value = 8;
    +inline bool UninterpretedOption::has_aggregate_value() const {
    +  return (_has_bits_[0] & 0x00000040u) != 0;
    +}
    +inline void UninterpretedOption::set_has_aggregate_value() {
    +  _has_bits_[0] |= 0x00000040u;
    +}
    +inline void UninterpretedOption::clear_has_aggregate_value() {
    +  _has_bits_[0] &= ~0x00000040u;
    +}
    +inline void UninterpretedOption::clear_aggregate_value() {
    +  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    aggregate_value_->clear();
    +  }
    +  clear_has_aggregate_value();
    +}
    +inline const ::std::string& UninterpretedOption::aggregate_value() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value)
    +  return *aggregate_value_;
    +}
    +inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
    +  set_has_aggregate_value();
    +  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    aggregate_value_ = new ::std::string;
    +  }
    +  aggregate_value_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
    +}
    +inline void UninterpretedOption::set_aggregate_value(const char* value) {
    +  set_has_aggregate_value();
    +  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    aggregate_value_ = new ::std::string;
    +  }
    +  aggregate_value_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value)
    +}
    +inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
    +  set_has_aggregate_value();
    +  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    aggregate_value_ = new ::std::string;
    +  }
    +  aggregate_value_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value)
    +}
    +inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
    +  set_has_aggregate_value();
    +  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    aggregate_value_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
    +  return aggregate_value_;
    +}
    +inline ::std::string* UninterpretedOption::release_aggregate_value() {
    +  clear_has_aggregate_value();
    +  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = aggregate_value_;
    +    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) {
    +  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete aggregate_value_;
    +  }
    +  if (aggregate_value) {
    +    set_has_aggregate_value();
    +    aggregate_value_ = aggregate_value;
    +  } else {
    +    clear_has_aggregate_value();
    +    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// SourceCodeInfo_Location
    +
    +// repeated int32 path = 1 [packed = true];
    +inline int SourceCodeInfo_Location::path_size() const {
    +  return path_.size();
    +}
    +inline void SourceCodeInfo_Location::clear_path() {
    +  path_.Clear();
    +}
    +inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.path)
    +  return path_.Get(index);
    +}
    +inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
    +  path_.Set(index, value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
    +}
    +inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
    +  path_.Add(value);
    +  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path)
    +}
    +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +SourceCodeInfo_Location::path() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
    +  return path_;
    +}
    +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +SourceCodeInfo_Location::mutable_path() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path)
    +  return &path_;
    +}
    +
    +// repeated int32 span = 2 [packed = true];
    +inline int SourceCodeInfo_Location::span_size() const {
    +  return span_.size();
    +}
    +inline void SourceCodeInfo_Location::clear_span() {
    +  span_.Clear();
    +}
    +inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.span)
    +  return span_.Get(index);
    +}
    +inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
    +  span_.Set(index, value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
    +}
    +inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
    +  span_.Add(value);
    +  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span)
    +}
    +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
    +SourceCodeInfo_Location::span() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
    +  return span_;
    +}
    +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
    +SourceCodeInfo_Location::mutable_span() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span)
    +  return &span_;
    +}
    +
    +// optional string leading_comments = 3;
    +inline bool SourceCodeInfo_Location::has_leading_comments() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void SourceCodeInfo_Location::set_has_leading_comments() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void SourceCodeInfo_Location::clear_has_leading_comments() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void SourceCodeInfo_Location::clear_leading_comments() {
    +  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    leading_comments_->clear();
    +  }
    +  clear_has_leading_comments();
    +}
    +inline const ::std::string& SourceCodeInfo_Location::leading_comments() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments)
    +  return *leading_comments_;
    +}
    +inline void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) {
    +  set_has_leading_comments();
    +  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    leading_comments_ = new ::std::string;
    +  }
    +  leading_comments_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
    +}
    +inline void SourceCodeInfo_Location::set_leading_comments(const char* value) {
    +  set_has_leading_comments();
    +  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    leading_comments_ = new ::std::string;
    +  }
    +  leading_comments_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments)
    +}
    +inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) {
    +  set_has_leading_comments();
    +  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    leading_comments_ = new ::std::string;
    +  }
    +  leading_comments_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments)
    +}
    +inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() {
    +  set_has_leading_comments();
    +  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    leading_comments_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
    +  return leading_comments_;
    +}
    +inline ::std::string* SourceCodeInfo_Location::release_leading_comments() {
    +  clear_has_leading_comments();
    +  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = leading_comments_;
    +    leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) {
    +  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete leading_comments_;
    +  }
    +  if (leading_comments) {
    +    set_has_leading_comments();
    +    leading_comments_ = leading_comments;
    +  } else {
    +    clear_has_leading_comments();
    +    leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments)
    +}
    +
    +// optional string trailing_comments = 4;
    +inline bool SourceCodeInfo_Location::has_trailing_comments() const {
    +  return (_has_bits_[0] & 0x00000008u) != 0;
    +}
    +inline void SourceCodeInfo_Location::set_has_trailing_comments() {
    +  _has_bits_[0] |= 0x00000008u;
    +}
    +inline void SourceCodeInfo_Location::clear_has_trailing_comments() {
    +  _has_bits_[0] &= ~0x00000008u;
    +}
    +inline void SourceCodeInfo_Location::clear_trailing_comments() {
    +  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    trailing_comments_->clear();
    +  }
    +  clear_has_trailing_comments();
    +}
    +inline const ::std::string& SourceCodeInfo_Location::trailing_comments() const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments)
    +  return *trailing_comments_;
    +}
    +inline void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) {
    +  set_has_trailing_comments();
    +  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    trailing_comments_ = new ::std::string;
    +  }
    +  trailing_comments_->assign(value);
    +  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
    +}
    +inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
    +  set_has_trailing_comments();
    +  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    trailing_comments_ = new ::std::string;
    +  }
    +  trailing_comments_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments)
    +}
    +inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) {
    +  set_has_trailing_comments();
    +  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    trailing_comments_ = new ::std::string;
    +  }
    +  trailing_comments_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments)
    +}
    +inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
    +  set_has_trailing_comments();
    +  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    trailing_comments_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
    +  return trailing_comments_;
    +}
    +inline ::std::string* SourceCodeInfo_Location::release_trailing_comments() {
    +  clear_has_trailing_comments();
    +  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = trailing_comments_;
    +    trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) {
    +  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete trailing_comments_;
    +  }
    +  if (trailing_comments) {
    +    set_has_trailing_comments();
    +    trailing_comments_ = trailing_comments;
    +  } else {
    +    clear_has_trailing_comments();
    +    trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// SourceCodeInfo
    +
    +// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
    +inline int SourceCodeInfo::location_size() const {
    +  return location_.size();
    +}
    +inline void SourceCodeInfo::clear_location() {
    +  location_.Clear();
    +}
    +inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
    +  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location)
    +  return location_.Get(index);
    +}
    +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
    +  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
    +  return location_.Mutable(index);
    +}
    +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
    +  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
    +  return location_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
    +SourceCodeInfo::location() const {
    +  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
    +  return location_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
    +SourceCodeInfo::mutable_location() {
    +  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
    +  return &location_;
    +}
    +
    +
    +// @@protoc_insertion_point(namespace_scope)
    +
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#ifndef SWIG
    +namespace google {
    +namespace protobuf {
    +
    +template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Type> : ::google::protobuf::internal::true_type {};
    +template <>
    +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() {
    +  return ::google::protobuf::FieldDescriptorProto_Type_descriptor();
    +}
    +template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Label> : ::google::protobuf::internal::true_type {};
    +template <>
    +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() {
    +  return ::google::protobuf::FieldDescriptorProto_Label_descriptor();
    +}
    +template <> struct is_proto_enum< ::google::protobuf::FileOptions_OptimizeMode> : ::google::protobuf::internal::true_type {};
    +template <>
    +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() {
    +  return ::google::protobuf::FileOptions_OptimizeMode_descriptor();
    +}
    +template <> struct is_proto_enum< ::google::protobuf::FieldOptions_CType> : ::google::protobuf::internal::true_type {};
    +template <>
    +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() {
    +  return ::google::protobuf::FieldOptions_CType_descriptor();
    +}
    +
    +}  // namespace google
    +}  // namespace protobuf
    +#endif  // SWIG
    +
    +// @@protoc_insertion_point(global_scope)
    +
    +#endif  // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
    diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor.proto b/toolkit/components/protobuf/src/google/protobuf/descriptor.proto
    new file mode 100644
    index 000000000000..a753601f39d5
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/descriptor.proto
    @@ -0,0 +1,687 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// The messages in this file describe the definitions found in .proto files.
    +// A valid .proto file can be translated directly to a FileDescriptorProto
    +// without any other information (e.g. without reading its imports).
    +
    +
    +
    +package google.protobuf;
    +option java_package = "com.google.protobuf";
    +option java_outer_classname = "DescriptorProtos";
    +
    +// descriptor.proto must be optimized for speed because reflection-based
    +// algorithms don't work during bootstrapping.
    +option optimize_for = SPEED;
    +
    +// The protocol compiler can output a FileDescriptorSet containing the .proto
    +// files it parses.
    +message FileDescriptorSet {
    +  repeated FileDescriptorProto file = 1;
    +}
    +
    +// Describes a complete .proto file.
    +message FileDescriptorProto {
    +  optional string name = 1;       // file name, relative to root of source tree
    +  optional string package = 2;    // e.g. "foo", "foo.bar", etc.
    +
    +  // Names of files imported by this file.
    +  repeated string dependency = 3;
    +  // Indexes of the public imported files in the dependency list above.
    +  repeated int32 public_dependency = 10;
    +  // Indexes of the weak imported files in the dependency list.
    +  // For Google-internal migration only. Do not use.
    +  repeated int32 weak_dependency = 11;
    +
    +  // All top-level definitions in this file.
    +  repeated DescriptorProto message_type = 4;
    +  repeated EnumDescriptorProto enum_type = 5;
    +  repeated ServiceDescriptorProto service = 6;
    +  repeated FieldDescriptorProto extension = 7;
    +
    +  optional FileOptions options = 8;
    +
    +  // This field contains optional information about the original source code.
    +  // You may safely remove this entire field whithout harming runtime
    +  // functionality of the descriptors -- the information is needed only by
    +  // development tools.
    +  optional SourceCodeInfo source_code_info = 9;
    +}
    +
    +// Describes a message type.
    +message DescriptorProto {
    +  optional string name = 1;
    +
    +  repeated FieldDescriptorProto field = 2;
    +  repeated FieldDescriptorProto extension = 6;
    +
    +  repeated DescriptorProto nested_type = 3;
    +  repeated EnumDescriptorProto enum_type = 4;
    +
    +  message ExtensionRange {
    +    optional int32 start = 1;
    +    optional int32 end = 2;
    +  }
    +  repeated ExtensionRange extension_range = 5;
    +
    +  repeated OneofDescriptorProto oneof_decl = 8;
    +
    +  optional MessageOptions options = 7;
    +}
    +
    +// Describes a field within a message.
    +message FieldDescriptorProto {
    +  enum Type {
    +    // 0 is reserved for errors.
    +    // Order is weird for historical reasons.
    +    TYPE_DOUBLE         = 1;
    +    TYPE_FLOAT          = 2;
    +    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
    +    // negative values are likely.
    +    TYPE_INT64          = 3;
    +    TYPE_UINT64         = 4;
    +    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
    +    // negative values are likely.
    +    TYPE_INT32          = 5;
    +    TYPE_FIXED64        = 6;
    +    TYPE_FIXED32        = 7;
    +    TYPE_BOOL           = 8;
    +    TYPE_STRING         = 9;
    +    TYPE_GROUP          = 10;  // Tag-delimited aggregate.
    +    TYPE_MESSAGE        = 11;  // Length-delimited aggregate.
    +
    +    // New in version 2.
    +    TYPE_BYTES          = 12;
    +    TYPE_UINT32         = 13;
    +    TYPE_ENUM           = 14;
    +    TYPE_SFIXED32       = 15;
    +    TYPE_SFIXED64       = 16;
    +    TYPE_SINT32         = 17;  // Uses ZigZag encoding.
    +    TYPE_SINT64         = 18;  // Uses ZigZag encoding.
    +  };
    +
    +  enum Label {
    +    // 0 is reserved for errors
    +    LABEL_OPTIONAL      = 1;
    +    LABEL_REQUIRED      = 2;
    +    LABEL_REPEATED      = 3;
    +    // TODO(sanjay): Should we add LABEL_MAP?
    +  };
    +
    +  optional string name = 1;
    +  optional int32 number = 3;
    +  optional Label label = 4;
    +
    +  // If type_name is set, this need not be set.  If both this and type_name
    +  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
    +  optional Type type = 5;
    +
    +  // For message and enum types, this is the name of the type.  If the name
    +  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
    +  // rules are used to find the type (i.e. first the nested types within this
    +  // message are searched, then within the parent, on up to the root
    +  // namespace).
    +  optional string type_name = 6;
    +
    +  // For extensions, this is the name of the type being extended.  It is
    +  // resolved in the same manner as type_name.
    +  optional string extendee = 2;
    +
    +  // For numeric types, contains the original text representation of the value.
    +  // For booleans, "true" or "false".
    +  // For strings, contains the default text contents (not escaped in any way).
    +  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
    +  // TODO(kenton):  Base-64 encode?
    +  optional string default_value = 7;
    +
    +  // If set, gives the index of a oneof in the containing type's oneof_decl
    +  // list.  This field is a member of that oneof.  Extensions of a oneof should
    +  // not set this since the oneof to which they belong will be inferred based
    +  // on the extension range containing the extension's field number.
    +  optional int32 oneof_index = 9;
    +
    +  optional FieldOptions options = 8;
    +}
    +
    +// Describes a oneof.
    +message OneofDescriptorProto {
    +  optional string name = 1;
    +}
    +
    +// Describes an enum type.
    +message EnumDescriptorProto {
    +  optional string name = 1;
    +
    +  repeated EnumValueDescriptorProto value = 2;
    +
    +  optional EnumOptions options = 3;
    +}
    +
    +// Describes a value within an enum.
    +message EnumValueDescriptorProto {
    +  optional string name = 1;
    +  optional int32 number = 2;
    +
    +  optional EnumValueOptions options = 3;
    +}
    +
    +// Describes a service.
    +message ServiceDescriptorProto {
    +  optional string name = 1;
    +  repeated MethodDescriptorProto method = 2;
    +
    +  optional ServiceOptions options = 3;
    +}
    +
    +// Describes a method of a service.
    +message MethodDescriptorProto {
    +  optional string name = 1;
    +
    +  // Input and output type names.  These are resolved in the same way as
    +  // FieldDescriptorProto.type_name, but must refer to a message type.
    +  optional string input_type = 2;
    +  optional string output_type = 3;
    +
    +  optional MethodOptions options = 4;
    +}
    +
    +
    +// ===================================================================
    +// Options
    +
    +// Each of the definitions above may have "options" attached.  These are
    +// just annotations which may cause code to be generated slightly differently
    +// or may contain hints for code that manipulates protocol messages.
    +//
    +// Clients may define custom options as extensions of the *Options messages.
    +// These extensions may not yet be known at parsing time, so the parser cannot
    +// store the values in them.  Instead it stores them in a field in the *Options
    +// message called uninterpreted_option. This field must have the same name
    +// across all *Options messages. We then use this field to populate the
    +// extensions when we build a descriptor, at which point all protos have been
    +// parsed and so all extensions are known.
    +//
    +// Extension numbers for custom options may be chosen as follows:
    +// * For options which will only be used within a single application or
    +//   organization, or for experimental options, use field numbers 50000
    +//   through 99999.  It is up to you to ensure that you do not use the
    +//   same number for multiple options.
    +// * For options which will be published and used publicly by multiple
    +//   independent entities, e-mail protobuf-global-extension-registry@google.com
    +//   to reserve extension numbers. Simply provide your project name (e.g.
    +//   Object-C plugin) and your porject website (if available) -- there's no need
    +//   to explain how you intend to use them. Usually you only need one extension
    +//   number. You can declare multiple options with only one extension number by
    +//   putting them in a sub-message. See the Custom Options section of the docs
    +//   for examples:
    +//   https://developers.google.com/protocol-buffers/docs/proto#options
    +//   If this turns out to be popular, a web service will be set up
    +//   to automatically assign option numbers.
    +
    +
    +message FileOptions {
    +
    +  // Sets the Java package where classes generated from this .proto will be
    +  // placed.  By default, the proto package is used, but this is often
    +  // inappropriate because proto packages do not normally start with backwards
    +  // domain names.
    +  optional string java_package = 1;
    +
    +
    +  // If set, all the classes from the .proto file are wrapped in a single
    +  // outer class with the given name.  This applies to both Proto1
    +  // (equivalent to the old "--one_java_file" option) and Proto2 (where
    +  // a .proto always translates to a single class, but you may want to
    +  // explicitly choose the class name).
    +  optional string java_outer_classname = 8;
    +
    +  // If set true, then the Java code generator will generate a separate .java
    +  // file for each top-level message, enum, and service defined in the .proto
    +  // file.  Thus, these types will *not* be nested inside the outer class
    +  // named by java_outer_classname.  However, the outer class will still be
    +  // generated to contain the file's getDescriptor() method as well as any
    +  // top-level extensions defined in the file.
    +  optional bool java_multiple_files = 10 [default=false];
    +
    +  // If set true, then the Java code generator will generate equals() and
    +  // hashCode() methods for all messages defined in the .proto file.
    +  // - In the full runtime, this is purely a speed optimization, as the
    +  // AbstractMessage base class includes reflection-based implementations of
    +  // these methods.
    +  //- In the lite runtime, setting this option changes the semantics of
    +  // equals() and hashCode() to more closely match those of the full runtime;
    +  // the generated methods compute their results based on field values rather
    +  // than object identity. (Implementations should not assume that hashcodes
    +  // will be consistent across runtimes or versions of the protocol compiler.)
    +  optional bool java_generate_equals_and_hash = 20 [default=false];
    +
    +  // If set true, then the Java2 code generator will generate code that
    +  // throws an exception whenever an attempt is made to assign a non-UTF-8
    +  // byte sequence to a string field.
    +  // Message reflection will do the same.
    +  // However, an extension field still accepts non-UTF-8 byte sequences.
    +  // This option has no effect on when used with the lite runtime.
    +  optional bool java_string_check_utf8 = 27 [default=false];
    +
    +
    +  // Generated classes can be optimized for speed or code size.
    +  enum OptimizeMode {
    +    SPEED = 1;        // Generate complete code for parsing, serialization,
    +                      // etc.
    +    CODE_SIZE = 2;    // Use ReflectionOps to implement these methods.
    +    LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
    +  }
    +  optional OptimizeMode optimize_for = 9 [default=SPEED];
    +
    +  // Sets the Go package where structs generated from this .proto will be
    +  // placed.  There is no default.
    +  optional string go_package = 11;
    +
    +
    +
    +  // Should generic services be generated in each language?  "Generic" services
    +  // are not specific to any particular RPC system.  They are generated by the
    +  // main code generators in each language (without additional plugins).
    +  // Generic services were the only kind of service generation supported by
    +  // early versions of proto2.
    +  //
    +  // Generic services are now considered deprecated in favor of using plugins
    +  // that generate code specific to your particular RPC system.  Therefore,
    +  // these default to false.  Old code which depends on generic services should
    +  // explicitly set them to true.
    +  optional bool cc_generic_services = 16 [default=false];
    +  optional bool java_generic_services = 17 [default=false];
    +  optional bool py_generic_services = 18 [default=false];
    +
    +  // Is this file deprecated?
    +  // Depending on the target platform, this can emit Deprecated annotations
    +  // for everything in the file, or it will be completely ignored; in the very
    +  // least, this is a formalization for deprecating files.
    +  optional bool deprecated = 23 [default=false];
    +
    +
    +  // The parser stores options it doesn't recognize here. See above.
    +  repeated UninterpretedOption uninterpreted_option = 999;
    +
    +  // Clients can define custom options in extensions of this message. See above.
    +  extensions 1000 to max;
    +}
    +
    +message MessageOptions {
    +  // Set true to use the old proto1 MessageSet wire format for extensions.
    +  // This is provided for backwards-compatibility with the MessageSet wire
    +  // format.  You should not use this for any other reason:  It's less
    +  // efficient, has fewer features, and is more complicated.
    +  //
    +  // The message must be defined exactly as follows:
    +  //   message Foo {
    +  //     option message_set_wire_format = true;
    +  //     extensions 4 to max;
    +  //   }
    +  // Note that the message cannot have any defined fields; MessageSets only
    +  // have extensions.
    +  //
    +  // All extensions of your type must be singular messages; e.g. they cannot
    +  // be int32s, enums, or repeated messages.
    +  //
    +  // Because this is an option, the above two restrictions are not enforced by
    +  // the protocol compiler.
    +  optional bool message_set_wire_format = 1 [default=false];
    +
    +  // Disables the generation of the standard "descriptor()" accessor, which can
    +  // conflict with a field of the same name.  This is meant to make migration
    +  // from proto1 easier; new code should avoid fields named "descriptor".
    +  optional bool no_standard_descriptor_accessor = 2 [default=false];
    +
    +  // Is this message deprecated?
    +  // Depending on the target platform, this can emit Deprecated annotations
    +  // for the message, or it will be completely ignored; in the very least,
    +  // this is a formalization for deprecating messages.
    +  optional bool deprecated = 3 [default=false];
    +
    +  // The parser stores options it doesn't recognize here. See above.
    +  repeated UninterpretedOption uninterpreted_option = 999;
    +
    +  // Clients can define custom options in extensions of this message. See above.
    +  extensions 1000 to max;
    +}
    +
    +message FieldOptions {
    +  // The ctype option instructs the C++ code generator to use a different
    +  // representation of the field than it normally would.  See the specific
    +  // options below.  This option is not yet implemented in the open source
    +  // release -- sorry, we'll try to include it in a future version!
    +  optional CType ctype = 1 [default = STRING];
    +  enum CType {
    +    // Default mode.
    +    STRING = 0;
    +
    +    CORD = 1;
    +
    +    STRING_PIECE = 2;
    +  }
    +  // The packed option can be enabled for repeated primitive fields to enable
    +  // a more efficient representation on the wire. Rather than repeatedly
    +  // writing the tag and type for each element, the entire array is encoded as
    +  // a single length-delimited blob.
    +  optional bool packed = 2;
    +
    +
    +
    +  // Should this field be parsed lazily?  Lazy applies only to message-type
    +  // fields.  It means that when the outer message is initially parsed, the
    +  // inner message's contents will not be parsed but instead stored in encoded
    +  // form.  The inner message will actually be parsed when it is first accessed.
    +  //
    +  // This is only a hint.  Implementations are free to choose whether to use
    +  // eager or lazy parsing regardless of the value of this option.  However,
    +  // setting this option true suggests that the protocol author believes that
    +  // using lazy parsing on this field is worth the additional bookkeeping
    +  // overhead typically needed to implement it.
    +  //
    +  // This option does not affect the public interface of any generated code;
    +  // all method signatures remain the same.  Furthermore, thread-safety of the
    +  // interface is not affected by this option; const methods remain safe to
    +  // call from multiple threads concurrently, while non-const methods continue
    +  // to require exclusive access.
    +  //
    +  //
    +  // Note that implementations may choose not to check required fields within
    +  // a lazy sub-message.  That is, calling IsInitialized() on the outher message
    +  // may return true even if the inner message has missing required fields.
    +  // This is necessary because otherwise the inner message would have to be
    +  // parsed in order to perform the check, defeating the purpose of lazy
    +  // parsing.  An implementation which chooses not to check required fields
    +  // must be consistent about it.  That is, for any particular sub-message, the
    +  // implementation must either *always* check its required fields, or *never*
    +  // check its required fields, regardless of whether or not the message has
    +  // been parsed.
    +  optional bool lazy = 5 [default=false];
    +
    +  // Is this field deprecated?
    +  // Depending on the target platform, this can emit Deprecated annotations
    +  // for accessors, or it will be completely ignored; in the very least, this
    +  // is a formalization for deprecating fields.
    +  optional bool deprecated = 3 [default=false];
    +
    +  // EXPERIMENTAL.  DO NOT USE.
    +  // For "map" fields, the name of the field in the enclosed type that
    +  // is the key for this map.  For example, suppose we have:
    +  //   message Item {
    +  //     required string name = 1;
    +  //     required string value = 2;
    +  //   }
    +  //   message Config {
    +  //     repeated Item items = 1 [experimental_map_key="name"];
    +  //   }
    +  // In this situation, the map key for Item will be set to "name".
    +  // TODO: Fully-implement this, then remove the "experimental_" prefix.
    +  optional string experimental_map_key = 9;
    +
    +  // For Google-internal migration only. Do not use.
    +  optional bool weak = 10 [default=false];
    +
    +
    +
    +  // The parser stores options it doesn't recognize here. See above.
    +  repeated UninterpretedOption uninterpreted_option = 999;
    +
    +  // Clients can define custom options in extensions of this message. See above.
    +  extensions 1000 to max;
    +}
    +
    +message EnumOptions {
    +
    +  // Set this option to true to allow mapping different tag names to the same
    +  // value.
    +  optional bool allow_alias = 2;
    +
    +  // Is this enum deprecated?
    +  // Depending on the target platform, this can emit Deprecated annotations
    +  // for the enum, or it will be completely ignored; in the very least, this
    +  // is a formalization for deprecating enums.
    +  optional bool deprecated = 3 [default=false];
    +
    +  // The parser stores options it doesn't recognize here. See above.
    +  repeated UninterpretedOption uninterpreted_option = 999;
    +
    +  // Clients can define custom options in extensions of this message. See above.
    +  extensions 1000 to max;
    +}
    +
    +message EnumValueOptions {
    +  // Is this enum value deprecated?
    +  // Depending on the target platform, this can emit Deprecated annotations
    +  // for the enum value, or it will be completely ignored; in the very least,
    +  // this is a formalization for deprecating enum values.
    +  optional bool deprecated = 1 [default=false];
    +
    +  // The parser stores options it doesn't recognize here. See above.
    +  repeated UninterpretedOption uninterpreted_option = 999;
    +
    +  // Clients can define custom options in extensions of this message. See above.
    +  extensions 1000 to max;
    +}
    +
    +message ServiceOptions {
    +
    +  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
    +  //   framework.  We apologize for hoarding these numbers to ourselves, but
    +  //   we were already using them long before we decided to release Protocol
    +  //   Buffers.
    +
    +  // Is this service deprecated?
    +  // Depending on the target platform, this can emit Deprecated annotations
    +  // for the service, or it will be completely ignored; in the very least,
    +  // this is a formalization for deprecating services.
    +  optional bool deprecated = 33 [default=false];
    +
    +  // The parser stores options it doesn't recognize here. See above.
    +  repeated UninterpretedOption uninterpreted_option = 999;
    +
    +  // Clients can define custom options in extensions of this message. See above.
    +  extensions 1000 to max;
    +}
    +
    +message MethodOptions {
    +
    +  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
    +  //   framework.  We apologize for hoarding these numbers to ourselves, but
    +  //   we were already using them long before we decided to release Protocol
    +  //   Buffers.
    +
    +  // Is this method deprecated?
    +  // Depending on the target platform, this can emit Deprecated annotations
    +  // for the method, or it will be completely ignored; in the very least,
    +  // this is a formalization for deprecating methods.
    +  optional bool deprecated = 33 [default=false];
    +
    +  // The parser stores options it doesn't recognize here. See above.
    +  repeated UninterpretedOption uninterpreted_option = 999;
    +
    +  // Clients can define custom options in extensions of this message. See above.
    +  extensions 1000 to max;
    +}
    +
    +
    +// A message representing a option the parser does not recognize. This only
    +// appears in options protos created by the compiler::Parser class.
    +// DescriptorPool resolves these when building Descriptor objects. Therefore,
    +// options protos in descriptor objects (e.g. returned by Descriptor::options(),
    +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
    +// in them.
    +message UninterpretedOption {
    +  // The name of the uninterpreted option.  Each string represents a segment in
    +  // a dot-separated name.  is_extension is true iff a segment represents an
    +  // extension (denoted with parentheses in options specs in .proto files).
    +  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
    +  // "foo.(bar.baz).qux".
    +  message NamePart {
    +    required string name_part = 1;
    +    required bool is_extension = 2;
    +  }
    +  repeated NamePart name = 2;
    +
    +  // The value of the uninterpreted option, in whatever type the tokenizer
    +  // identified it as during parsing. Exactly one of these should be set.
    +  optional string identifier_value = 3;
    +  optional uint64 positive_int_value = 4;
    +  optional int64 negative_int_value = 5;
    +  optional double double_value = 6;
    +  optional bytes string_value = 7;
    +  optional string aggregate_value = 8;
    +}
    +
    +// ===================================================================
    +// Optional source code info
    +
    +// Encapsulates information about the original source file from which a
    +// FileDescriptorProto was generated.
    +message SourceCodeInfo {
    +  // A Location identifies a piece of source code in a .proto file which
    +  // corresponds to a particular definition.  This information is intended
    +  // to be useful to IDEs, code indexers, documentation generators, and similar
    +  // tools.
    +  //
    +  // For example, say we have a file like:
    +  //   message Foo {
    +  //     optional string foo = 1;
    +  //   }
    +  // Let's look at just the field definition:
    +  //   optional string foo = 1;
    +  //   ^       ^^     ^^  ^  ^^^
    +  //   a       bc     de  f  ghi
    +  // We have the following locations:
    +  //   span   path               represents
    +  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
    +  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
    +  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
    +  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
    +  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
    +  //
    +  // Notes:
    +  // - A location may refer to a repeated field itself (i.e. not to any
    +  //   particular index within it).  This is used whenever a set of elements are
    +  //   logically enclosed in a single code segment.  For example, an entire
    +  //   extend block (possibly containing multiple extension definitions) will
    +  //   have an outer location whose path refers to the "extensions" repeated
    +  //   field without an index.
    +  // - Multiple locations may have the same path.  This happens when a single
    +  //   logical declaration is spread out across multiple places.  The most
    +  //   obvious example is the "extend" block again -- there may be multiple
    +  //   extend blocks in the same scope, each of which will have the same path.
    +  // - A location's span is not always a subset of its parent's span.  For
    +  //   example, the "extendee" of an extension declaration appears at the
    +  //   beginning of the "extend" block and is shared by all extensions within
    +  //   the block.
    +  // - Just because a location's span is a subset of some other location's span
    +  //   does not mean that it is a descendent.  For example, a "group" defines
    +  //   both a type and a field in a single declaration.  Thus, the locations
    +  //   corresponding to the type and field and their components will overlap.
    +  // - Code which tries to interpret locations should probably be designed to
    +  //   ignore those that it doesn't understand, as more types of locations could
    +  //   be recorded in the future.
    +  repeated Location location = 1;
    +  message Location {
    +    // Identifies which part of the FileDescriptorProto was defined at this
    +    // location.
    +    //
    +    // Each element is a field number or an index.  They form a path from
    +    // the root FileDescriptorProto to the place where the definition.  For
    +    // example, this path:
    +    //   [ 4, 3, 2, 7, 1 ]
    +    // refers to:
    +    //   file.message_type(3)  // 4, 3
    +    //       .field(7)         // 2, 7
    +    //       .name()           // 1
    +    // This is because FileDescriptorProto.message_type has field number 4:
    +    //   repeated DescriptorProto message_type = 4;
    +    // and DescriptorProto.field has field number 2:
    +    //   repeated FieldDescriptorProto field = 2;
    +    // and FieldDescriptorProto.name has field number 1:
    +    //   optional string name = 1;
    +    //
    +    // Thus, the above path gives the location of a field name.  If we removed
    +    // the last element:
    +    //   [ 4, 3, 2, 7 ]
    +    // this path refers to the whole field declaration (from the beginning
    +    // of the label to the terminating semicolon).
    +    repeated int32 path = 1 [packed=true];
    +
    +    // Always has exactly three or four elements: start line, start column,
    +    // end line (optional, otherwise assumed same as start line), end column.
    +    // These are packed into a single field for efficiency.  Note that line
    +    // and column numbers are zero-based -- typically you will want to add
    +    // 1 to each before displaying to a user.
    +    repeated int32 span = 2 [packed=true];
    +
    +    // If this SourceCodeInfo represents a complete declaration, these are any
    +    // comments appearing before and after the declaration which appear to be
    +    // attached to the declaration.
    +    //
    +    // A series of line comments appearing on consecutive lines, with no other
    +    // tokens appearing on those lines, will be treated as a single comment.
    +    //
    +    // Only the comment content is provided; comment markers (e.g. //) are
    +    // stripped out.  For block comments, leading whitespace and an asterisk
    +    // will be stripped from the beginning of each line other than the first.
    +    // Newlines are included in the output.
    +    //
    +    // Examples:
    +    //
    +    //   optional int32 foo = 1;  // Comment attached to foo.
    +    //   // Comment attached to bar.
    +    //   optional int32 bar = 2;
    +    //
    +    //   optional string baz = 3;
    +    //   // Comment attached to baz.
    +    //   // Another line attached to baz.
    +    //
    +    //   // Comment attached to qux.
    +    //   //
    +    //   // Another line attached to qux.
    +    //   optional double qux = 4;
    +    //
    +    //   optional string corge = 5;
    +    //   /* Block comment attached
    +    //    * to corge.  Leading asterisks
    +    //    * will be removed. */
    +    //   /* Block comment attached to
    +    //    * grault. */
    +    //   optional int32 grault = 6;
    +    optional string leading_comments = 3;
    +    optional string trailing_comments = 4;
    +  }
    +}
    diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc
    new file mode 100644
    index 000000000000..d024eab13a47
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc
    @@ -0,0 +1,543 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +DescriptorDatabase::~DescriptorDatabase() {}
    +
    +// ===================================================================
    +
    +template 
    +bool SimpleDescriptorDatabase::DescriptorIndex::AddFile(
    +    const FileDescriptorProto& file,
    +    Value value) {
    +  if (!InsertIfNotPresent(&by_name_, file.name(), value)) {
    +    GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name();
    +    return false;
    +  }
    +
    +  // We must be careful here -- calling file.package() if file.has_package() is
    +  // false could access an uninitialized static-storage variable if we are being
    +  // run at startup time.
    +  string path = file.has_package() ? file.package() : string();
    +  if (!path.empty()) path += '.';
    +
    +  for (int i = 0; i < file.message_type_size(); i++) {
    +    if (!AddSymbol(path + file.message_type(i).name(), value)) return false;
    +    if (!AddNestedExtensions(file.message_type(i), value)) return false;
    +  }
    +  for (int i = 0; i < file.enum_type_size(); i++) {
    +    if (!AddSymbol(path + file.enum_type(i).name(), value)) return false;
    +  }
    +  for (int i = 0; i < file.extension_size(); i++) {
    +    if (!AddSymbol(path + file.extension(i).name(), value)) return false;
    +    if (!AddExtension(file.extension(i), value)) return false;
    +  }
    +  for (int i = 0; i < file.service_size(); i++) {
    +    if (!AddSymbol(path + file.service(i).name(), value)) return false;
    +  }
    +
    +  return true;
    +}
    +
    +template 
    +bool SimpleDescriptorDatabase::DescriptorIndex::AddSymbol(
    +    const string& name, Value value) {
    +  // We need to make sure not to violate our map invariant.
    +
    +  // If the symbol name is invalid it could break our lookup algorithm (which
    +  // relies on the fact that '.' sorts before all other characters that are
    +  // valid in symbol names).
    +  if (!ValidateSymbolName(name)) {
    +    GOOGLE_LOG(ERROR) << "Invalid symbol name: " << name;
    +    return false;
    +  }
    +
    +  // Try to look up the symbol to make sure a super-symbol doesn't already
    +  // exist.
    +  typename map::iterator iter = FindLastLessOrEqual(name);
    +
    +  if (iter == by_symbol_.end()) {
    +    // Apparently the map is currently empty.  Just insert and be done with it.
    +    by_symbol_.insert(typename map::value_type(name, value));
    +    return true;
    +  }
    +
    +  if (IsSubSymbol(iter->first, name)) {
    +    GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing "
    +                  "symbol \"" << iter->first << "\".";
    +    return false;
    +  }
    +
    +  // OK, that worked.  Now we have to make sure that no symbol in the map is
    +  // a sub-symbol of the one we are inserting.  The only symbol which could
    +  // be so is the first symbol that is greater than the new symbol.  Since
    +  // |iter| points at the last symbol that is less than or equal, we just have
    +  // to increment it.
    +  ++iter;
    +
    +  if (iter != by_symbol_.end() && IsSubSymbol(name, iter->first)) {
    +    GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing "
    +                  "symbol \"" << iter->first << "\".";
    +    return false;
    +  }
    +
    +  // OK, no conflicts.
    +
    +  // Insert the new symbol using the iterator as a hint, the new entry will
    +  // appear immediately before the one the iterator is pointing at.
    +  by_symbol_.insert(iter, typename map::value_type(name, value));
    +
    +  return true;
    +}
    +
    +template 
    +bool SimpleDescriptorDatabase::DescriptorIndex::AddNestedExtensions(
    +    const DescriptorProto& message_type,
    +    Value value) {
    +  for (int i = 0; i < message_type.nested_type_size(); i++) {
    +    if (!AddNestedExtensions(message_type.nested_type(i), value)) return false;
    +  }
    +  for (int i = 0; i < message_type.extension_size(); i++) {
    +    if (!AddExtension(message_type.extension(i), value)) return false;
    +  }
    +  return true;
    +}
    +
    +template 
    +bool SimpleDescriptorDatabase::DescriptorIndex::AddExtension(
    +    const FieldDescriptorProto& field,
    +    Value value) {
    +  if (!field.extendee().empty() && field.extendee()[0] == '.') {
    +    // The extension is fully-qualified.  We can use it as a lookup key in
    +    // the by_symbol_ table.
    +    if (!InsertIfNotPresent(&by_extension_,
    +                            make_pair(field.extendee().substr(1),
    +                                      field.number()),
    +                            value)) {
    +      GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: "
    +                    "extend " << field.extendee() << " { "
    +                 << field.name() << " = " << field.number() << " }";
    +      return false;
    +    }
    +  } else {
    +    // Not fully-qualified.  We can't really do anything here, unfortunately.
    +    // We don't consider this an error, though, because the descriptor is
    +    // valid.
    +  }
    +  return true;
    +}
    +
    +template 
    +Value SimpleDescriptorDatabase::DescriptorIndex::FindFile(
    +    const string& filename) {
    +  return FindWithDefault(by_name_, filename, Value());
    +}
    +
    +template 
    +Value SimpleDescriptorDatabase::DescriptorIndex::FindSymbol(
    +    const string& name) {
    +  typename map::iterator iter = FindLastLessOrEqual(name);
    +
    +  return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ?
    +         iter->second : Value();
    +}
    +
    +template 
    +Value SimpleDescriptorDatabase::DescriptorIndex::FindExtension(
    +    const string& containing_type,
    +    int field_number) {
    +  return FindWithDefault(by_extension_,
    +                         make_pair(containing_type, field_number),
    +                         Value());
    +}
    +
    +template 
    +bool SimpleDescriptorDatabase::DescriptorIndex::FindAllExtensionNumbers(
    +    const string& containing_type,
    +    vector* output) {
    +  typename map, Value >::const_iterator it =
    +      by_extension_.lower_bound(make_pair(containing_type, 0));
    +  bool success = false;
    +
    +  for (; it != by_extension_.end() && it->first.first == containing_type;
    +       ++it) {
    +    output->push_back(it->first.second);
    +    success = true;
    +  }
    +
    +  return success;
    +}
    +
    +template 
    +typename map::iterator
    +SimpleDescriptorDatabase::DescriptorIndex::FindLastLessOrEqual(
    +    const string& name) {
    +  // Find the last key in the map which sorts less than or equal to the
    +  // symbol name.  Since upper_bound() returns the *first* key that sorts
    +  // *greater* than the input, we want the element immediately before that.
    +  typename map::iterator iter = by_symbol_.upper_bound(name);
    +  if (iter != by_symbol_.begin()) --iter;
    +  return iter;
    +}
    +
    +template 
    +bool SimpleDescriptorDatabase::DescriptorIndex::IsSubSymbol(
    +    const string& sub_symbol, const string& super_symbol) {
    +  return sub_symbol == super_symbol ||
    +         (HasPrefixString(super_symbol, sub_symbol) &&
    +             super_symbol[sub_symbol.size()] == '.');
    +}
    +
    +template 
    +bool SimpleDescriptorDatabase::DescriptorIndex::ValidateSymbolName(
    +    const string& name) {
    +  for (int i = 0; i < name.size(); i++) {
    +    // I don't trust ctype.h due to locales.  :(
    +    if (name[i] != '.' && name[i] != '_' &&
    +        (name[i] < '0' || name[i] > '9') &&
    +        (name[i] < 'A' || name[i] > 'Z') &&
    +        (name[i] < 'a' || name[i] > 'z')) {
    +      return false;
    +    }
    +  }
    +  return true;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +SimpleDescriptorDatabase::SimpleDescriptorDatabase() {}
    +SimpleDescriptorDatabase::~SimpleDescriptorDatabase() {
    +  STLDeleteElements(&files_to_delete_);
    +}
    +
    +bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) {
    +  FileDescriptorProto* new_file = new FileDescriptorProto;
    +  new_file->CopyFrom(file);
    +  return AddAndOwn(new_file);
    +}
    +
    +bool SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) {
    +  files_to_delete_.push_back(file);
    +  return index_.AddFile(*file, file);
    +}
    +
    +bool SimpleDescriptorDatabase::FindFileByName(
    +    const string& filename,
    +    FileDescriptorProto* output) {
    +  return MaybeCopy(index_.FindFile(filename), output);
    +}
    +
    +bool SimpleDescriptorDatabase::FindFileContainingSymbol(
    +    const string& symbol_name,
    +    FileDescriptorProto* output) {
    +  return MaybeCopy(index_.FindSymbol(symbol_name), output);
    +}
    +
    +bool SimpleDescriptorDatabase::FindFileContainingExtension(
    +    const string& containing_type,
    +    int field_number,
    +    FileDescriptorProto* output) {
    +  return MaybeCopy(index_.FindExtension(containing_type, field_number), output);
    +}
    +
    +bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
    +    const string& extendee_type,
    +    vector* output) {
    +  return index_.FindAllExtensionNumbers(extendee_type, output);
    +}
    +
    +
    +bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file,
    +                                         FileDescriptorProto* output) {
    +  if (file == NULL) return false;
    +  output->CopyFrom(*file);
    +  return true;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +EncodedDescriptorDatabase::EncodedDescriptorDatabase() {}
    +EncodedDescriptorDatabase::~EncodedDescriptorDatabase() {
    +  for (int i = 0; i < files_to_delete_.size(); i++) {
    +    operator delete(files_to_delete_[i]);
    +  }
    +}
    +
    +bool EncodedDescriptorDatabase::Add(
    +    const void* encoded_file_descriptor, int size) {
    +  FileDescriptorProto file;
    +  if (file.ParseFromArray(encoded_file_descriptor, size)) {
    +    return index_.AddFile(file, make_pair(encoded_file_descriptor, size));
    +  } else {
    +    GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to "
    +                  "EncodedDescriptorDatabase::Add().";
    +    return false;
    +  }
    +}
    +
    +bool EncodedDescriptorDatabase::AddCopy(
    +    const void* encoded_file_descriptor, int size) {
    +  void* copy = operator new(size);
    +  memcpy(copy, encoded_file_descriptor, size);
    +  files_to_delete_.push_back(copy);
    +  return Add(copy, size);
    +}
    +
    +bool EncodedDescriptorDatabase::FindFileByName(
    +    const string& filename,
    +    FileDescriptorProto* output) {
    +  return MaybeParse(index_.FindFile(filename), output);
    +}
    +
    +bool EncodedDescriptorDatabase::FindFileContainingSymbol(
    +    const string& symbol_name,
    +    FileDescriptorProto* output) {
    +  return MaybeParse(index_.FindSymbol(symbol_name), output);
    +}
    +
    +bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol(
    +    const string& symbol_name,
    +    string* output) {
    +  pair encoded_file = index_.FindSymbol(symbol_name);
    +  if (encoded_file.first == NULL) return false;
    +
    +  // Optimization:  The name should be the first field in the encoded message.
    +  //   Try to just read it directly.
    +  io::CodedInputStream input(reinterpret_cast(encoded_file.first),
    +                             encoded_file.second);
    +
    +  const uint32 kNameTag = internal::WireFormatLite::MakeTag(
    +      FileDescriptorProto::kNameFieldNumber,
    +      internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
    +
    +  if (input.ReadTag() == kNameTag) {
    +    // Success!
    +    return internal::WireFormatLite::ReadString(&input, output);
    +  } else {
    +    // Slow path.  Parse whole message.
    +    FileDescriptorProto file_proto;
    +    if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) {
    +      return false;
    +    }
    +    *output = file_proto.name();
    +    return true;
    +  }
    +}
    +
    +bool EncodedDescriptorDatabase::FindFileContainingExtension(
    +    const string& containing_type,
    +    int field_number,
    +    FileDescriptorProto* output) {
    +  return MaybeParse(index_.FindExtension(containing_type, field_number),
    +                    output);
    +}
    +
    +bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
    +    const string& extendee_type,
    +    vector* output) {
    +  return index_.FindAllExtensionNumbers(extendee_type, output);
    +}
    +
    +bool EncodedDescriptorDatabase::MaybeParse(
    +    pair encoded_file,
    +    FileDescriptorProto* output) {
    +  if (encoded_file.first == NULL) return false;
    +  return output->ParseFromArray(encoded_file.first, encoded_file.second);
    +}
    +
    +// ===================================================================
    +
    +DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool)
    +  : pool_(pool) {}
    +DescriptorPoolDatabase::~DescriptorPoolDatabase() {}
    +
    +bool DescriptorPoolDatabase::FindFileByName(
    +    const string& filename,
    +    FileDescriptorProto* output) {
    +  const FileDescriptor* file = pool_.FindFileByName(filename);
    +  if (file == NULL) return false;
    +  output->Clear();
    +  file->CopyTo(output);
    +  return true;
    +}
    +
    +bool DescriptorPoolDatabase::FindFileContainingSymbol(
    +    const string& symbol_name,
    +    FileDescriptorProto* output) {
    +  const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name);
    +  if (file == NULL) return false;
    +  output->Clear();
    +  file->CopyTo(output);
    +  return true;
    +}
    +
    +bool DescriptorPoolDatabase::FindFileContainingExtension(
    +    const string& containing_type,
    +    int field_number,
    +    FileDescriptorProto* output) {
    +  const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type);
    +  if (extendee == NULL) return false;
    +
    +  const FieldDescriptor* extension =
    +    pool_.FindExtensionByNumber(extendee, field_number);
    +  if (extension == NULL) return false;
    +
    +  output->Clear();
    +  extension->file()->CopyTo(output);
    +  return true;
    +}
    +
    +bool DescriptorPoolDatabase::FindAllExtensionNumbers(
    +    const string& extendee_type,
    +    vector* output) {
    +  const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type);
    +  if (extendee == NULL) return false;
    +
    +  vector extensions;
    +  pool_.FindAllExtensions(extendee, &extensions);
    +
    +  for (int i = 0; i < extensions.size(); ++i) {
    +    output->push_back(extensions[i]->number());
    +  }
    +
    +  return true;
    +}
    +
    +// ===================================================================
    +
    +MergedDescriptorDatabase::MergedDescriptorDatabase(
    +    DescriptorDatabase* source1,
    +    DescriptorDatabase* source2) {
    +  sources_.push_back(source1);
    +  sources_.push_back(source2);
    +}
    +MergedDescriptorDatabase::MergedDescriptorDatabase(
    +    const vector& sources)
    +  : sources_(sources) {}
    +MergedDescriptorDatabase::~MergedDescriptorDatabase() {}
    +
    +bool MergedDescriptorDatabase::FindFileByName(
    +    const string& filename,
    +    FileDescriptorProto* output) {
    +  for (int i = 0; i < sources_.size(); i++) {
    +    if (sources_[i]->FindFileByName(filename, output)) {
    +      return true;
    +    }
    +  }
    +  return false;
    +}
    +
    +bool MergedDescriptorDatabase::FindFileContainingSymbol(
    +    const string& symbol_name,
    +    FileDescriptorProto* output) {
    +  for (int i = 0; i < sources_.size(); i++) {
    +    if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) {
    +      // The symbol was found in source i.  However, if one of the previous
    +      // sources defines a file with the same name (which presumably doesn't
    +      // contain the symbol, since it wasn't found in that source), then we
    +      // must hide it from the caller.
    +      FileDescriptorProto temp;
    +      for (int j = 0; j < i; j++) {
    +        if (sources_[j]->FindFileByName(output->name(), &temp)) {
    +          // Found conflicting file in a previous source.
    +          return false;
    +        }
    +      }
    +      return true;
    +    }
    +  }
    +  return false;
    +}
    +
    +bool MergedDescriptorDatabase::FindFileContainingExtension(
    +    const string& containing_type,
    +    int field_number,
    +    FileDescriptorProto* output) {
    +  for (int i = 0; i < sources_.size(); i++) {
    +    if (sources_[i]->FindFileContainingExtension(
    +          containing_type, field_number, output)) {
    +      // The symbol was found in source i.  However, if one of the previous
    +      // sources defines a file with the same name (which presumably doesn't
    +      // contain the symbol, since it wasn't found in that source), then we
    +      // must hide it from the caller.
    +      FileDescriptorProto temp;
    +      for (int j = 0; j < i; j++) {
    +        if (sources_[j]->FindFileByName(output->name(), &temp)) {
    +          // Found conflicting file in a previous source.
    +          return false;
    +        }
    +      }
    +      return true;
    +    }
    +  }
    +  return false;
    +}
    +
    +bool MergedDescriptorDatabase::FindAllExtensionNumbers(
    +    const string& extendee_type,
    +    vector* output) {
    +  set merged_results;
    +  vector results;
    +  bool success = false;
    +
    +  for (int i = 0; i < sources_.size(); i++) {
    +    if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
    +      copy(results.begin(), results.end(),
    +           insert_iterator >(merged_results, merged_results.begin()));
    +      success = true;
    +    }
    +    results.clear();
    +  }
    +
    +  copy(merged_results.begin(), merged_results.end(),
    +       insert_iterator >(*output, output->end()));
    +
    +  return success;
    +}
    +
    +
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/descriptor_database.h b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.h
    new file mode 100644
    index 000000000000..934e4022be74
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/descriptor_database.h
    @@ -0,0 +1,369 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Interface for manipulating databases of descriptors.
    +
    +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
    +#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +// Defined in this file.
    +class DescriptorDatabase;
    +class SimpleDescriptorDatabase;
    +class EncodedDescriptorDatabase;
    +class DescriptorPoolDatabase;
    +class MergedDescriptorDatabase;
    +
    +// Abstract interface for a database of descriptors.
    +//
    +// This is useful if you want to create a DescriptorPool which loads
    +// descriptors on-demand from some sort of large database.  If the database
    +// is large, it may be inefficient to enumerate every .proto file inside it
    +// calling DescriptorPool::BuildFile() for each one.  Instead, a DescriptorPool
    +// can be created which wraps a DescriptorDatabase and only builds particular
    +// descriptors when they are needed.
    +class LIBPROTOBUF_EXPORT DescriptorDatabase {
    + public:
    +  inline DescriptorDatabase() {}
    +  virtual ~DescriptorDatabase();
    +
    +  // Find a file by file name.  Fills in in *output and returns true if found.
    +  // Otherwise, returns false, leaving the contents of *output undefined.
    +  virtual bool FindFileByName(const string& filename,
    +                              FileDescriptorProto* output) = 0;
    +
    +  // Find the file that declares the given fully-qualified symbol name.
    +  // If found, fills in *output and returns true, otherwise returns false
    +  // and leaves *output undefined.
    +  virtual bool FindFileContainingSymbol(const string& symbol_name,
    +                                        FileDescriptorProto* output) = 0;
    +
    +  // Find the file which defines an extension extending the given message type
    +  // with the given field number.  If found, fills in *output and returns true,
    +  // otherwise returns false and leaves *output undefined.  containing_type
    +  // must be a fully-qualified type name.
    +  virtual bool FindFileContainingExtension(const string& containing_type,
    +                                           int field_number,
    +                                           FileDescriptorProto* output) = 0;
    +
    +  // Finds the tag numbers used by all known extensions of
    +  // extendee_type, and appends them to output in an undefined
    +  // order. This method is best-effort: it's not guaranteed that the
    +  // database will find all extensions, and it's not guaranteed that
    +  // FindFileContainingExtension will return true on all of the found
    +  // numbers. Returns true if the search was successful, otherwise
    +  // returns false and leaves output unchanged.
    +  //
    +  // This method has a default implementation that always returns
    +  // false.
    +  virtual bool FindAllExtensionNumbers(const string& /* extendee_type */,
    +                                       vector* /* output */) {
    +    return false;
    +  }
    +
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
    +};
    +
    +// A DescriptorDatabase into which you can insert files manually.
    +//
    +// FindFileContainingSymbol() is fully-implemented.  When you add a file, its
    +// symbols will be indexed for this purpose.  Note that the implementation
    +// may return false positives, but only if it isn't possible for the symbol
    +// to be defined in any other file.  In particular, if a file defines a symbol
    +// "Foo", then searching for "Foo.[anything]" will match that file.  This way,
    +// the database does not need to aggressively index all children of a symbol.
    +//
    +// FindFileContainingExtension() is mostly-implemented.  It works if and only
    +// if the original FieldDescriptorProto defining the extension has a
    +// fully-qualified type name in its "extendee" field (i.e. starts with a '.').
    +// If the extendee is a relative name, SimpleDescriptorDatabase will not
    +// attempt to resolve the type, so it will not know what type the extension is
    +// extending.  Therefore, calling FindFileContainingExtension() with the
    +// extension's containing type will never actually find that extension.  Note
    +// that this is an unlikely problem, as all FileDescriptorProtos created by the
    +// protocol compiler (as well as ones created by calling
    +// FileDescriptor::CopyTo()) will always use fully-qualified names for all
    +// types.  You only need to worry if you are constructing FileDescriptorProtos
    +// yourself, or are calling compiler::Parser directly.
    +class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
    + public:
    +  SimpleDescriptorDatabase();
    +  ~SimpleDescriptorDatabase();
    +
    +  // Adds the FileDescriptorProto to the database, making a copy.  The object
    +  // can be deleted after Add() returns.  Returns false if the file conflicted
    +  // with a file already in the database, in which case an error will have
    +  // been written to GOOGLE_LOG(ERROR).
    +  bool Add(const FileDescriptorProto& file);
    +
    +  // Adds the FileDescriptorProto to the database and takes ownership of it.
    +  bool AddAndOwn(const FileDescriptorProto* file);
    +
    +  // implements DescriptorDatabase -----------------------------------
    +  bool FindFileByName(const string& filename,
    +                      FileDescriptorProto* output);
    +  bool FindFileContainingSymbol(const string& symbol_name,
    +                                FileDescriptorProto* output);
    +  bool FindFileContainingExtension(const string& containing_type,
    +                                   int field_number,
    +                                   FileDescriptorProto* output);
    +  bool FindAllExtensionNumbers(const string& extendee_type,
    +                               vector* output);
    +
    + private:
    +  // So that it can use DescriptorIndex.
    +  friend class EncodedDescriptorDatabase;
    +
    +  // An index mapping file names, symbol names, and extension numbers to
    +  // some sort of values.
    +  template 
    +  class DescriptorIndex {
    +   public:
    +    // Helpers to recursively add particular descriptors and all their contents
    +    // to the index.
    +    bool AddFile(const FileDescriptorProto& file,
    +                 Value value);
    +    bool AddSymbol(const string& name, Value value);
    +    bool AddNestedExtensions(const DescriptorProto& message_type,
    +                             Value value);
    +    bool AddExtension(const FieldDescriptorProto& field,
    +                      Value value);
    +
    +    Value FindFile(const string& filename);
    +    Value FindSymbol(const string& name);
    +    Value FindExtension(const string& containing_type, int field_number);
    +    bool FindAllExtensionNumbers(const string& containing_type,
    +                                 vector* output);
    +
    +   private:
    +    map by_name_;
    +    map by_symbol_;
    +    map, Value> by_extension_;
    +
    +    // Invariant:  The by_symbol_ map does not contain any symbols which are
    +    // prefixes of other symbols in the map.  For example, "foo.bar" is a
    +    // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz").
    +    //
    +    // This invariant is important because it means that given a symbol name,
    +    // we can find a key in the map which is a prefix of the symbol in O(lg n)
    +    // time, and we know that there is at most one such key.
    +    //
    +    // The prefix lookup algorithm works like so:
    +    // 1) Find the last key in the map which is less than or equal to the
    +    //    search key.
    +    // 2) If the found key is a prefix of the search key, then return it.
    +    //    Otherwise, there is no match.
    +    //
    +    // I am sure this algorithm has been described elsewhere, but since I
    +    // wasn't able to find it quickly I will instead prove that it works
    +    // myself.  The key to the algorithm is that if a match exists, step (1)
    +    // will find it.  Proof:
    +    // 1) Define the "search key" to be the key we are looking for, the "found
    +    //    key" to be the key found in step (1), and the "match key" to be the
    +    //    key which actually matches the serach key (i.e. the key we're trying
    +    //    to find).
    +    // 2) The found key must be less than or equal to the search key by
    +    //    definition.
    +    // 3) The match key must also be less than or equal to the search key
    +    //    (because it is a prefix).
    +    // 4) The match key cannot be greater than the found key, because if it
    +    //    were, then step (1) of the algorithm would have returned the match
    +    //    key instead (since it finds the *greatest* key which is less than or
    +    //    equal to the search key).
    +    // 5) Therefore, the found key must be between the match key and the search
    +    //    key, inclusive.
    +    // 6) Since the search key must be a sub-symbol of the match key, if it is
    +    //    not equal to the match key, then search_key[match_key.size()] must
    +    //    be '.'.
    +    // 7) Since '.' sorts before any other character that is valid in a symbol
    +    //    name, then if the found key is not equal to the match key, then
    +    //    found_key[match_key.size()] must also be '.', because any other value
    +    //    would make it sort after the search key.
    +    // 8) Therefore, if the found key is not equal to the match key, then the
    +    //    found key must be a sub-symbol of the match key.  However, this would
    +    //    contradict our map invariant which says that no symbol in the map is
    +    //    a sub-symbol of any other.
    +    // 9) Therefore, the found key must match the match key.
    +    //
    +    // The above proof assumes the match key exists.  In the case that the
    +    // match key does not exist, then step (1) will return some other symbol.
    +    // That symbol cannot be a super-symbol of the search key since if it were,
    +    // then it would be a match, and we're assuming the match key doesn't exist.
    +    // Therefore, step 2 will correctly return no match.
    +
    +    // Find the last entry in the by_symbol_ map whose key is less than or
    +    // equal to the given name.
    +    typename map::iterator FindLastLessOrEqual(
    +        const string& name);
    +
    +    // True if either the arguments are equal or super_symbol identifies a
    +    // parent symbol of sub_symbol (e.g. "foo.bar" is a parent of
    +    // "foo.bar.baz", but not a parent of "foo.barbaz").
    +    bool IsSubSymbol(const string& sub_symbol, const string& super_symbol);
    +
    +    // Returns true if and only if all characters in the name are alphanumerics,
    +    // underscores, or periods.
    +    bool ValidateSymbolName(const string& name);
    +  };
    +
    +
    +  DescriptorIndex index_;
    +  vector files_to_delete_;
    +
    +  // If file is non-NULL, copy it into *output and return true, otherwise
    +  // return false.
    +  bool MaybeCopy(const FileDescriptorProto* file,
    +                 FileDescriptorProto* output);
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase);
    +};
    +
    +// Very similar to SimpleDescriptorDatabase, but stores all the descriptors
    +// as raw bytes and generally tries to use as little memory as possible.
    +//
    +// The same caveats regarding FindFileContainingExtension() apply as with
    +// SimpleDescriptorDatabase.
    +class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
    + public:
    +  EncodedDescriptorDatabase();
    +  ~EncodedDescriptorDatabase();
    +
    +  // Adds the FileDescriptorProto to the database.  The descriptor is provided
    +  // in encoded form.  The database does not make a copy of the bytes, nor
    +  // does it take ownership; it's up to the caller to make sure the bytes
    +  // remain valid for the life of the database.  Returns false and logs an error
    +  // if the bytes are not a valid FileDescriptorProto or if the file conflicted
    +  // with a file already in the database.
    +  bool Add(const void* encoded_file_descriptor, int size);
    +
    +  // Like Add(), but makes a copy of the data, so that the caller does not
    +  // need to keep it around.
    +  bool AddCopy(const void* encoded_file_descriptor, int size);
    +
    +  // Like FindFileContainingSymbol but returns only the name of the file.
    +  bool FindNameOfFileContainingSymbol(const string& symbol_name,
    +                                      string* output);
    +
    +  // implements DescriptorDatabase -----------------------------------
    +  bool FindFileByName(const string& filename,
    +                      FileDescriptorProto* output);
    +  bool FindFileContainingSymbol(const string& symbol_name,
    +                                FileDescriptorProto* output);
    +  bool FindFileContainingExtension(const string& containing_type,
    +                                   int field_number,
    +                                   FileDescriptorProto* output);
    +  bool FindAllExtensionNumbers(const string& extendee_type,
    +                               vector* output);
    +
    + private:
    +  SimpleDescriptorDatabase::DescriptorIndex > index_;
    +  vector files_to_delete_;
    +
    +  // If encoded_file.first is non-NULL, parse the data into *output and return
    +  // true, otherwise return false.
    +  bool MaybeParse(pair encoded_file,
    +                  FileDescriptorProto* output);
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase);
    +};
    +
    +// A DescriptorDatabase that fetches files from a given pool.
    +class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
    + public:
    +  DescriptorPoolDatabase(const DescriptorPool& pool);
    +  ~DescriptorPoolDatabase();
    +
    +  // implements DescriptorDatabase -----------------------------------
    +  bool FindFileByName(const string& filename,
    +                      FileDescriptorProto* output);
    +  bool FindFileContainingSymbol(const string& symbol_name,
    +                                FileDescriptorProto* output);
    +  bool FindFileContainingExtension(const string& containing_type,
    +                                   int field_number,
    +                                   FileDescriptorProto* output);
    +  bool FindAllExtensionNumbers(const string& extendee_type,
    +                               vector* output);
    +
    + private:
    +  const DescriptorPool& pool_;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase);
    +};
    +
    +// A DescriptorDatabase that wraps two or more others.  It first searches the
    +// first database and, if that fails, tries the second, and so on.
    +class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
    + public:
    +  // Merge just two databases.  The sources remain property of the caller.
    +  MergedDescriptorDatabase(DescriptorDatabase* source1,
    +                           DescriptorDatabase* source2);
    +  // Merge more than two databases.  The sources remain property of the caller.
    +  // The vector may be deleted after the constructor returns but the
    +  // DescriptorDatabases need to stick around.
    +  MergedDescriptorDatabase(const vector& sources);
    +  ~MergedDescriptorDatabase();
    +
    +  // implements DescriptorDatabase -----------------------------------
    +  bool FindFileByName(const string& filename,
    +                      FileDescriptorProto* output);
    +  bool FindFileContainingSymbol(const string& symbol_name,
    +                                FileDescriptorProto* output);
    +  bool FindFileContainingExtension(const string& containing_type,
    +                                   int field_number,
    +                                   FileDescriptorProto* output);
    +  // Merges the results of calling all databases. Returns true iff any
    +  // of the databases returned true.
    +  bool FindAllExtensionNumbers(const string& extendee_type,
    +                               vector* output);
    +
    +
    + private:
    +  vector sources_;
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
    +};
    +
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc
    new file mode 100644
    index 000000000000..4cca98691bfb
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc
    @@ -0,0 +1,764 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// DynamicMessage is implemented by constructing a data structure which
    +// has roughly the same memory layout as a generated message would have.
    +// Then, we use GeneratedMessageReflection to implement our reflection
    +// interface.  All the other operations we need to implement (e.g.
    +// parsing, copying, etc.) are already implemented in terms of
    +// Reflection, so the rest is easy.
    +//
    +// The up side of this strategy is that it's very efficient.  We don't
    +// need to use hash_maps or generic representations of fields.  The
    +// down side is that this is a low-level memory management hack which
    +// can be tricky to get right.
    +//
    +// As mentioned in the header, we only expose a DynamicMessageFactory
    +// publicly, not the DynamicMessage class itself.  This is because
    +// GenericMessageReflection wants to have a pointer to a "default"
    +// copy of the class, with all fields initialized to their default
    +// values.  We only want to construct one of these per message type,
    +// so DynamicMessageFactory stores a cache of default messages for
    +// each type it sees (each unique Descriptor pointer).  The code
    +// refers to the "default" copy of the class as the "prototype".
    +//
    +// Note on memory allocation:  This module often calls "operator new()"
    +// to allocate untyped memory, rather than calling something like
    +// "new uint8[]".  This is because "operator new()" means "Give me some
    +// space which I can use as I please." while "new uint8[]" means "Give
    +// me an array of 8-bit integers.".  In practice, the later may return
    +// a pointer that is not aligned correctly for general use.  I believe
    +// Item 8 of "More Effective C++" discusses this in more detail, though
    +// I don't have the book on me right now so I'm not sure.
    +
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +using internal::WireFormat;
    +using internal::ExtensionSet;
    +using internal::GeneratedMessageReflection;
    +
    +
    +// ===================================================================
    +// Some helper tables and functions...
    +
    +namespace {
    +
    +// Compute the byte size of the in-memory representation of the field.
    +int FieldSpaceUsed(const FieldDescriptor* field) {
    +  typedef FieldDescriptor FD;  // avoid line wrapping
    +  if (field->label() == FD::LABEL_REPEATED) {
    +    switch (field->cpp_type()) {
    +      case FD::CPPTYPE_INT32  : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_INT64  : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_UINT32 : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_UINT64 : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_DOUBLE : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_FLOAT  : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_BOOL   : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_ENUM   : return sizeof(RepeatedField);
    +      case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField);
    +
    +      case FD::CPPTYPE_STRING:
    +        switch (field->options().ctype()) {
    +          default:  // TODO(kenton):  Support other string reps.
    +          case FieldOptions::STRING:
    +            return sizeof(RepeatedPtrField);
    +        }
    +        break;
    +    }
    +  } else {
    +    switch (field->cpp_type()) {
    +      case FD::CPPTYPE_INT32  : return sizeof(int32   );
    +      case FD::CPPTYPE_INT64  : return sizeof(int64   );
    +      case FD::CPPTYPE_UINT32 : return sizeof(uint32  );
    +      case FD::CPPTYPE_UINT64 : return sizeof(uint64  );
    +      case FD::CPPTYPE_DOUBLE : return sizeof(double  );
    +      case FD::CPPTYPE_FLOAT  : return sizeof(float   );
    +      case FD::CPPTYPE_BOOL   : return sizeof(bool    );
    +      case FD::CPPTYPE_ENUM   : return sizeof(int     );
    +
    +      case FD::CPPTYPE_MESSAGE:
    +        return sizeof(Message*);
    +
    +      case FD::CPPTYPE_STRING:
    +        switch (field->options().ctype()) {
    +          default:  // TODO(kenton):  Support other string reps.
    +          case FieldOptions::STRING:
    +            return sizeof(string*);
    +        }
    +        break;
    +    }
    +  }
    +
    +  GOOGLE_LOG(DFATAL) << "Can't get here.";
    +  return 0;
    +}
    +
    +// Compute the byte size of in-memory representation of the oneof fields
    +// in default oneof instance.
    +int OneofFieldSpaceUsed(const FieldDescriptor* field) {
    +  typedef FieldDescriptor FD;  // avoid line wrapping
    +  switch (field->cpp_type()) {
    +    case FD::CPPTYPE_INT32  : return sizeof(int32   );
    +    case FD::CPPTYPE_INT64  : return sizeof(int64   );
    +    case FD::CPPTYPE_UINT32 : return sizeof(uint32  );
    +    case FD::CPPTYPE_UINT64 : return sizeof(uint64  );
    +    case FD::CPPTYPE_DOUBLE : return sizeof(double  );
    +    case FD::CPPTYPE_FLOAT  : return sizeof(float   );
    +    case FD::CPPTYPE_BOOL   : return sizeof(bool    );
    +    case FD::CPPTYPE_ENUM   : return sizeof(int     );
    +
    +    case FD::CPPTYPE_MESSAGE:
    +      return sizeof(Message*);
    +
    +    case FD::CPPTYPE_STRING:
    +      switch (field->options().ctype()) {
    +        default:
    +        case FieldOptions::STRING:
    +          return sizeof(string*);
    +      }
    +      break;
    +  }
    +
    +  GOOGLE_LOG(DFATAL) << "Can't get here.";
    +  return 0;
    +}
    +
    +inline int DivideRoundingUp(int i, int j) {
    +  return (i + (j - 1)) / j;
    +}
    +
    +static const int kSafeAlignment = sizeof(uint64);
    +static const int kMaxOneofUnionSize = sizeof(uint64);
    +
    +inline int AlignTo(int offset, int alignment) {
    +  return DivideRoundingUp(offset, alignment) * alignment;
    +}
    +
    +// Rounds the given byte offset up to the next offset aligned such that any
    +// type may be stored at it.
    +inline int AlignOffset(int offset) {
    +  return AlignTo(offset, kSafeAlignment);
    +}
    +
    +#define bitsizeof(T) (sizeof(T) * 8)
    +
    +}  // namespace
    +
    +// ===================================================================
    +
    +class DynamicMessage : public Message {
    + public:
    +  struct TypeInfo {
    +    int size;
    +    int has_bits_offset;
    +    int oneof_case_offset;
    +    int unknown_fields_offset;
    +    int extensions_offset;
    +
    +    // Not owned by the TypeInfo.
    +    DynamicMessageFactory* factory;  // The factory that created this object.
    +    const DescriptorPool* pool;      // The factory's DescriptorPool.
    +    const Descriptor* type;          // Type of this DynamicMessage.
    +
    +    // Warning:  The order in which the following pointers are defined is
    +    //   important (the prototype must be deleted *before* the offsets).
    +    scoped_array offsets;
    +    scoped_ptr reflection;
    +    // Don't use a scoped_ptr to hold the prototype: the destructor for
    +    // DynamicMessage needs to know whether it is the prototype, and does so by
    +    // looking back at this field. This would assume details about the
    +    // implementation of scoped_ptr.
    +    const DynamicMessage* prototype;
    +    void* default_oneof_instance;
    +
    +    TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {}
    +
    +    ~TypeInfo() {
    +      delete prototype;
    +      operator delete(default_oneof_instance);
    +    }
    +  };
    +
    +  DynamicMessage(const TypeInfo* type_info);
    +  ~DynamicMessage();
    +
    +  // Called on the prototype after construction to initialize message fields.
    +  void CrossLinkPrototypes();
    +
    +  // implements Message ----------------------------------------------
    +
    +  Message* New() const;
    +
    +  int GetCachedSize() const;
    +  void SetCachedSize(int size) const;
    +
    +  Metadata GetMetadata() const;
    +
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
    +
    +  inline bool is_prototype() const {
    +    return type_info_->prototype == this ||
    +           // If type_info_->prototype is NULL, then we must be constructing
    +           // the prototype now, which means we must be the prototype.
    +           type_info_->prototype == NULL;
    +  }
    +
    +  inline void* OffsetToPointer(int offset) {
    +    return reinterpret_cast(this) + offset;
    +  }
    +  inline const void* OffsetToPointer(int offset) const {
    +    return reinterpret_cast(this) + offset;
    +  }
    +
    +  const TypeInfo* type_info_;
    +
    +  // TODO(kenton):  Make this an atomic when C++ supports it.
    +  mutable int cached_byte_size_;
    +};
    +
    +DynamicMessage::DynamicMessage(const TypeInfo* type_info)
    +  : type_info_(type_info),
    +    cached_byte_size_(0) {
    +  // We need to call constructors for various fields manually and set
    +  // default values where appropriate.  We use placement new to call
    +  // constructors.  If you haven't heard of placement new, I suggest Googling
    +  // it now.  We use placement new even for primitive types that don't have
    +  // constructors for consistency.  (In theory, placement new should be used
    +  // any time you are trying to convert untyped memory to typed memory, though
    +  // in practice that's not strictly necessary for types that don't have a
    +  // constructor.)
    +
    +  const Descriptor* descriptor = type_info_->type;
    +
    +  // Initialize oneof cases.
    +  for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) {
    +    new(OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i))
    +        uint32(0);
    +  }
    +
    +  new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet;
    +
    +  if (type_info_->extensions_offset != -1) {
    +    new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet;
    +  }
    +
    +  for (int i = 0; i < descriptor->field_count(); i++) {
    +    const FieldDescriptor* field = descriptor->field(i);
    +    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
    +    if (field->containing_oneof()) {
    +      continue;
    +    }
    +    switch (field->cpp_type()) {
    +#define HANDLE_TYPE(CPPTYPE, TYPE)                                           \
    +      case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
    +        if (!field->is_repeated()) {                                         \
    +          new(field_ptr) TYPE(field->default_value_##TYPE());                \
    +        } else {                                                             \
    +          new(field_ptr) RepeatedField();                              \
    +        }                                                                    \
    +        break;
    +
    +      HANDLE_TYPE(INT32 , int32 );
    +      HANDLE_TYPE(INT64 , int64 );
    +      HANDLE_TYPE(UINT32, uint32);
    +      HANDLE_TYPE(UINT64, uint64);
    +      HANDLE_TYPE(DOUBLE, double);
    +      HANDLE_TYPE(FLOAT , float );
    +      HANDLE_TYPE(BOOL  , bool  );
    +#undef HANDLE_TYPE
    +
    +      case FieldDescriptor::CPPTYPE_ENUM:
    +        if (!field->is_repeated()) {
    +          new(field_ptr) int(field->default_value_enum()->number());
    +        } else {
    +          new(field_ptr) RepeatedField();
    +        }
    +        break;
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +        switch (field->options().ctype()) {
    +          default:  // TODO(kenton):  Support other string reps.
    +          case FieldOptions::STRING:
    +            if (!field->is_repeated()) {
    +              if (is_prototype()) {
    +                new(field_ptr) const string*(&field->default_value_string());
    +              } else {
    +                string* default_value =
    +                  *reinterpret_cast(
    +                    type_info_->prototype->OffsetToPointer(
    +                      type_info_->offsets[i]));
    +                new(field_ptr) string*(default_value);
    +              }
    +            } else {
    +              new(field_ptr) RepeatedPtrField();
    +            }
    +            break;
    +        }
    +        break;
    +
    +      case FieldDescriptor::CPPTYPE_MESSAGE: {
    +        if (!field->is_repeated()) {
    +          new(field_ptr) Message*(NULL);
    +        } else {
    +          new(field_ptr) RepeatedPtrField();
    +        }
    +        break;
    +      }
    +    }
    +  }
    +}
    +
    +DynamicMessage::~DynamicMessage() {
    +  const Descriptor* descriptor = type_info_->type;
    +
    +  reinterpret_cast(
    +    OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet();
    +
    +  if (type_info_->extensions_offset != -1) {
    +    reinterpret_cast(
    +      OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet();
    +  }
    +
    +  // We need to manually run the destructors for repeated fields and strings,
    +  // just as we ran their constructors in the the DynamicMessage constructor.
    +  // We also need to manually delete oneof fields if it is set and is string
    +  // or message.
    +  // Additionally, if any singular embedded messages have been allocated, we
    +  // need to delete them, UNLESS we are the prototype message of this type,
    +  // in which case any embedded messages are other prototypes and shouldn't
    +  // be touched.
    +  for (int i = 0; i < descriptor->field_count(); i++) {
    +    const FieldDescriptor* field = descriptor->field(i);
    +    if (field->containing_oneof()) {
    +      void* field_ptr = OffsetToPointer(
    +          type_info_->oneof_case_offset
    +          + sizeof(uint32) * field->containing_oneof()->index());
    +      if (*(reinterpret_cast(field_ptr)) ==
    +          field->number()) {
    +        field_ptr = OffsetToPointer(type_info_->offsets[
    +            descriptor->field_count() + field->containing_oneof()->index()]);
    +        if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
    +          switch (field->options().ctype()) {
    +            default:
    +            case FieldOptions::STRING:
    +              delete *reinterpret_cast(field_ptr);
    +              break;
    +          }
    +        } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +            delete *reinterpret_cast(field_ptr);
    +        }
    +      }
    +      continue;
    +    }
    +    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
    +
    +    if (field->is_repeated()) {
    +      switch (field->cpp_type()) {
    +#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
    +        case FieldDescriptor::CPPTYPE_##UPPERCASE :                           \
    +          reinterpret_cast*>(field_ptr)              \
    +              ->~RepeatedField();                                  \
    +          break
    +
    +        HANDLE_TYPE( INT32,  int32);
    +        HANDLE_TYPE( INT64,  int64);
    +        HANDLE_TYPE(UINT32, uint32);
    +        HANDLE_TYPE(UINT64, uint64);
    +        HANDLE_TYPE(DOUBLE, double);
    +        HANDLE_TYPE( FLOAT,  float);
    +        HANDLE_TYPE(  BOOL,   bool);
    +        HANDLE_TYPE(  ENUM,    int);
    +#undef HANDLE_TYPE
    +
    +        case FieldDescriptor::CPPTYPE_STRING:
    +          switch (field->options().ctype()) {
    +            default:  // TODO(kenton):  Support other string reps.
    +            case FieldOptions::STRING:
    +              reinterpret_cast*>(field_ptr)
    +                  ->~RepeatedPtrField();
    +              break;
    +          }
    +          break;
    +
    +        case FieldDescriptor::CPPTYPE_MESSAGE:
    +          reinterpret_cast*>(field_ptr)
    +              ->~RepeatedPtrField();
    +          break;
    +      }
    +
    +    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
    +      switch (field->options().ctype()) {
    +        default:  // TODO(kenton):  Support other string reps.
    +        case FieldOptions::STRING: {
    +          string* ptr = *reinterpret_cast(field_ptr);
    +          if (ptr != &field->default_value_string()) {
    +            delete ptr;
    +          }
    +          break;
    +        }
    +      }
    +    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      if (!is_prototype()) {
    +        Message* message = *reinterpret_cast(field_ptr);
    +        if (message != NULL) {
    +          delete message;
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +void DynamicMessage::CrossLinkPrototypes() {
    +  // This should only be called on the prototype message.
    +  GOOGLE_CHECK(is_prototype());
    +
    +  DynamicMessageFactory* factory = type_info_->factory;
    +  const Descriptor* descriptor = type_info_->type;
    +
    +  // Cross-link default messages.
    +  for (int i = 0; i < descriptor->field_count(); i++) {
    +    const FieldDescriptor* field = descriptor->field(i);
    +    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
    +    if (field->containing_oneof()) {
    +      field_ptr = reinterpret_cast(
    +          type_info_->default_oneof_instance) + type_info_->offsets[i];
    +    }
    +
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
    +        !field->is_repeated()) {
    +      // For fields with message types, we need to cross-link with the
    +      // prototype for the field's type.
    +      // For singular fields, the field is just a pointer which should
    +      // point to the prototype.
    +      *reinterpret_cast(field_ptr) =
    +        factory->GetPrototypeNoLock(field->message_type());
    +    }
    +  }
    +}
    +
    +Message* DynamicMessage::New() const {
    +  void* new_base = operator new(type_info_->size);
    +  memset(new_base, 0, type_info_->size);
    +  return new(new_base) DynamicMessage(type_info_);
    +}
    +
    +int DynamicMessage::GetCachedSize() const {
    +  return cached_byte_size_;
    +}
    +
    +void DynamicMessage::SetCachedSize(int size) const {
    +  // This is theoretically not thread-compatible, but in practice it works
    +  // because if multiple threads write this simultaneously, they will be
    +  // writing the exact same value.
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  cached_byte_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +
    +Metadata DynamicMessage::GetMetadata() const {
    +  Metadata metadata;
    +  metadata.descriptor = type_info_->type;
    +  metadata.reflection = type_info_->reflection.get();
    +  return metadata;
    +}
    +
    +// ===================================================================
    +
    +struct DynamicMessageFactory::PrototypeMap {
    +  typedef hash_map Map;
    +  Map map_;
    +};
    +
    +DynamicMessageFactory::DynamicMessageFactory()
    +  : pool_(NULL), delegate_to_generated_factory_(false),
    +    prototypes_(new PrototypeMap) {
    +}
    +
    +DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
    +  : pool_(pool), delegate_to_generated_factory_(false),
    +    prototypes_(new PrototypeMap) {
    +}
    +
    +DynamicMessageFactory::~DynamicMessageFactory() {
    +  for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
    +       iter != prototypes_->map_.end(); ++iter) {
    +    DeleteDefaultOneofInstance(iter->second->type,
    +                               iter->second->offsets.get(),
    +                               iter->second->default_oneof_instance);
    +    delete iter->second;
    +  }
    +}
    +
    +const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
    +  MutexLock lock(&prototypes_mutex_);
    +  return GetPrototypeNoLock(type);
    +}
    +
    +const Message* DynamicMessageFactory::GetPrototypeNoLock(
    +    const Descriptor* type) {
    +  if (delegate_to_generated_factory_ &&
    +      type->file()->pool() == DescriptorPool::generated_pool()) {
    +    return MessageFactory::generated_factory()->GetPrototype(type);
    +  }
    +
    +  const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
    +  if (*target != NULL) {
    +    // Already exists.
    +    return (*target)->prototype;
    +  }
    +
    +  DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
    +  *target = type_info;
    +
    +  type_info->type = type;
    +  type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
    +  type_info->factory = this;
    +
    +  // We need to construct all the structures passed to
    +  // GeneratedMessageReflection's constructor.  This includes:
    +  // - A block of memory that contains space for all the message's fields.
    +  // - An array of integers indicating the byte offset of each field within
    +  //   this block.
    +  // - A big bitfield containing a bit for each field indicating whether
    +  //   or not that field is set.
    +
    +  // Compute size and offsets.
    +  int* offsets = new int[type->field_count() + type->oneof_decl_count()];
    +  type_info->offsets.reset(offsets);
    +
    +  // Decide all field offsets by packing in order.
    +  // We place the DynamicMessage object itself at the beginning of the allocated
    +  // space.
    +  int size = sizeof(DynamicMessage);
    +  size = AlignOffset(size);
    +
    +  // Next the has_bits, which is an array of uint32s.
    +  type_info->has_bits_offset = size;
    +  int has_bits_array_size =
    +    DivideRoundingUp(type->field_count(), bitsizeof(uint32));
    +  size += has_bits_array_size * sizeof(uint32);
    +  size = AlignOffset(size);
    +
    +  // The oneof_case, if any. It is an array of uint32s.
    +  if (type->oneof_decl_count() > 0) {
    +    type_info->oneof_case_offset = size;
    +    size += type->oneof_decl_count() * sizeof(uint32);
    +    size = AlignOffset(size);
    +  }
    +
    +  // The ExtensionSet, if any.
    +  if (type->extension_range_count() > 0) {
    +    type_info->extensions_offset = size;
    +    size += sizeof(ExtensionSet);
    +    size = AlignOffset(size);
    +  } else {
    +    // No extensions.
    +    type_info->extensions_offset = -1;
    +  }
    +
    +  // All the fields.
    +  for (int i = 0; i < type->field_count(); i++) {
    +    // Make sure field is aligned to avoid bus errors.
    +    // Oneof fields do not use any space.
    +    if (!type->field(i)->containing_oneof()) {
    +      int field_size = FieldSpaceUsed(type->field(i));
    +      size = AlignTo(size, min(kSafeAlignment, field_size));
    +      offsets[i] = size;
    +      size += field_size;
    +    }
    +  }
    +
    +  // The oneofs.
    +  for (int i = 0; i < type->oneof_decl_count(); i++) {
    +    size = AlignTo(size, kSafeAlignment);
    +    offsets[type->field_count() + i] = size;
    +    size += kMaxOneofUnionSize;
    +  }
    +
    +  // Add the UnknownFieldSet to the end.
    +  size = AlignOffset(size);
    +  type_info->unknown_fields_offset = size;
    +  size += sizeof(UnknownFieldSet);
    +
    +  // Align the final size to make sure no clever allocators think that
    +  // alignment is not necessary.
    +  size = AlignOffset(size);
    +  type_info->size = size;
    +
    +  // Allocate the prototype.
    +  void* base = operator new(size);
    +  memset(base, 0, size);
    +  DynamicMessage* prototype = new(base) DynamicMessage(type_info);
    +  type_info->prototype = prototype;
    +
    +  // Construct the reflection object.
    +  if (type->oneof_decl_count() > 0) {
    +    // Compute the size of default oneof instance and offsets of default
    +    // oneof fields.
    +    int oneof_size = 0;
    +    for (int i = 0; i < type->oneof_decl_count(); i++) {
    +      for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
    +        const FieldDescriptor* field = type->oneof_decl(i)->field(j);
    +        int field_size = OneofFieldSpaceUsed(field);
    +        oneof_size = AlignTo(oneof_size, min(kSafeAlignment, field_size));
    +        offsets[field->index()] = oneof_size;
    +        oneof_size += field_size;
    +      }
    +    }
    +    // Construct default oneof instance.
    +    type_info->default_oneof_instance = ::operator new(oneof_size);
    +    ConstructDefaultOneofInstance(type_info->type,
    +                                  type_info->offsets.get(),
    +                                  type_info->default_oneof_instance);
    +    type_info->reflection.reset(
    +        new GeneratedMessageReflection(
    +            type_info->type,
    +            type_info->prototype,
    +            type_info->offsets.get(),
    +            type_info->has_bits_offset,
    +            type_info->unknown_fields_offset,
    +            type_info->extensions_offset,
    +            type_info->default_oneof_instance,
    +            type_info->oneof_case_offset,
    +            type_info->pool,
    +            this,
    +            type_info->size));
    +  } else {
    +    type_info->reflection.reset(
    +        new GeneratedMessageReflection(
    +            type_info->type,
    +            type_info->prototype,
    +            type_info->offsets.get(),
    +            type_info->has_bits_offset,
    +            type_info->unknown_fields_offset,
    +            type_info->extensions_offset,
    +            type_info->pool,
    +            this,
    +            type_info->size));
    +  }
    +  // Cross link prototypes.
    +  prototype->CrossLinkPrototypes();
    +
    +  return prototype;
    +}
    +
    +void DynamicMessageFactory::ConstructDefaultOneofInstance(
    +    const Descriptor* type,
    +    const int offsets[],
    +    void* default_oneof_instance) {
    +  for (int i = 0; i < type->oneof_decl_count(); i++) {
    +    for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
    +      const FieldDescriptor* field = type->oneof_decl(i)->field(j);
    +      void* field_ptr = reinterpret_cast(
    +          default_oneof_instance) + offsets[field->index()];
    +      switch (field->cpp_type()) {
    +#define HANDLE_TYPE(CPPTYPE, TYPE)                                      \
    +        case FieldDescriptor::CPPTYPE_##CPPTYPE:                        \
    +          new(field_ptr) TYPE(field->default_value_##TYPE());           \
    +          break;
    +
    +        HANDLE_TYPE(INT32 , int32 );
    +        HANDLE_TYPE(INT64 , int64 );
    +        HANDLE_TYPE(UINT32, uint32);
    +        HANDLE_TYPE(UINT64, uint64);
    +        HANDLE_TYPE(DOUBLE, double);
    +        HANDLE_TYPE(FLOAT , float );
    +        HANDLE_TYPE(BOOL  , bool  );
    +#undef HANDLE_TYPE
    +
    +        case FieldDescriptor::CPPTYPE_ENUM:
    +          new(field_ptr) int(field->default_value_enum()->number());
    +          break;
    +        case FieldDescriptor::CPPTYPE_STRING:
    +          switch (field->options().ctype()) {
    +            default:
    +            case FieldOptions::STRING:
    +              if (field->has_default_value()) {
    +                new(field_ptr) const string*(&field->default_value_string());
    +              } else {
    +                new(field_ptr) string*(
    +                    const_cast(&internal::GetEmptyString()));
    +              }
    +              break;
    +          }
    +          break;
    +
    +        case FieldDescriptor::CPPTYPE_MESSAGE: {
    +          new(field_ptr) Message*(NULL);
    +          break;
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +void DynamicMessageFactory::DeleteDefaultOneofInstance(
    +    const Descriptor* type,
    +    const int offsets[],
    +    void* default_oneof_instance) {
    +  for (int i = 0; i < type->oneof_decl_count(); i++) {
    +    for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
    +      const FieldDescriptor* field = type->oneof_decl(i)->field(j);
    +      if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
    +        switch (field->options().ctype()) {
    +          default:
    +          case FieldOptions::STRING:
    +            break;
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/dynamic_message.h b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.h
    new file mode 100644
    index 000000000000..10ed70051e0b
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/dynamic_message.h
    @@ -0,0 +1,148 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Defines an implementation of Message which can emulate types which are not
    +// known at compile-time.
    +
    +#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
    +#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
    +
    +#include 
    +
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +// Defined in other files.
    +class Descriptor;        // descriptor.h
    +class DescriptorPool;    // descriptor.h
    +
    +// Constructs implementations of Message which can emulate types which are not
    +// known at compile-time.
    +//
    +// Sometimes you want to be able to manipulate protocol types that you don't
    +// know about at compile time.  It would be nice to be able to construct
    +// a Message object which implements the message type given by any arbitrary
    +// Descriptor.  DynamicMessage provides this.
    +//
    +// As it turns out, a DynamicMessage needs to construct extra
    +// information about its type in order to operate.  Most of this information
    +// can be shared between all DynamicMessages of the same type.  But, caching
    +// this information in some sort of global map would be a bad idea, since
    +// the cached information for a particular descriptor could outlive the
    +// descriptor itself.  To avoid this problem, DynamicMessageFactory
    +// encapsulates this "cache".  All DynamicMessages of the same type created
    +// from the same factory will share the same support data.  Any Descriptors
    +// used with a particular factory must outlive the factory.
    +class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
    + public:
    +  // Construct a DynamicMessageFactory that will search for extensions in
    +  // the DescriptorPool in which the extendee is defined.
    +  DynamicMessageFactory();
    +
    +  // Construct a DynamicMessageFactory that will search for extensions in
    +  // the given DescriptorPool.
    +  //
    +  // DEPRECATED:  Use CodedInputStream::SetExtensionRegistry() to tell the
    +  //   parser to look for extensions in an alternate pool.  However, note that
    +  //   this is almost never what you want to do.  Almost all users should use
    +  //   the zero-arg constructor.
    +  DynamicMessageFactory(const DescriptorPool* pool);
    +
    +  ~DynamicMessageFactory();
    +
    +  // Call this to tell the DynamicMessageFactory that if it is given a
    +  // Descriptor d for which:
    +  //   d->file()->pool() == DescriptorPool::generated_pool(),
    +  // then it should delegate to MessageFactory::generated_factory() instead
    +  // of constructing a dynamic implementation of the message.  In theory there
    +  // is no down side to doing this, so it may become the default in the future.
    +  void SetDelegateToGeneratedFactory(bool enable) {
    +    delegate_to_generated_factory_ = enable;
    +  }
    +
    +  // implements MessageFactory ---------------------------------------
    +
    +  // Given a Descriptor, constructs the default (prototype) Message of that
    +  // type.  You can then call that message's New() method to construct a
    +  // mutable message of that type.
    +  //
    +  // Calling this method twice with the same Descriptor returns the same
    +  // object.  The returned object remains property of the factory and will
    +  // be destroyed when the factory is destroyed.  Also, any objects created
    +  // by calling the prototype's New() method share some data with the
    +  // prototype, so these must be destroyed before the DynamicMessageFactory
    +  // is destroyed.
    +  //
    +  // The given descriptor must outlive the returned message, and hence must
    +  // outlive the DynamicMessageFactory.
    +  //
    +  // The method is thread-safe.
    +  const Message* GetPrototype(const Descriptor* type);
    +
    + private:
    +  const DescriptorPool* pool_;
    +  bool delegate_to_generated_factory_;
    +
    +  // This struct just contains a hash_map.  We can't #include  from
    +  // this header due to hacks needed for hash_map portability in the open source
    +  // release.  Namely, stubs/hash.h, which defines hash_map portably, is not a
    +  // public header (for good reason), but dynamic_message.h is, and public
    +  // headers may only #include other public headers.
    +  struct PrototypeMap;
    +  scoped_ptr prototypes_;
    +  mutable Mutex prototypes_mutex_;
    +
    +  friend class DynamicMessage;
    +  const Message* GetPrototypeNoLock(const Descriptor* type);
    +
    +  // Construct default oneof instance for reflection usage if oneof
    +  // is defined.
    +  static void ConstructDefaultOneofInstance(const Descriptor* type,
    +                                            const int offsets[],
    +                                            void* default_oneof_instance);
    +  // Delete default oneof instance. Called by ~DynamicMessageFactory.
    +  static void DeleteDefaultOneofInstance(const Descriptor* type,
    +                                         const int offsets[],
    +                                         void* default_oneof_instance);
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
    +};
    +
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/extension_set.cc b/toolkit/components/protobuf/src/google/protobuf/extension_set.cc
    similarity index 76%
    rename from toolkit/components/protobuf/google/protobuf/extension_set.cc
    rename to toolkit/components/protobuf/src/google/protobuf/extension_set.cc
    index ba70f365f643..274554b5f75f 100644
    --- a/toolkit/components/protobuf/google/protobuf/extension_set.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/extension_set.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -38,10 +38,9 @@
     #include 
     #include 
     #include 
    -#include 
     #include 
     #include 
    -#include 
    +#include 
     
     namespace google {
     namespace protobuf {
    @@ -58,6 +57,22 @@ inline WireFormatLite::CppType cpp_type(FieldType type) {
       return WireFormatLite::FieldTypeToCppType(real_type(type));
     }
     
    +inline bool is_packable(WireFormatLite::WireType type) {
    +  switch (type) {
    +    case WireFormatLite::WIRETYPE_VARINT:
    +    case WireFormatLite::WIRETYPE_FIXED64:
    +    case WireFormatLite::WIRETYPE_FIXED32:
    +      return true;
    +    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
    +    case WireFormatLite::WIRETYPE_START_GROUP:
    +    case WireFormatLite::WIRETYPE_END_GROUP:
    +      return false;
    +
    +    // Do not add a default statement. Let the compiler complain when someone
    +    // adds a new wire type.
    +  }
    +}
    +
     // Registry stuff.
     typedef hash_map,
                      ExtensionInfo> ExtensionRegistry;
    @@ -71,7 +86,7 @@ void DeleteRegistry() {
     
     void InitRegistry() {
       registry_ = new ExtensionRegistry;
    -  internal::OnShutdown(&DeleteRegistry);
    +  OnShutdown(&DeleteRegistry);
     }
     
     // This function is only called at startup, so there is no need for thread-
    @@ -180,6 +195,17 @@ bool ExtensionSet::Has(int number) const {
       return !iter->second.is_cleared;
     }
     
    +int ExtensionSet::NumExtensions() const {
    +  int result = 0;
    +  for (map::const_iterator iter = extensions_.begin();
    +       iter != extensions_.end(); ++iter) {
    +    if (!iter->second.is_cleared) {
    +      ++result;
    +    }
    +  }
    +  return result;
    +}
    +
     int ExtensionSet::ExtensionSize(int number) const {
       map::const_iterator iter = extensions_.find(number);
       if (iter == extensions_.end()) return false;
    @@ -293,6 +319,80 @@ PRIMITIVE_ACCESSORS(  BOOL,   bool,   Bool)
     
     #undef PRIMITIVE_ACCESSORS
     
    +const void* ExtensionSet::GetRawRepeatedField(int number,
    +                                              const void* default_value) const {
    +  map::const_iterator iter = extensions_.find(number);
    +  if (iter == extensions_.end()) {
    +    return default_value;
    +  }
    +  // We assume that all the RepeatedField<>* pointers have the same
    +  // size and alignment within the anonymous union in Extension.
    +  return iter->second.repeated_int32_value;
    +}
    +
    +void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
    +                                            bool packed,
    +                                            const FieldDescriptor* desc) {
    +  Extension* extension;
    +
    +  // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
    +  // extension.
    +  if (MaybeNewExtension(number, desc, &extension)) {
    +    extension->is_repeated = true;
    +    extension->type = field_type;
    +    extension->is_packed = packed;
    +
    +    switch (WireFormatLite::FieldTypeToCppType(
    +        static_cast(field_type))) {
    +      case WireFormatLite::CPPTYPE_INT32:
    +        extension->repeated_int32_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_INT64:
    +        extension->repeated_int64_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_UINT32:
    +        extension->repeated_uint32_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_UINT64:
    +        extension->repeated_uint64_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_DOUBLE:
    +        extension->repeated_double_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_FLOAT:
    +        extension->repeated_float_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_BOOL:
    +        extension->repeated_bool_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_ENUM:
    +        extension->repeated_enum_value = new RepeatedField();
    +        break;
    +      case WireFormatLite::CPPTYPE_STRING:
    +        extension->repeated_string_value = new RepeatedPtrField< ::std::string>();
    +        break;
    +      case WireFormatLite::CPPTYPE_MESSAGE:
    +        extension->repeated_message_value = new RepeatedPtrField();
    +        break;
    +    }
    +  }
    +
    +  // We assume that all the RepeatedField<>* pointers have the same
    +  // size and alignment within the anonymous union in Extension.
    +  return extension->repeated_int32_value;
    +}
    +
    +// Compatible version using old call signature. Does not create extensions when
    +// the don't already exist; instead, just GOOGLE_CHECK-fails.
    +void* ExtensionSet::MutableRawRepeatedField(int number) {
    +  map::iterator iter = extensions_.find(number);
    +  GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
    +  // We assume that all the RepeatedField<>* pointers have the same
    +  // size and alignment within the anonymous union in Extension.
    +  return iter->second.repeated_int32_value;
    +}
    +
    +
     // -------------------------------------------------------------------
     // Enums
     
    @@ -422,7 +522,11 @@ const MessageLite& ExtensionSet::GetMessage(
         return default_value;
       } else {
         GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
    -    return *iter->second.message_value;
    +    if (iter->second.is_lazy) {
    +      return iter->second.lazymessage_value->GetMessage(default_value);
    +    } else {
    +      return *iter->second.message_value;
    +    }
       }
     }
     
    @@ -439,12 +543,19 @@ MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
         extension->type = type;
         GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
         extension->is_repeated = false;
    +    extension->is_lazy = false;
         extension->message_value = prototype.New();
    +    extension->is_cleared = false;
    +    return extension->message_value;
       } else {
         GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
    +    extension->is_cleared = false;
    +    if (extension->is_lazy) {
    +      return extension->lazymessage_value->MutableMessage(prototype);
    +    } else {
    +      return extension->message_value;
    +    }
       }
    -  extension->is_cleared = false;
    -  return extension->message_value;
     }
     
     // Defined in extension_set_heavy.cc.
    @@ -452,6 +563,56 @@ MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
     //                                           const Descriptor* message_type,
     //                                           MessageFactory* factory)
     
    +void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
    +                                       const FieldDescriptor* descriptor,
    +                                       MessageLite* message) {
    +  if (message == NULL) {
    +    ClearExtension(number);
    +    return;
    +  }
    +  Extension* extension;
    +  if (MaybeNewExtension(number, descriptor, &extension)) {
    +    extension->type = type;
    +    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
    +    extension->is_repeated = false;
    +    extension->is_lazy = false;
    +    extension->message_value = message;
    +  } else {
    +    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
    +    if (extension->is_lazy) {
    +      extension->lazymessage_value->SetAllocatedMessage(message);
    +    } else {
    +      delete extension->message_value;
    +      extension->message_value = message;
    +    }
    +  }
    +  extension->is_cleared = false;
    +}
    +
    +MessageLite* ExtensionSet::ReleaseMessage(int number,
    +                                          const MessageLite& prototype) {
    +  map::iterator iter = extensions_.find(number);
    +  if (iter == extensions_.end()) {
    +    // Not present.  Return NULL.
    +    return NULL;
    +  } else {
    +    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
    +    MessageLite* ret = NULL;
    +    if (iter->second.is_lazy) {
    +      ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
    +      delete iter->second.lazymessage_value;
    +    } else {
    +      ret = iter->second.message_value;
    +    }
    +    extensions_.erase(number);
    +    return ret;
    +  }
    +}
    +
    +// Defined in extension_set_heavy.cc.
    +// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
    +//                                           MessageFactory* factory);
    +
     const MessageLite& ExtensionSet::GetRepeatedMessage(
         int number, int index) const {
       map::const_iterator iter = extensions_.find(number);
    @@ -484,7 +645,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
       // RepeatedPtrField does not know how to Add() since it cannot
       // allocate an abstract object, so we have to be tricky.
       MessageLite* result = extension->repeated_message_value
    -      ->AddFromCleared >();
    +      ->AddFromCleared >();
       if (result == NULL) {
         result = prototype.New();
         extension->repeated_message_value->AddAllocated(result);
    @@ -540,6 +701,16 @@ void ExtensionSet::RemoveLast(int number) {
       }
     }
     
    +MessageLite* ExtensionSet::ReleaseLast(int number) {
    +  map::iterator iter = extensions_.find(number);
    +  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
    +
    +  Extension* extension = &iter->second;
    +  GOOGLE_DCHECK(extension->is_repeated);
    +  GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
    +  return extension->repeated_message_value->ReleaseLast();
    +}
    +
     void ExtensionSet::SwapElements(int number, int index1, int index2) {
       map::iterator iter = extensions_.find(number);
       GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
    @@ -602,9 +773,11 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) {
           if (is_new) {
             // Extension did not already exist in set.
             extension->type = other_extension.type;
    +        extension->is_packed = other_extension.is_packed;
             extension->is_repeated = true;
           } else {
             GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
    +        GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
             GOOGLE_DCHECK(extension->is_repeated);
           }
     
    @@ -675,12 +848,55 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) {
                           *other_extension.string_value,
                           other_extension.descriptor);
                 break;
    -          case WireFormatLite::CPPTYPE_MESSAGE:
    -            MutableMessage(iter->first, other_extension.type,
    -                           *other_extension.message_value,
    -                           other_extension.descriptor)
    -              ->CheckTypeAndMergeFrom(*other_extension.message_value);
    +          case WireFormatLite::CPPTYPE_MESSAGE: {
    +            Extension* extension;
    +            bool is_new = MaybeNewExtension(iter->first,
    +                                            other_extension.descriptor,
    +                                            &extension);
    +            if (is_new) {
    +              extension->type = other_extension.type;
    +              extension->is_packed = other_extension.is_packed;
    +              extension->is_repeated = false;
    +              if (other_extension.is_lazy) {
    +                extension->is_lazy = true;
    +                extension->lazymessage_value =
    +                    other_extension.lazymessage_value->New();
    +                extension->lazymessage_value->MergeFrom(
    +                    *other_extension.lazymessage_value);
    +              } else {
    +                extension->is_lazy = false;
    +                extension->message_value =
    +                    other_extension.message_value->New();
    +                extension->message_value->CheckTypeAndMergeFrom(
    +                    *other_extension.message_value);
    +              }
    +            } else {
    +              GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
    +              GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
    +              GOOGLE_DCHECK(!extension->is_repeated);
    +              if (other_extension.is_lazy) {
    +                if (extension->is_lazy) {
    +                  extension->lazymessage_value->MergeFrom(
    +                      *other_extension.lazymessage_value);
    +                } else {
    +                  extension->message_value->CheckTypeAndMergeFrom(
    +                      other_extension.lazymessage_value->GetMessage(
    +                          *extension->message_value));
    +                }
    +              } else {
    +                if (extension->is_lazy) {
    +                  extension->lazymessage_value->MutableMessage(
    +                      *other_extension.message_value)->CheckTypeAndMergeFrom(
    +                          *other_extension.message_value);
    +                } else {
    +                  extension->message_value->CheckTypeAndMergeFrom(
    +                      *other_extension.message_value);
    +                }
    +              }
    +            }
    +            extension->is_cleared = false;
                 break;
    +          }
             }
           }
         }
    @@ -691,6 +907,36 @@ void ExtensionSet::Swap(ExtensionSet* x) {
       extensions_.swap(x->extensions_);
     }
     
    +void ExtensionSet::SwapExtension(ExtensionSet* other,
    +                                 int number) {
    +  if (this == other) return;
    +  map::iterator this_iter = extensions_.find(number);
    +  map::iterator other_iter = other->extensions_.find(number);
    +
    +  if (this_iter == extensions_.end() &&
    +      other_iter == other->extensions_.end()) {
    +    return;
    +  }
    +
    +  if (this_iter != extensions_.end() &&
    +      other_iter != other->extensions_.end()) {
    +    std::swap(this_iter->second, other_iter->second);
    +    return;
    +  }
    +
    +  if (this_iter == extensions_.end()) {
    +    extensions_.insert(make_pair(number, other_iter->second));
    +    other->extensions_.erase(number);
    +    return;
    +  }
    +
    +  if (other_iter == other->extensions_.end()) {
    +    other->extensions_.insert(make_pair(number, this_iter->second));
    +    extensions_.erase(number);
    +    return;
    +  }
    +}
    +
     bool ExtensionSet::IsInitialized() const {
       // Extensions are never required.  However, we need to check that all
       // embedded messages are initialized.
    @@ -706,7 +952,11 @@ bool ExtensionSet::IsInitialized() const {
             }
           } else {
             if (!extension.is_cleared) {
    -          if (!extension.message_value->IsInitialized()) return false;
    +          if (extension.is_lazy) {
    +            if (!extension.lazymessage_value->IsInitialized()) return false;
    +          } else {
    +            if (!extension.message_value->IsInitialized()) return false;
    +          }
             }
           }
         }
    @@ -715,27 +965,60 @@ bool ExtensionSet::IsInitialized() const {
       return true;
     }
     
    +bool ExtensionSet::FindExtensionInfoFromTag(
    +    uint32 tag, ExtensionFinder* extension_finder, int* field_number,
    +    ExtensionInfo* extension, bool* was_packed_on_wire) {
    +  *field_number = WireFormatLite::GetTagFieldNumber(tag);
    +  WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
    +  return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
    +                                          extension_finder, extension,
    +                                          was_packed_on_wire);
    +}
    +
    +bool ExtensionSet::FindExtensionInfoFromFieldNumber(
    +    int wire_type, int field_number, ExtensionFinder* extension_finder,
    +    ExtensionInfo* extension, bool* was_packed_on_wire) {
    +  if (!extension_finder->Find(field_number, extension)) {
    +    return false;
    +  }
    +
    +  WireFormatLite::WireType expected_wire_type =
    +      WireFormatLite::WireTypeForFieldType(real_type(extension->type));
    +
    +  // Check if this is a packed field.
    +  *was_packed_on_wire = false;
    +  if (extension->is_repeated &&
    +      wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
    +      is_packable(expected_wire_type)) {
    +    *was_packed_on_wire = true;
    +    return true;
    +  }
    +  // Otherwise the wire type must match.
    +  return expected_wire_type == wire_type;
    +}
    +
     bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
                                   ExtensionFinder* extension_finder,
                                   FieldSkipper* field_skipper) {
    -  int number = WireFormatLite::GetTagFieldNumber(tag);
    -  WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
    -
    +  int number;
    +  bool was_packed_on_wire;
       ExtensionInfo extension;
    -  bool is_unknown;
    -  if (!extension_finder->Find(number, &extension)) {
    -    is_unknown = true;
    -  } else if (extension.is_packed) {
    -    is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
    +  if (!FindExtensionInfoFromTag(
    +      tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
    +    return field_skipper->SkipField(input, tag);
       } else {
    -    WireFormatLite::WireType expected_wire_type =
    -        WireFormatLite::WireTypeForFieldType(real_type(extension.type));
    -    is_unknown = (wire_type != expected_wire_type);
    +    return ParseFieldWithExtensionInfo(
    +        number, was_packed_on_wire, extension, input, field_skipper);
       }
    +}
     
    -  if (is_unknown) {
    -    field_skipper->SkipField(input, tag);
    -  } else if (extension.is_packed) {
    +bool ExtensionSet::ParseFieldWithExtensionInfo(
    +    int number, bool was_packed_on_wire, const ExtensionInfo& extension,
    +    io::CodedInputStream* input,
    +    FieldSkipper* field_skipper) {
    +  // Explicitly not read extension.is_packed, instead check whether the field
    +  // was encoded in packed form on the wire.
    +  if (was_packed_on_wire) {
         uint32 size;
         if (!input->ReadVarint32(&size)) return false;
         io::CodedInputStream::Limit limit = input->PushLimit(size);
    @@ -749,7 +1032,8 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
                       CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(            \
                     input, &value)) return false;                                  \
               Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
    -                             true, value, extension.descriptor);               \
    +                             extension.is_packed, value,                       \
    +                             extension.descriptor);                            \
             }                                                                      \
             break
     
    @@ -775,8 +1059,8 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
                       input, &value)) return false;
               if (extension.enum_validity_check.func(
                       extension.enum_validity_check.arg, value)) {
    -            AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
    -                    extension.descriptor);
    +            AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
    +                    value, extension.descriptor);
               }
             }
             break;
    @@ -798,9 +1082,10 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
             if (!WireFormatLite::ReadPrimitive<                                    \
                     CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(              \
                    input, &value)) return false;                                   \
    -        if (extension.is_repeated) {                                          \
    +        if (extension.is_repeated) {                                           \
               Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
    -                             false, value, extension.descriptor);              \
    +                             extension.is_packed, value,                       \
    +                             extension.descriptor);                            \
             } else {                                                               \
               Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
                                  extension.descriptor);                            \
    @@ -832,7 +1117,7 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
               // Invalid value.  Treat as unknown.
               field_skipper->SkipUnknownEnum(number, value);
             } else if (extension.is_repeated) {
    -          AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
    +          AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
                       extension.descriptor);
             } else {
               SetEnum(number, WireFormatLite::TYPE_ENUM, value,
    @@ -852,8 +1137,8 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
     
           case WireFormatLite::TYPE_BYTES:  {
             string* value = extension.is_repeated ?
    -          AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
    -          MutableString(number, WireFormatLite::TYPE_STRING,
    +          AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
    +          MutableString(number, WireFormatLite::TYPE_BYTES,
                             extension.descriptor);
             if (!WireFormatLite::ReadBytes(input, value)) return false;
             break;
    @@ -891,125 +1176,24 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
       return ParseField(tag, input, &finder, &skipper);
     }
     
    +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
    +                              const MessageLite* containing_type,
    +                              io::CodedOutputStream* unknown_fields) {
    +  CodedOutputStreamFieldSkipper skipper(unknown_fields);
    +  GeneratedExtensionFinder finder(containing_type);
    +  return ParseField(tag, input, &finder, &skipper);
    +}
    +
     // Defined in extension_set_heavy.cc.
     // bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
     //                               const MessageLite* containing_type,
     //                               UnknownFieldSet* unknown_fields)
     
    -bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    -                                   ExtensionFinder* extension_finder,
    -                                   FieldSkipper* field_skipper) {
    -  while (true) {
    -    uint32 tag = input->ReadTag();
    -    switch (tag) {
    -      case 0:
    -        return true;
    -      case WireFormatLite::kMessageSetItemStartTag:
    -        if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
    -          return false;
    -        }
    -        break;
    -      default:
    -        if (!ParseField(tag, input, extension_finder, field_skipper)) {
    -          return false;
    -        }
    -        break;
    -    }
    -  }
    -}
    -
    -bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    -                                   const MessageLite* containing_type) {
    -  FieldSkipper skipper;
    -  GeneratedExtensionFinder finder(containing_type);
    -  return ParseMessageSet(input, &finder, &skipper);
    -}
    -
     // Defined in extension_set_heavy.cc.
     // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
     //                                    const MessageLite* containing_type,
     //                                    UnknownFieldSet* unknown_fields);
     
    -bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
    -                                       ExtensionFinder* extension_finder,
    -                                       FieldSkipper* field_skipper) {
    -  // TODO(kenton):  It would be nice to share code between this and
    -  // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
    -  // differences would be hard to factor out.
    -
    -  // This method parses a group which should contain two fields:
    -  //   required int32 type_id = 2;
    -  //   required data message = 3;
    -
    -  // Once we see a type_id, we'll construct a fake tag for this extension
    -  // which is the tag it would have had under the proto2 extensions wire
    -  // format.
    -  uint32 fake_tag = 0;
    -
    -  // If we see message data before the type_id, we'll append it to this so
    -  // we can parse it later.  This will probably never happen in practice,
    -  // as no MessageSet encoder I know of writes the message before the type ID.
    -  // But, it's technically valid so we should allow it.
    -  // TODO(kenton):  Use a Cord instead?  Do I care?
    -  string message_data;
    -
    -  while (true) {
    -    uint32 tag = input->ReadTag();
    -    if (tag == 0) return false;
    -
    -    switch (tag) {
    -      case WireFormatLite::kMessageSetTypeIdTag: {
    -        uint32 type_id;
    -        if (!input->ReadVarint32(&type_id)) return false;
    -        fake_tag = WireFormatLite::MakeTag(type_id,
    -            WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
    -
    -        if (!message_data.empty()) {
    -          // We saw some message data before the type_id.  Have to parse it
    -          // now.
    -          io::CodedInputStream sub_input(
    -              reinterpret_cast(message_data.data()),
    -              message_data.size());
    -          if (!ParseField(fake_tag, &sub_input,
    -                          extension_finder, field_skipper)) {
    -            return false;
    -          }
    -          message_data.clear();
    -        }
    -
    -        break;
    -      }
    -
    -      case WireFormatLite::kMessageSetMessageTag: {
    -        if (fake_tag == 0) {
    -          // We haven't seen a type_id yet.  Append this data to message_data.
    -          string temp;
    -          uint32 length;
    -          if (!input->ReadVarint32(&length)) return false;
    -          if (!input->ReadString(&temp, length)) return false;
    -          message_data.append(temp);
    -        } else {
    -          // Already saw type_id, so we can parse this directly.
    -          if (!ParseField(fake_tag, input,
    -                          extension_finder, field_skipper)) {
    -            return false;
    -          }
    -        }
    -
    -        break;
    -      }
    -
    -      case WireFormatLite::kMessageSetItemEndTag: {
    -        return true;
    -      }
    -
    -      default: {
    -        if (!field_skipper->SkipField(input, tag)) return false;
    -      }
    -    }
    -  }
    -}
    -
     void ExtensionSet::SerializeWithCachedSizes(
         int start_field_number, int end_field_number,
         io::CodedOutputStream* output) const {
    @@ -1021,14 +1205,6 @@ void ExtensionSet::SerializeWithCachedSizes(
       }
     }
     
    -void ExtensionSet::SerializeMessageSetWithCachedSizes(
    -    io::CodedOutputStream* output) const {
    -  map::const_iterator iter;
    -  for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
    -    iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
    -  }
    -}
    -
     int ExtensionSet::ByteSize() const {
       int total_size = 0;
     
    @@ -1040,17 +1216,6 @@ int ExtensionSet::ByteSize() const {
       return total_size;
     }
     
    -int ExtensionSet::MessageSetByteSize() const {
    -  int total_size = 0;
    -
    -  for (map::const_iterator iter = extensions_.begin();
    -       iter != extensions_.end(); ++iter) {
    -    total_size += iter->second.MessageSetItemByteSize(iter->first);
    -  }
    -
    -  return total_size;
    -}
    -
     // Defined in extension_set_heavy.cc.
     // int ExtensionSet::SpaceUsedExcludingSelf() const
     
    @@ -1094,7 +1259,11 @@ void ExtensionSet::Extension::Clear() {
               string_value->clear();
               break;
             case WireFormatLite::CPPTYPE_MESSAGE:
    -          message_value->Clear();
    +          if (is_lazy) {
    +            lazymessage_value->Clear();
    +          } else {
    +            message_value->Clear();
    +          }
               break;
             default:
               // No need to do anything.  Get*() will return the default value
    @@ -1206,40 +1375,18 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
           HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
           HANDLE_TYPE(    ENUM,     Enum,     enum_value);
           HANDLE_TYPE(   GROUP,    Group, *message_value);
    -      HANDLE_TYPE( MESSAGE,  Message, *message_value);
     #undef HANDLE_TYPE
    +      case WireFormatLite::TYPE_MESSAGE:
    +        if (is_lazy) {
    +          lazymessage_value->WriteMessage(number, output);
    +        } else {
    +          WireFormatLite::WriteMessage(number, *message_value, output);
    +        }
    +        break;
         }
       }
     }
     
    -void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
    -    int number,
    -    io::CodedOutputStream* output) const {
    -  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    -    // Not a valid MessageSet extension, but serialize it the normal way.
    -    SerializeFieldWithCachedSizes(number, output);
    -    return;
    -  }
    -
    -  if (is_cleared) return;
    -
    -  // Start group.
    -  output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
    -
    -  // Write type ID.
    -  WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
    -                              number,
    -                              output);
    -  // Write message.
    -  WireFormatLite::WriteMessageMaybeToArray(
    -      WireFormatLite::kMessageSetMessageNumber,
    -      *message_value,
    -      output);
    -
    -  // End group.
    -  output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
    -}
    -
     int ExtensionSet::Extension::ByteSize(int number) const {
       int result = 0;
     
    @@ -1353,8 +1500,16 @@ int ExtensionSet::Extension::ByteSize(int number) const {
           HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
           HANDLE_TYPE(    ENUM,     Enum,     enum_value);
           HANDLE_TYPE(   GROUP,    Group, *message_value);
    -      HANDLE_TYPE( MESSAGE,  Message, *message_value);
     #undef HANDLE_TYPE
    +      case WireFormatLite::TYPE_MESSAGE: {
    +        if (is_lazy) {
    +          int size = lazymessage_value->ByteSize();
    +          result += io::CodedOutputStream::VarintSize32(size) + size;
    +        } else {
    +          result += WireFormatLite::MessageSize(*message_value);
    +        }
    +        break;
    +      }
     
           // Stuff with fixed size.
     #define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
    @@ -1375,29 +1530,6 @@ int ExtensionSet::Extension::ByteSize(int number) const {
       return result;
     }
     
    -int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
    -  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    -    // Not a valid MessageSet extension, but compute the byte size for it the
    -    // normal way.
    -    return ByteSize(number);
    -  }
    -
    -  if (is_cleared) return 0;
    -
    -  int our_size = WireFormatLite::kMessageSetItemTagsSize;
    -
    -  // type_id
    -  our_size += io::CodedOutputStream::VarintSize32(number);
    -
    -  // message
    -  int message_size = message_value->ByteSize();
    -
    -  our_size += io::CodedOutputStream::VarintSize32(message_size);
    -  our_size += message_size;
    -
    -  return our_size;
    -}
    -
     int ExtensionSet::Extension::GetSize() const {
       GOOGLE_DCHECK(is_repeated);
       switch (cpp_type(type)) {
    @@ -1448,7 +1580,11 @@ void ExtensionSet::Extension::Free() {
             delete string_value;
             break;
           case WireFormatLite::CPPTYPE_MESSAGE:
    -        delete message_value;
    +        if (is_lazy) {
    +          delete lazymessage_value;
    +        } else {
    +          delete message_value;
    +        }
             break;
           default:
             break;
    @@ -1459,6 +1595,69 @@ void ExtensionSet::Extension::Free() {
     // Defined in extension_set_heavy.cc.
     // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
     
    +// ==================================================================
    +// Default repeated field instances for iterator-compatible accessors
    +
    +const RepeatedStringTypeTraits::RepeatedFieldType*
    +RepeatedStringTypeTraits::default_repeated_field_ = NULL;
    +
    +const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
    +RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
    +
    +#define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE)                                 \
    +    const RepeatedField*                                                 \
    +    RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
    +
    +PROTOBUF_DEFINE_DEFAULT_REPEATED(int32)
    +PROTOBUF_DEFINE_DEFAULT_REPEATED(int64)
    +PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32)
    +PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
    +PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
    +PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
    +PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
    +
    +#undef PROTOBUF_DEFINE_DEFAULT_REPEATED
    +
    +struct StaticDefaultRepeatedFieldsInitializer {
    +  StaticDefaultRepeatedFieldsInitializer() {
    +    InitializeDefaultRepeatedFields();
    +    OnShutdown(&DestroyDefaultRepeatedFields);
    +  }
    +} static_repeated_fields_initializer;
    +
    +void InitializeDefaultRepeatedFields() {
    +  RepeatedStringTypeTraits::default_repeated_field_ =
    +      new RepeatedStringTypeTraits::RepeatedFieldType;
    +  RepeatedMessageGenericTypeTraits::default_repeated_field_ =
    +      new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
    +  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
    +      new RepeatedField;
    +  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
    +      new RepeatedField;
    +  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
    +      new RepeatedField;
    +  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
    +      new RepeatedField;
    +  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
    +      new RepeatedField;
    +  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
    +      new RepeatedField;
    +  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
    +      new RepeatedField;
    +}
    +
    +void DestroyDefaultRepeatedFields() {
    +  delete RepeatedStringTypeTraits::default_repeated_field_;
    +  delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
    +  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
    +  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
    +  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
    +  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
    +  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
    +  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
    +  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
    +}
    +
     }  // namespace internal
     }  // namespace protobuf
     }  // namespace google
    diff --git a/toolkit/components/protobuf/google/protobuf/extension_set.h b/toolkit/components/protobuf/src/google/protobuf/extension_set.h
    similarity index 63%
    rename from toolkit/components/protobuf/google/protobuf/extension_set.h
    rename to toolkit/components/protobuf/src/google/protobuf/extension_set.h
    index ac1ada029f1f..d7ec51924705 100644
    --- a/toolkit/components/protobuf/google/protobuf/extension_set.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/extension_set.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -46,6 +46,8 @@
     
     #include 
     
    +#include 
    +
     namespace google {
     
     namespace protobuf {
    @@ -62,10 +64,7 @@ namespace protobuf {
       }
       namespace internal {
         class FieldSkipper;                                  // wire_format_lite.h
    -    class RepeatedPtrFieldBase;                          // repeated_field.h
       }
    -  template  class RepeatedField;     // repeated_field.h
    -  template  class RepeatedPtrField;  // repeated_field.h
     }
     
     namespace protobuf {
    @@ -89,8 +88,8 @@ typedef bool EnumValidityFuncWithArg(const void* arg, int number);
     // Information about a registered extension.
     struct ExtensionInfo {
       inline ExtensionInfo() {}
    -  inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed)
    -      : type(type), is_repeated(is_repeated), is_packed(is_packed),
    +  inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked)
    +      : type(type_param), is_repeated(isrepeated), is_packed(ispacked),
             descriptor(NULL) {}
     
       FieldType type;
    @@ -138,6 +137,9 @@ class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
       const MessageLite* containing_type_;
     };
     
    +// A FieldSkipper used for parsing MessageSet.
    +class MessageSetFieldSkipper;
    +
     // Note:  extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
     // finding extensions from a DescriptorPool.
     
    @@ -214,6 +216,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
     
       bool Has(int number) const;
       int ExtensionSize(int number) const;   // Size of a repeated extension.
    +  int NumExtensions() const;  // The number of extensions
       FieldType ExtensionType(int number) const;
       void ClearExtension(int number);
     
    @@ -251,10 +254,35 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
                                   const MessageLite& prototype, desc);
       MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
                                   MessageFactory* factory);
    +  // Adds the given message to the ExtensionSet, taking ownership of the
    +  // message object. Existing message with the same number will be deleted.
    +  // If "message" is NULL, this is equivalent to "ClearExtension(number)".
    +  void SetAllocatedMessage(int number, FieldType type,
    +                           const FieldDescriptor* descriptor,
    +                           MessageLite* message);
    +  MessageLite* ReleaseMessage(int number, const MessageLite& prototype);
    +  MessageLite* ReleaseMessage(const FieldDescriptor* descriptor,
    +                              MessageFactory* factory);
     #undef desc
     
       // repeated fields -------------------------------------------------
     
    +  // Fetches a RepeatedField extension by number; returns |default_value|
    +  // if no such extension exists. User should not touch this directly; it is
    +  // used by the GetRepeatedExtension() method.
    +  const void* GetRawRepeatedField(int number, const void* default_value) const;
    +  // Fetches a mutable version of a RepeatedField extension by number,
    +  // instantiating one if none exists. Similar to above, user should not use
    +  // this directly; it underlies MutableRepeatedExtension().
    +  void* MutableRawRepeatedField(int number, FieldType field_type,
    +                                bool packed, const FieldDescriptor* desc);
    +
    +  // This is an overload of MutableRawRepeatedField to maintain compatibility
    +  // with old code using a previous API. This version of
    +  // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension.
    +  // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.)
    +  void* MutableRawRepeatedField(int number);
    +
       int32  GetRepeatedInt32 (int number, int index) const;
       int64  GetRepeatedInt64 (int number, int index) const;
       uint32 GetRepeatedUInt32(int number, int index) const;
    @@ -296,6 +324,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
     #undef desc
     
       void RemoveLast(int number);
    +  MessageLite* ReleaseLast(int number);
       void SwapElements(int number, int index1, int index2);
     
       // -----------------------------------------------------------------
    @@ -310,31 +339,35 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
       void Clear();
       void MergeFrom(const ExtensionSet& other);
       void Swap(ExtensionSet* other);
    +  void SwapExtension(ExtensionSet* other, int number);
       bool IsInitialized() const;
     
    -  // Parses a single extension from the input.  The input should start out
    -  // positioned immediately after the tag.  |containing_type| is the default
    -  // instance for the containing message; it is used only to look up the
    -  // extension by number.  See RegisterExtension(), above.  Unlike the other
    -  // methods of ExtensionSet, this only works for generated message types --
    -  // it looks up extensions registered using RegisterExtension().
    +  // Parses a single extension from the input. The input should start out
    +  // positioned immediately after the tag.
       bool ParseField(uint32 tag, io::CodedInputStream* input,
                       ExtensionFinder* extension_finder,
                       FieldSkipper* field_skipper);
     
       // Specific versions for lite or full messages (constructs the appropriate
    -  // FieldSkipper automatically).
    +  // FieldSkipper automatically).  |containing_type| is the default
    +  // instance for the containing message; it is used only to look up the
    +  // extension by number.  See RegisterExtension(), above.  Unlike the other
    +  // methods of ExtensionSet, this only works for generated message types --
    +  // it looks up extensions registered using RegisterExtension().
       bool ParseField(uint32 tag, io::CodedInputStream* input,
                       const MessageLite* containing_type);
       bool ParseField(uint32 tag, io::CodedInputStream* input,
                       const Message* containing_type,
                       UnknownFieldSet* unknown_fields);
    +  bool ParseField(uint32 tag, io::CodedInputStream* input,
    +                  const MessageLite* containing_type,
    +                  io::CodedOutputStream* unknown_fields);
     
       // Parse an entire message in MessageSet format.  Such messages have no
       // fields, only extensions.
       bool ParseMessageSet(io::CodedInputStream* input,
                            ExtensionFinder* extension_finder,
    -                       FieldSkipper* field_skipper);
    +                       MessageSetFieldSkipper* field_skipper);
     
       // Specific versions for lite or full messages (constructs the appropriate
       // FieldSkipper automatically).
    @@ -382,18 +415,49 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
     
      private:
     
    +  // Interface of a lazily parsed singular message extension.
    +  class LIBPROTOBUF_EXPORT LazyMessageExtension {
    +   public:
    +    LazyMessageExtension() {}
    +    virtual ~LazyMessageExtension() {}
    +
    +    virtual LazyMessageExtension* New() const = 0;
    +    virtual const MessageLite& GetMessage(
    +        const MessageLite& prototype) const = 0;
    +    virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0;
    +    virtual void SetAllocatedMessage(MessageLite *message) = 0;
    +    virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0;
    +
    +    virtual bool IsInitialized() const = 0;
    +    virtual int ByteSize() const = 0;
    +    virtual int SpaceUsed() const = 0;
    +
    +    virtual void MergeFrom(const LazyMessageExtension& other) = 0;
    +    virtual void Clear() = 0;
    +
    +    virtual bool ReadMessage(const MessageLite& prototype,
    +                             io::CodedInputStream* input) = 0;
    +    virtual void WriteMessage(int number,
    +                              io::CodedOutputStream* output) const = 0;
    +    virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0;
    +   private:
    +    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
    +  };
       struct Extension {
    +    // The order of these fields packs Extension into 24 bytes when using 8
    +    // byte alignment. Consider this when adding or removing fields here.
         union {
    -      int32        int32_value;
    -      int64        int64_value;
    -      uint32       uint32_value;
    -      uint64       uint64_value;
    -      float        float_value;
    -      double       double_value;
    -      bool         bool_value;
    -      int          enum_value;
    -      string*      string_value;
    -      MessageLite* message_value;
    +      int32                 int32_value;
    +      int64                 int64_value;
    +      uint32                uint32_value;
    +      uint64                uint64_value;
    +      float                 float_value;
    +      double                double_value;
    +      bool                  bool_value;
    +      int                   enum_value;
    +      string*               string_value;
    +      MessageLite*          message_value;
    +      LazyMessageExtension* lazymessage_value;
     
           RepeatedField   * repeated_int32_value;
           RepeatedField   * repeated_int64_value;
    @@ -416,21 +480,28 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
         // removing it from the map, we just set is_cleared = true.  This has no
         // meaning for repeated types; for those, the size of the RepeatedField
         // simply becomes zero when cleared.
    -    bool is_cleared;
    +    bool is_cleared : 4;
    +
    +    // For singular message types, indicates whether lazy parsing is enabled
    +    // for this extension. This field is only valid when type == TYPE_MESSAGE
    +    // and !is_repeated because we only support lazy parsing for singular
    +    // message types currently. If is_lazy = true, the extension is stored in
    +    // lazymessage_value. Otherwise, the extension will be message_value.
    +    bool is_lazy : 4;
     
         // For repeated types, this indicates if the [packed=true] option is set.
         bool is_packed;
     
    -    // The descriptor for this extension, if one exists and is known.  May be
    -    // NULL.  Must not be NULL if the descriptor for the extension does not
    -    // live in the same pool as the descriptor for the containing type.
    -    const FieldDescriptor* descriptor;
    -
         // For packed fields, the size of the packed data is recorded here when
         // ByteSize() is called then used during serialization.
         // TODO(kenton):  Use atomic when C++ supports it.
         mutable int cached_size;
     
    +    // The descriptor for this extension, if one exists and is known.  May be
    +    // NULL.  Must not be NULL if the descriptor for the extension does not
    +    // live in the same pool as the descriptor for the containing type.
    +    const FieldDescriptor* descriptor;
    +
         // Some helper methods for operations on a single Extension.
         void SerializeFieldWithCachedSizes(
             int number,
    @@ -453,6 +524,40 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
       };
     
     
    +  // Returns true and fills field_number and extension if extension is found.
    +  // Note to support packed repeated field compatibility, it also fills whether
    +  // the tag on wire is packed, which can be different from
    +  // extension->is_packed (whether packed=true is specified).
    +  bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder,
    +                                int* field_number, ExtensionInfo* extension,
    +                                bool* was_packed_on_wire);
    +
    +  // Returns true and fills extension if extension is found.
    +  // Note to support packed repeated field compatibility, it also fills whether
    +  // the tag on wire is packed, which can be different from
    +  // extension->is_packed (whether packed=true is specified).
    +  bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number,
    +                                        ExtensionFinder* extension_finder,
    +                                        ExtensionInfo* extension,
    +                                        bool* was_packed_on_wire);
    +
    +  // Parses a single extension from the input. The input should start out
    +  // positioned immediately after the wire tag. This method is called in
    +  // ParseField() after field number and was_packed_on_wire is extracted from
    +  // the wire tag and ExtensionInfo is found by the field number.
    +  bool ParseFieldWithExtensionInfo(int field_number,
    +                                   bool was_packed_on_wire,
    +                                   const ExtensionInfo& extension,
    +                                   io::CodedInputStream* input,
    +                                   FieldSkipper* field_skipper);
    +
    +  // Like ParseField(), but this method may parse singular message extensions
    +  // lazily depending on the value of FLAGS_eagerly_parse_message_sets.
    +  bool ParseFieldMaybeLazily(int wire_type, int field_number,
    +                             io::CodedInputStream* input,
    +                             ExtensionFinder* extension_finder,
    +                             MessageSetFieldSkipper* field_skipper);
    +
       // Gets the extension with the given number, creating it if it does not
       // already exist.  Returns true if the extension did not already exist.
       bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
    @@ -462,7 +567,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
       // tag has been read.
       bool ParseMessageSetItem(io::CodedInputStream* input,
                                ExtensionFinder* extension_finder,
    -                           FieldSkipper* field_skipper);
    +                           MessageSetFieldSkipper* field_skipper);
     
     
       // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This
    @@ -481,7 +586,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
       // only contain a small number of extensions whereas hash_map is optimized
       // for 100 elements or more.  Also, we want AppendToList() to order fields
       // by field number.
    -  map extensions_;
    +  std::map extensions_;
     
       GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
     };
    @@ -517,6 +622,16 @@ inline void ExtensionSet::AddString(int number, FieldType type,
     //    public:
     //     typedef ? ConstType;
     //     typedef ? MutableType;
    +//     // TypeTraits for singular fields and repeated fields will define the
    +//     // symbol "Singular" or "Repeated" respectively. These two symbols will
    +//     // be used in extension accessors to distinguish between singular
    +//     // extensions and repeated extensions. If the TypeTraits for the passed
    +//     // in extension doesn't have the expected symbol defined, it means the
    +//     // user is passing a repeated extension to a singular accessor, or the
    +//     // opposite. In that case the C++ compiler will generate an error
    +//     // message "no matching member function" to inform the user.
    +//     typedef ? Singular
    +//     typedef ? Repeated
     //
     //     static inline ConstType Get(int number, const ExtensionSet& set);
     //     static inline void Set(int number, ConstType value, ExtensionSet* set);
    @@ -555,6 +670,8 @@ template 
     class PrimitiveTypeTraits {
      public:
       typedef Type ConstType;
    +  typedef Type MutableType;
    +  typedef PrimitiveTypeTraits Singular;
     
       static inline ConstType Get(int number, const ExtensionSet& set,
                                   ConstType default_value);
    @@ -566,11 +683,41 @@ template 
     class RepeatedPrimitiveTypeTraits {
      public:
       typedef Type ConstType;
    +  typedef Type MutableType;
    +  typedef RepeatedPrimitiveTypeTraits Repeated;
    +
    +  typedef RepeatedField RepeatedFieldType;
     
       static inline Type Get(int number, const ExtensionSet& set, int index);
       static inline void Set(int number, int index, Type value, ExtensionSet* set);
       static inline void Add(int number, FieldType field_type,
                              bool is_packed, Type value, ExtensionSet* set);
    +
    +  static inline const RepeatedField&
    +      GetRepeated(int number, const ExtensionSet& set);
    +  static inline RepeatedField*
    +      MutableRepeated(int number, FieldType field_type,
    +                      bool is_packed, ExtensionSet* set);
    +
    +  static const RepeatedFieldType* GetDefaultRepeatedField();
    +};
    +
    +// Declared here so that this can be friended below.
    +void InitializeDefaultRepeatedFields();
    +void DestroyDefaultRepeatedFields();
    +
    +class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits {
    + private:
    +  template friend class RepeatedPrimitiveTypeTraits;
    +  friend void InitializeDefaultRepeatedFields();
    +  friend void DestroyDefaultRepeatedFields();
    +  static const RepeatedField* default_repeated_field_int32_;
    +  static const RepeatedField* default_repeated_field_int64_;
    +  static const RepeatedField* default_repeated_field_uint32_;
    +  static const RepeatedField* default_repeated_field_uint64_;
    +  static const RepeatedField* default_repeated_field_double_;
    +  static const RepeatedField* default_repeated_field_float_;
    +  static const RepeatedField* default_repeated_field_bool_;
     };
     
     #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                       \
    @@ -595,6 +742,26 @@ template<> inline void RepeatedPrimitiveTypeTraits::Add(             \
         int number, FieldType field_type, bool is_packed,                      \
         TYPE value, ExtensionSet* set) {                                       \
       set->Add##METHOD(number, field_type, is_packed, value, NULL);            \
    +}                                                                          \
    +template<> inline const RepeatedField*                               \
    +    RepeatedPrimitiveTypeTraits::GetDefaultRepeatedField() {         \
    +  return RepeatedPrimitiveGenericTypeTraits::                              \
    +      default_repeated_field_##TYPE##_;                                    \
    +}                                                                          \
    +template<> inline const RepeatedField&                               \
    +    RepeatedPrimitiveTypeTraits::GetRepeated(int number,             \
    +                                               const ExtensionSet& set) {  \
    +  return *reinterpret_cast*>(                    \
    +                            set.GetRawRepeatedField(                       \
    +                                number, GetDefaultRepeatedField()));       \
    +}                                                                          \
    +template<> inline RepeatedField*                                     \
    +    RepeatedPrimitiveTypeTraits::MutableRepeated(int number,         \
    +                                                   FieldType field_type,   \
    +                                                   bool is_packed,         \
    +                                                   ExtensionSet* set) {    \
    +  return reinterpret_cast*>(                           \
    +      set->MutableRawRepeatedField(number, field_type, is_packed, NULL));  \
     }
     
     PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32,  Int32)
    @@ -615,6 +782,7 @@ class LIBPROTOBUF_EXPORT StringTypeTraits {
      public:
       typedef const string& ConstType;
       typedef string* MutableType;
    +  typedef StringTypeTraits Singular;
     
       static inline const string& Get(int number, const ExtensionSet& set,
                                       ConstType default_value) {
    @@ -634,6 +802,9 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
      public:
       typedef const string& ConstType;
       typedef string* MutableType;
    +  typedef RepeatedStringTypeTraits Repeated;
    +
    +  typedef RepeatedPtrField RepeatedFieldType;
     
       static inline const string& Get(int number, const ExtensionSet& set,
                                       int index) {
    @@ -655,6 +826,28 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
                                 ExtensionSet* set) {
         return set->AddString(number, field_type, NULL);
       }
    +  static inline const RepeatedPtrField&
    +      GetRepeated(int number, const ExtensionSet& set) {
    +    return *reinterpret_cast*>(
    +        set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
    +  }
    +
    +  static inline RepeatedPtrField*
    +      MutableRepeated(int number, FieldType field_type,
    +                      bool is_packed, ExtensionSet* set) {
    +    return reinterpret_cast*>(
    +        set->MutableRawRepeatedField(number, field_type,
    +                                     is_packed, NULL));
    +  }
    +
    +  static const RepeatedFieldType* GetDefaultRepeatedField() {
    +    return default_repeated_field_;
    +  }
    +
    + private:
    +  friend void InitializeDefaultRepeatedFields();
    +  friend void DestroyDefaultRepeatedFields();
    +  static const RepeatedFieldType *default_repeated_field_;
     };
     
     // -------------------------------------------------------------------
    @@ -666,6 +859,8 @@ template 
     class EnumTypeTraits {
      public:
       typedef Type ConstType;
    +  typedef Type MutableType;
    +  typedef EnumTypeTraits Singular;
     
       static inline ConstType Get(int number, const ExtensionSet& set,
                                   ConstType default_value) {
    @@ -682,6 +877,10 @@ template 
     class RepeatedEnumTypeTraits {
      public:
       typedef Type ConstType;
    +  typedef Type MutableType;
    +  typedef RepeatedEnumTypeTraits Repeated;
    +
    +  typedef RepeatedField RepeatedFieldType;
     
       static inline ConstType Get(int number, const ExtensionSet& set, int index) {
         return static_cast(set.GetRepeatedEnum(number, index));
    @@ -696,6 +895,35 @@ class RepeatedEnumTypeTraits {
         GOOGLE_DCHECK(IsValid(value));
         set->AddEnum(number, field_type, is_packed, value, NULL);
       }
    +  static inline const RepeatedField& GetRepeated(int number,
    +                                                       const ExtensionSet&
    +                                                       set) {
    +    // Hack: the `Extension` struct stores a RepeatedField for enums.
    +    // RepeatedField cannot implicitly convert to RepeatedField
    +    // so we need to do some casting magic. See message.h for similar
    +    // contortions for non-extension fields.
    +    return *reinterpret_cast*>(
    +        set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
    +  }
    +
    +  static inline RepeatedField* MutableRepeated(int number,
    +                                                     FieldType field_type,
    +                                                     bool is_packed,
    +                                                     ExtensionSet* set) {
    +    return reinterpret_cast*>(
    +        set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
    +  }
    +
    +  static const RepeatedFieldType* GetDefaultRepeatedField() {
    +    // Hack: as noted above, repeated enum fields are internally stored as a
    +    // RepeatedField. We need to be able to instantiate global static
    +    // objects to return as default (empty) repeated fields on non-existent
    +    // extensions. We would not be able to know a-priori all of the enum types
    +    // (values of |Type|) to instantiate all of these, so we just re-use int32's
    +    // default repeated field object.
    +    return reinterpret_cast*>(
    +        RepeatedPrimitiveTypeTraits::GetDefaultRepeatedField());
    +  }
     };
     
     // -------------------------------------------------------------------
    @@ -709,6 +937,7 @@ class MessageTypeTraits {
      public:
       typedef const Type& ConstType;
       typedef Type* MutableType;
    +  typedef MessageTypeTraits Singular;
     
       static inline ConstType Get(int number, const ExtensionSet& set,
                                   ConstType default_value) {
    @@ -720,13 +949,28 @@ class MessageTypeTraits {
         return static_cast(
           set->MutableMessage(number, field_type, Type::default_instance(), NULL));
       }
    +  static inline void SetAllocated(int number, FieldType field_type,
    +                                  MutableType message, ExtensionSet* set) {
    +    set->SetAllocatedMessage(number, field_type, NULL, message);
    +  }
    +  static inline MutableType Release(int number, FieldType /* field_type */,
    +                                    ExtensionSet* set) {
    +    return static_cast(set->ReleaseMessage(
    +        number, Type::default_instance()));
    +  }
     };
     
    +// forward declaration
    +class RepeatedMessageGenericTypeTraits;
    +
     template 
     class RepeatedMessageTypeTraits {
      public:
       typedef const Type& ConstType;
       typedef Type* MutableType;
    +  typedef RepeatedMessageTypeTraits Repeated;
    +
    +  typedef RepeatedPtrField RepeatedFieldType;
     
       static inline ConstType Get(int number, const ExtensionSet& set, int index) {
         return static_cast(set.GetRepeatedMessage(number, index));
    @@ -739,8 +983,47 @@ class RepeatedMessageTypeTraits {
         return static_cast(
             set->AddMessage(number, field_type, Type::default_instance(), NULL));
       }
    +  static inline const RepeatedPtrField& GetRepeated(int number,
    +                                                          const ExtensionSet&
    +                                                          set) {
    +    // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
    +    // casting hack applies here, because a RepeatedPtrField
    +    // cannot naturally become a RepeatedPtrType even though Type is
    +    // presumably a message. google::protobuf::Message goes through similar contortions
    +    // with a reinterpret_cast<>.
    +    return *reinterpret_cast*>(
    +        set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
    +  }
    +  static inline RepeatedPtrField* MutableRepeated(int number,
    +                                                        FieldType field_type,
    +                                                        bool is_packed,
    +                                                        ExtensionSet* set) {
    +    return reinterpret_cast*>(
    +        set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
    +  }
    +
    +  static const RepeatedFieldType* GetDefaultRepeatedField();
     };
     
    +// This class exists only to hold a generic default empty repeated field for all
    +// message-type repeated field extensions.
    +class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
    + public:
    +  typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType;
    + private:
    +  template friend class RepeatedMessageTypeTraits;
    +  friend void InitializeDefaultRepeatedFields();
    +  friend void DestroyDefaultRepeatedFields();
    +  static const RepeatedFieldType* default_repeated_field_;
    +};
    +
    +template inline
    +    const typename RepeatedMessageTypeTraits::RepeatedFieldType*
    +    RepeatedMessageTypeTraits::GetDefaultRepeatedField() {
    +  return reinterpret_cast(
    +      RepeatedMessageGenericTypeTraits::default_repeated_field_);
    +}
    +
     // -------------------------------------------------------------------
     // ExtensionIdentifier
     
    @@ -787,114 +1070,161 @@ class ExtensionIdentifier {
     // causes problems if the class has a nested message or enum type with that
     // name and "_TypeTraits" is technically reserved for the C++ library since
     // it starts with an underscore followed by a capital letter.
    +//
    +// For similar reason, we use "_field_type" and "_is_packed" as parameter names
    +// below, so that "field_type" and "is_packed" can be used as field names.
     #define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME)                        \
       /* Has, Size, Clear */                                                      \
       template                                                    \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
       inline bool HasExtension(                                                   \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const {     \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
         return _extensions_.Has(id.number());                                     \
       }                                                                           \
                                                                                   \
       template                                                    \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
       inline void ClearExtension(                                                 \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) {           \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
         _extensions_.ClearExtension(id.number());                                 \
       }                                                                           \
                                                                                   \
       template                                                    \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
       inline int ExtensionSize(                                                   \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const {     \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
         return _extensions_.ExtensionSize(id.number());                           \
       }                                                                           \
                                                                                   \
       /* Singular accessors */                                                    \
       template                                                    \
    -  inline typename _proto_TypeTraits::ConstType GetExtension(                  \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
    +  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(        \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const {     \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
         return _proto_TypeTraits::Get(id.number(), _extensions_,                  \
                                       id.default_value());                        \
       }                                                                           \
                                                                                   \
       template                                                    \
    -  inline typename _proto_TypeTraits::MutableType MutableExtension(            \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
    +  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(  \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) {           \
    -    return _proto_TypeTraits::Mutable(id.number(), field_type, &_extensions_);\
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    +    return _proto_TypeTraits::Mutable(id.number(), _field_type,               \
    +                                      &_extensions_);                         \
       }                                                                           \
                                                                                   \
       template                                                    \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
       inline void SetExtension(                                                   \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    -      typename _proto_TypeTraits::ConstType value) {                          \
    -    _proto_TypeTraits::Set(id.number(), field_type, value, &_extensions_);    \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    +      typename _proto_TypeTraits::Singular::ConstType value) {                \
    +    _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);   \
    +  }                                                                           \
    +                                                                              \
    +  template                                                   \
    +  inline void SetAllocatedExtension(                                          \
    +      const ::google::protobuf::internal::ExtensionIdentifier<                          \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    +      typename _proto_TypeTraits::Singular::MutableType value) {              \
    +    _proto_TypeTraits::SetAllocated(id.number(), _field_type,                 \
    +                                    value, &_extensions_);                    \
    +  }                                                                           \
    +  template                                                   \
    +  inline typename _proto_TypeTraits::Singular::MutableType ReleaseExtension(  \
    +      const ::google::protobuf::internal::ExtensionIdentifier<                          \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    +    return _proto_TypeTraits::Release(id.number(), _field_type,               \
    +                                      &_extensions_);                         \
       }                                                                           \
                                                                                   \
       /* Repeated accessors */                                                    \
       template                                                    \
    -  inline typename _proto_TypeTraits::ConstType GetExtension(                  \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
    +  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(        \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
           int index) const {                                                      \
         return _proto_TypeTraits::Get(id.number(), _extensions_, index);          \
       }                                                                           \
                                                                                   \
       template                                                    \
    -  inline typename _proto_TypeTraits::MutableType MutableExtension(            \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
    +  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(  \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
           int index) {                                                            \
         return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);     \
       }                                                                           \
                                                                                   \
       template                                                    \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
       inline void SetExtension(                                                   \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    -      int index, typename _proto_TypeTraits::ConstType value) {               \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    +      int index, typename _proto_TypeTraits::Repeated::ConstType value) {     \
         _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);         \
       }                                                                           \
                                                                                   \
       template                                                    \
    -  inline typename _proto_TypeTraits::MutableType AddExtension(                \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
    +  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(      \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) {           \
    -    return _proto_TypeTraits::Add(id.number(), field_type, &_extensions_);    \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    +    return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);   \
       }                                                                           \
                                                                                   \
       template                                                    \
    +            ::google::protobuf::internal::FieldType _field_type,                        \
    +            bool _is_packed>                                                  \
       inline void AddExtension(                                                   \
           const ::google::protobuf::internal::ExtensionIdentifier<                          \
    -        CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    -      typename _proto_TypeTraits::ConstType value) {                          \
    -    _proto_TypeTraits::Add(id.number(), field_type, is_packed,                \
    +        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    +      typename _proto_TypeTraits::Repeated::ConstType value) {                \
    +    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed,              \
                                value, &_extensions_);                             \
    +  }                                                                           \
    +                                                                              \
    +  template                                                   \
    +  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&       \
    +      GetRepeatedExtension(                                                   \
    +          const ::google::protobuf::internal::ExtensionIdentifier<                      \
    +            CLASSNAME, _proto_TypeTraits, _field_type,                        \
    +            _is_packed>& id) const {                                          \
    +    return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);         \
    +  }                                                                           \
    +                                                                              \
    +  template                                                   \
    +  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*             \
    +      MutableRepeatedExtension(                                               \
    +          const ::google::protobuf::internal::ExtensionIdentifier<                      \
    +              CLASSNAME, _proto_TypeTraits, _field_type,                      \
    +              _is_packed>& id) {                                              \
    +    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,       \
    +                                              _is_packed, &_extensions_);     \
       }
     
     }  // namespace internal
    diff --git a/toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc b/toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc
    new file mode 100644
    index 000000000000..eae4d574f892
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc
    @@ -0,0 +1,734 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Contains methods defined in extension_set.h which cannot be part of the
    +// lite library because they use descriptors or reflection.
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +
    +namespace protobuf {
    +namespace internal {
    +
    +// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
    +class MessageSetFieldSkipper
    +    : public UnknownFieldSetFieldSkipper {
    + public:
    +  explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
    +      : UnknownFieldSetFieldSkipper(unknown_fields) {}
    +  virtual ~MessageSetFieldSkipper() {}
    +
    +  virtual bool SkipMessageSetField(io::CodedInputStream* input,
    +                                   int field_number);
    +};
    +bool MessageSetFieldSkipper::SkipMessageSetField(
    +    io::CodedInputStream* input, int field_number) {
    +  uint32 length;
    +  if (!input->ReadVarint32(&length)) return false;
    +  if (unknown_fields_ == NULL) {
    +    return input->Skip(length);
    +  } else {
    +    return input->ReadString(
    +        unknown_fields_->AddLengthDelimited(field_number), length);
    +  }
    +}
    +
    +
    +// Implementation of ExtensionFinder which finds extensions in a given
    +// DescriptorPool, using the given MessageFactory to construct sub-objects.
    +// This class is implemented in extension_set_heavy.cc.
    +class DescriptorPoolExtensionFinder : public ExtensionFinder {
    + public:
    +  DescriptorPoolExtensionFinder(const DescriptorPool* pool,
    +                                MessageFactory* factory,
    +                                const Descriptor* containing_type)
    +      : pool_(pool), factory_(factory), containing_type_(containing_type) {}
    +  virtual ~DescriptorPoolExtensionFinder() {}
    +
    +  virtual bool Find(int number, ExtensionInfo* output);
    +
    + private:
    +  const DescriptorPool* pool_;
    +  MessageFactory* factory_;
    +  const Descriptor* containing_type_;
    +};
    +
    +void ExtensionSet::AppendToList(const Descriptor* containing_type,
    +                                const DescriptorPool* pool,
    +                                vector* output) const {
    +  for (map::const_iterator iter = extensions_.begin();
    +       iter != extensions_.end(); ++iter) {
    +    bool has = false;
    +    if (iter->second.is_repeated) {
    +      has = iter->second.GetSize() > 0;
    +    } else {
    +      has = !iter->second.is_cleared;
    +    }
    +
    +    if (has) {
    +      // TODO(kenton): Looking up each field by number is somewhat unfortunate.
    +      //   Is there a better way?  The problem is that descriptors are lazily-
    +      //   initialized, so they might not even be constructed until
    +      //   AppendToList() is called.
    +
    +      if (iter->second.descriptor == NULL) {
    +        output->push_back(pool->FindExtensionByNumber(
    +            containing_type, iter->first));
    +      } else {
    +        output->push_back(iter->second.descriptor);
    +      }
    +    }
    +  }
    +}
    +
    +inline FieldDescriptor::Type real_type(FieldType type) {
    +  GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
    +  return static_cast(type);
    +}
    +
    +inline FieldDescriptor::CppType cpp_type(FieldType type) {
    +  return FieldDescriptor::TypeToCppType(
    +      static_cast(type));
    +}
    +
    +inline WireFormatLite::FieldType field_type(FieldType type) {
    +  GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
    +  return static_cast(type);
    +}
    +
    +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                            \
    +  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED     \
    +                                  : FieldDescriptor::LABEL_OPTIONAL,      \
    +            FieldDescriptor::LABEL_##LABEL);                              \
    +  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
    +
    +const MessageLite& ExtensionSet::GetMessage(int number,
    +                                            const Descriptor* message_type,
    +                                            MessageFactory* factory) const {
    +  map::const_iterator iter = extensions_.find(number);
    +  if (iter == extensions_.end() || iter->second.is_cleared) {
    +    // Not present.  Return the default value.
    +    return *factory->GetPrototype(message_type);
    +  } else {
    +    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
    +    if (iter->second.is_lazy) {
    +      return iter->second.lazymessage_value->GetMessage(
    +          *factory->GetPrototype(message_type));
    +    } else {
    +      return *iter->second.message_value;
    +    }
    +  }
    +}
    +
    +MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
    +                                          MessageFactory* factory) {
    +  Extension* extension;
    +  if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
    +    extension->type = descriptor->type();
    +    GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
    +    extension->is_repeated = false;
    +    extension->is_packed = false;
    +    const MessageLite* prototype =
    +        factory->GetPrototype(descriptor->message_type());
    +    extension->is_lazy = false;
    +    extension->message_value = prototype->New();
    +    extension->is_cleared = false;
    +    return extension->message_value;
    +  } else {
    +    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
    +    extension->is_cleared = false;
    +    if (extension->is_lazy) {
    +      return extension->lazymessage_value->MutableMessage(
    +          *factory->GetPrototype(descriptor->message_type()));
    +    } else {
    +      return extension->message_value;
    +    }
    +  }
    +}
    +
    +MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
    +                                          MessageFactory* factory) {
    +  map::iterator iter = extensions_.find(descriptor->number());
    +  if (iter == extensions_.end()) {
    +    // Not present.  Return NULL.
    +    return NULL;
    +  } else {
    +    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
    +    MessageLite* ret = NULL;
    +    if (iter->second.is_lazy) {
    +      ret = iter->second.lazymessage_value->ReleaseMessage(
    +          *factory->GetPrototype(descriptor->message_type()));
    +      delete iter->second.lazymessage_value;
    +    } else {
    +      ret = iter->second.message_value;
    +    }
    +    extensions_.erase(descriptor->number());
    +    return ret;
    +  }
    +}
    +
    +MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
    +                                      MessageFactory* factory) {
    +  Extension* extension;
    +  if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
    +    extension->type = descriptor->type();
    +    GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
    +    extension->is_repeated = true;
    +    extension->repeated_message_value =
    +      new RepeatedPtrField();
    +  } else {
    +    GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
    +  }
    +
    +  // RepeatedPtrField does not know how to Add() since it cannot
    +  // allocate an abstract object, so we have to be tricky.
    +  MessageLite* result = extension->repeated_message_value
    +      ->AddFromCleared >();
    +  if (result == NULL) {
    +    const MessageLite* prototype;
    +    if (extension->repeated_message_value->size() == 0) {
    +      prototype = factory->GetPrototype(descriptor->message_type());
    +      GOOGLE_CHECK(prototype != NULL);
    +    } else {
    +      prototype = &extension->repeated_message_value->Get(0);
    +    }
    +    result = prototype->New();
    +    extension->repeated_message_value->AddAllocated(result);
    +  }
    +  return result;
    +}
    +
    +static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
    +  return reinterpret_cast(arg)
    +      ->FindValueByNumber(number) != NULL;
    +}
    +
    +bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
    +  const FieldDescriptor* extension =
    +      pool_->FindExtensionByNumber(containing_type_, number);
    +  if (extension == NULL) {
    +    return false;
    +  } else {
    +    output->type = extension->type();
    +    output->is_repeated = extension->is_repeated();
    +    output->is_packed = extension->options().packed();
    +    output->descriptor = extension;
    +    if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      output->message_prototype =
    +          factory_->GetPrototype(extension->message_type());
    +      GOOGLE_CHECK(output->message_prototype != NULL)
    +          << "Extension factory's GetPrototype() returned NULL for extension: "
    +          << extension->full_name();
    +    } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
    +      output->enum_validity_check.func = ValidateEnumUsingDescriptor;
    +      output->enum_validity_check.arg = extension->enum_type();
    +    }
    +
    +    return true;
    +  }
    +}
    +
    +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
    +                              const Message* containing_type,
    +                              UnknownFieldSet* unknown_fields) {
    +  UnknownFieldSetFieldSkipper skipper(unknown_fields);
    +  if (input->GetExtensionPool() == NULL) {
    +    GeneratedExtensionFinder finder(containing_type);
    +    return ParseField(tag, input, &finder, &skipper);
    +  } else {
    +    DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
    +                                         input->GetExtensionFactory(),
    +                                         containing_type->GetDescriptor());
    +    return ParseField(tag, input, &finder, &skipper);
    +  }
    +}
    +
    +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    +                                   const Message* containing_type,
    +                                   UnknownFieldSet* unknown_fields) {
    +  MessageSetFieldSkipper skipper(unknown_fields);
    +  if (input->GetExtensionPool() == NULL) {
    +    GeneratedExtensionFinder finder(containing_type);
    +    return ParseMessageSet(input, &finder, &skipper);
    +  } else {
    +    DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
    +                                         input->GetExtensionFactory(),
    +                                         containing_type->GetDescriptor());
    +    return ParseMessageSet(input, &finder, &skipper);
    +  }
    +}
    +
    +int ExtensionSet::SpaceUsedExcludingSelf() const {
    +  int total_size =
    +      extensions_.size() * sizeof(map::value_type);
    +  for (map::const_iterator iter = extensions_.begin(),
    +       end = extensions_.end();
    +       iter != end;
    +       ++iter) {
    +    total_size += iter->second.SpaceUsedExcludingSelf();
    +  }
    +  return total_size;
    +}
    +
    +inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
    +    RepeatedPtrFieldBase* field) {
    +  return field->SpaceUsedExcludingSelf >();
    +}
    +
    +int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
    +  int total_size = 0;
    +  if (is_repeated) {
    +    switch (cpp_type(type)) {
    +#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
    +      case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
    +        total_size += sizeof(*repeated_##LOWERCASE##_value) +      \
    +            repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
    +        break
    +
    +      HANDLE_TYPE(  INT32,   int32);
    +      HANDLE_TYPE(  INT64,   int64);
    +      HANDLE_TYPE( UINT32,  uint32);
    +      HANDLE_TYPE( UINT64,  uint64);
    +      HANDLE_TYPE(  FLOAT,   float);
    +      HANDLE_TYPE( DOUBLE,  double);
    +      HANDLE_TYPE(   BOOL,    bool);
    +      HANDLE_TYPE(   ENUM,    enum);
    +      HANDLE_TYPE( STRING,  string);
    +#undef HANDLE_TYPE
    +
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        // repeated_message_value is actually a RepeatedPtrField,
    +        // but MessageLite has no SpaceUsed(), so we must directly call
    +        // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
    +        // handler.
    +        total_size += sizeof(*repeated_message_value) +
    +            RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
    +        break;
    +    }
    +  } else {
    +    switch (cpp_type(type)) {
    +      case FieldDescriptor::CPPTYPE_STRING:
    +        total_size += sizeof(*string_value) +
    +                      StringSpaceUsedExcludingSelf(*string_value);
    +        break;
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        if (is_lazy) {
    +          total_size += lazymessage_value->SpaceUsed();
    +        } else {
    +          total_size += down_cast(message_value)->SpaceUsed();
    +        }
    +        break;
    +      default:
    +        // No extra storage costs for primitive types.
    +        break;
    +    }
    +  }
    +  return total_size;
    +}
    +
    +// The Serialize*ToArray methods are only needed in the heavy library, as
    +// the lite library only generates SerializeWithCachedSizes.
    +uint8* ExtensionSet::SerializeWithCachedSizesToArray(
    +    int start_field_number, int end_field_number,
    +    uint8* target) const {
    +  map::const_iterator iter;
    +  for (iter = extensions_.lower_bound(start_field_number);
    +       iter != extensions_.end() && iter->first < end_field_number;
    +       ++iter) {
    +    target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
    +                                                               target);
    +  }
    +  return target;
    +}
    +
    +uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
    +    uint8* target) const {
    +  map::const_iterator iter;
    +  for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
    +    target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
    +        iter->first, target);
    +  }
    +  return target;
    +}
    +
    +uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
    +    int number, uint8* target) const {
    +  if (is_repeated) {
    +    if (is_packed) {
    +      if (cached_size == 0) return target;
    +
    +      target = WireFormatLite::WriteTagToArray(number,
    +          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
    +      target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
    +
    +      switch (real_type(type)) {
    +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
    +        case FieldDescriptor::TYPE_##UPPERCASE:                             \
    +          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
    +            target = WireFormatLite::Write##CAMELCASE##NoTagToArray(        \
    +              repeated_##LOWERCASE##_value->Get(i), target);                \
    +          }                                                                 \
    +          break
    +
    +        HANDLE_TYPE(   INT32,    Int32,   int32);
    +        HANDLE_TYPE(   INT64,    Int64,   int64);
    +        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
    +        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
    +        HANDLE_TYPE(  SINT32,   SInt32,   int32);
    +        HANDLE_TYPE(  SINT64,   SInt64,   int64);
    +        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
    +        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
    +        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
    +        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
    +        HANDLE_TYPE(   FLOAT,    Float,   float);
    +        HANDLE_TYPE(  DOUBLE,   Double,  double);
    +        HANDLE_TYPE(    BOOL,     Bool,    bool);
    +        HANDLE_TYPE(    ENUM,     Enum,    enum);
    +#undef HANDLE_TYPE
    +
    +        case WireFormatLite::TYPE_STRING:
    +        case WireFormatLite::TYPE_BYTES:
    +        case WireFormatLite::TYPE_GROUP:
    +        case WireFormatLite::TYPE_MESSAGE:
    +          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
    +          break;
    +      }
    +    } else {
    +      switch (real_type(type)) {
    +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
    +        case FieldDescriptor::TYPE_##UPPERCASE:                             \
    +          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
    +            target = WireFormatLite::Write##CAMELCASE##ToArray(number,      \
    +              repeated_##LOWERCASE##_value->Get(i), target);                \
    +          }                                                                 \
    +          break
    +
    +        HANDLE_TYPE(   INT32,    Int32,   int32);
    +        HANDLE_TYPE(   INT64,    Int64,   int64);
    +        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
    +        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
    +        HANDLE_TYPE(  SINT32,   SInt32,   int32);
    +        HANDLE_TYPE(  SINT64,   SInt64,   int64);
    +        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
    +        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
    +        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
    +        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
    +        HANDLE_TYPE(   FLOAT,    Float,   float);
    +        HANDLE_TYPE(  DOUBLE,   Double,  double);
    +        HANDLE_TYPE(    BOOL,     Bool,    bool);
    +        HANDLE_TYPE(  STRING,   String,  string);
    +        HANDLE_TYPE(   BYTES,    Bytes,  string);
    +        HANDLE_TYPE(    ENUM,     Enum,    enum);
    +        HANDLE_TYPE(   GROUP,    Group, message);
    +        HANDLE_TYPE( MESSAGE,  Message, message);
    +#undef HANDLE_TYPE
    +      }
    +    }
    +  } else if (!is_cleared) {
    +    switch (real_type(type)) {
    +#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
    +      case FieldDescriptor::TYPE_##UPPERCASE:                    \
    +        target = WireFormatLite::Write##CAMELCASE##ToArray(      \
    +            number, VALUE, target); \
    +        break
    +
    +      HANDLE_TYPE(   INT32,    Int32,    int32_value);
    +      HANDLE_TYPE(   INT64,    Int64,    int64_value);
    +      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
    +      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
    +      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
    +      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
    +      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
    +      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
    +      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
    +      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
    +      HANDLE_TYPE(   FLOAT,    Float,    float_value);
    +      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
    +      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
    +      HANDLE_TYPE(  STRING,   String,  *string_value);
    +      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
    +      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
    +      HANDLE_TYPE(   GROUP,    Group, *message_value);
    +#undef HANDLE_TYPE
    +      case FieldDescriptor::TYPE_MESSAGE:
    +        if (is_lazy) {
    +          target = lazymessage_value->WriteMessageToArray(number, target);
    +        } else {
    +          target = WireFormatLite::WriteMessageToArray(
    +              number, *message_value, target);
    +        }
    +        break;
    +    }
    +  }
    +  return target;
    +}
    +
    +uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
    +    int number,
    +    uint8* target) const {
    +  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    +    // Not a valid MessageSet extension, but serialize it the normal way.
    +    GOOGLE_LOG(WARNING) << "Invalid message set extension.";
    +    return SerializeFieldWithCachedSizesToArray(number, target);
    +  }
    +
    +  if (is_cleared) return target;
    +
    +  // Start group.
    +  target = io::CodedOutputStream::WriteTagToArray(
    +      WireFormatLite::kMessageSetItemStartTag, target);
    +  // Write type ID.
    +  target = WireFormatLite::WriteUInt32ToArray(
    +      WireFormatLite::kMessageSetTypeIdNumber, number, target);
    +  // Write message.
    +  if (is_lazy) {
    +    target = lazymessage_value->WriteMessageToArray(
    +        WireFormatLite::kMessageSetMessageNumber, target);
    +  } else {
    +    target = WireFormatLite::WriteMessageToArray(
    +        WireFormatLite::kMessageSetMessageNumber, *message_value, target);
    +  }
    +  // End group.
    +  target = io::CodedOutputStream::WriteTagToArray(
    +      WireFormatLite::kMessageSetItemEndTag, target);
    +  return target;
    +}
    +
    +
    +bool ExtensionSet::ParseFieldMaybeLazily(
    +    int wire_type, int field_number, io::CodedInputStream* input,
    +    ExtensionFinder* extension_finder,
    +    MessageSetFieldSkipper* field_skipper) {
    +  return ParseField(WireFormatLite::MakeTag(
    +      field_number, static_cast(wire_type)),
    +                    input, extension_finder, field_skipper);
    +}
    +
    +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    +                                   ExtensionFinder* extension_finder,
    +                                   MessageSetFieldSkipper* field_skipper) {
    +  while (true) {
    +    const uint32 tag = input->ReadTag();
    +    switch (tag) {
    +      case 0:
    +        return true;
    +      case WireFormatLite::kMessageSetItemStartTag:
    +        if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
    +          return false;
    +        }
    +        break;
    +      default:
    +        if (!ParseField(tag, input, extension_finder, field_skipper)) {
    +          return false;
    +        }
    +        break;
    +    }
    +  }
    +}
    +
    +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    +                                   const MessageLite* containing_type) {
    +  MessageSetFieldSkipper skipper(NULL);
    +  GeneratedExtensionFinder finder(containing_type);
    +  return ParseMessageSet(input, &finder, &skipper);
    +}
    +
    +bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
    +                                       ExtensionFinder* extension_finder,
    +                                       MessageSetFieldSkipper* field_skipper) {
    +  // TODO(kenton):  It would be nice to share code between this and
    +  // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
    +  // differences would be hard to factor out.
    +
    +  // This method parses a group which should contain two fields:
    +  //   required int32 type_id = 2;
    +  //   required data message = 3;
    +
    +  uint32 last_type_id = 0;
    +
    +  // If we see message data before the type_id, we'll append it to this so
    +  // we can parse it later.
    +  string message_data;
    +
    +  while (true) {
    +    const uint32 tag = input->ReadTag();
    +    if (tag == 0) return false;
    +
    +    switch (tag) {
    +      case WireFormatLite::kMessageSetTypeIdTag: {
    +        uint32 type_id;
    +        if (!input->ReadVarint32(&type_id)) return false;
    +        last_type_id = type_id;
    +
    +        if (!message_data.empty()) {
    +          // We saw some message data before the type_id.  Have to parse it
    +          // now.
    +          io::CodedInputStream sub_input(
    +              reinterpret_cast(message_data.data()),
    +              message_data.size());
    +          if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
    +                                     last_type_id, &sub_input,
    +                                     extension_finder, field_skipper)) {
    +            return false;
    +          }
    +          message_data.clear();
    +        }
    +
    +        break;
    +      }
    +
    +      case WireFormatLite::kMessageSetMessageTag: {
    +        if (last_type_id == 0) {
    +          // We haven't seen a type_id yet.  Append this data to message_data.
    +          string temp;
    +          uint32 length;
    +          if (!input->ReadVarint32(&length)) return false;
    +          if (!input->ReadString(&temp, length)) return false;
    +          io::StringOutputStream output_stream(&message_data);
    +          io::CodedOutputStream coded_output(&output_stream);
    +          coded_output.WriteVarint32(length);
    +          coded_output.WriteString(temp);
    +        } else {
    +          // Already saw type_id, so we can parse this directly.
    +          if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
    +                                     last_type_id, input,
    +                                     extension_finder, field_skipper)) {
    +            return false;
    +          }
    +        }
    +
    +        break;
    +      }
    +
    +      case WireFormatLite::kMessageSetItemEndTag: {
    +        return true;
    +      }
    +
    +      default: {
    +        if (!field_skipper->SkipField(input, tag)) return false;
    +      }
    +    }
    +  }
    +}
    +
    +void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
    +    int number,
    +    io::CodedOutputStream* output) const {
    +  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    +    // Not a valid MessageSet extension, but serialize it the normal way.
    +    SerializeFieldWithCachedSizes(number, output);
    +    return;
    +  }
    +
    +  if (is_cleared) return;
    +
    +  // Start group.
    +  output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
    +
    +  // Write type ID.
    +  WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
    +                              number,
    +                              output);
    +  // Write message.
    +  if (is_lazy) {
    +    lazymessage_value->WriteMessage(
    +        WireFormatLite::kMessageSetMessageNumber, output);
    +  } else {
    +    WireFormatLite::WriteMessageMaybeToArray(
    +        WireFormatLite::kMessageSetMessageNumber,
    +        *message_value,
    +        output);
    +  }
    +
    +  // End group.
    +  output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
    +}
    +
    +int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
    +  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    +    // Not a valid MessageSet extension, but compute the byte size for it the
    +    // normal way.
    +    return ByteSize(number);
    +  }
    +
    +  if (is_cleared) return 0;
    +
    +  int our_size = WireFormatLite::kMessageSetItemTagsSize;
    +
    +  // type_id
    +  our_size += io::CodedOutputStream::VarintSize32(number);
    +
    +  // message
    +  int message_size = 0;
    +  if (is_lazy) {
    +    message_size = lazymessage_value->ByteSize();
    +  } else {
    +    message_size = message_value->ByteSize();
    +  }
    +
    +  our_size += io::CodedOutputStream::VarintSize32(message_size);
    +  our_size += message_size;
    +
    +  return our_size;
    +}
    +
    +void ExtensionSet::SerializeMessageSetWithCachedSizes(
    +    io::CodedOutputStream* output) const {
    +  for (map::const_iterator iter = extensions_.begin();
    +       iter != extensions_.end(); ++iter) {
    +    iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
    +  }
    +}
    +
    +int ExtensionSet::MessageSetByteSize() const {
    +  int total_size = 0;
    +
    +  for (map::const_iterator iter = extensions_.begin();
    +       iter != extensions_.end(); ++iter) {
    +    total_size += iter->second.MessageSetItemByteSize(iter->first);
    +  }
    +
    +  return total_size;
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h b/toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h
    new file mode 100644
    index 000000000000..3852cea5804e
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h
    @@ -0,0 +1,91 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: jasonh@google.com (Jason Hsueh)
    +//
    +// This header is logically internal, but is made public because it is used
    +// from protocol-compiler-generated code, which may reside in other components.
    +// It provides reflection support for generated enums, and is included in
    +// generated .pb.h files and should have minimal dependencies. The methods are
    +// implemented in generated_message_reflection.cc.
    +
    +#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
    +#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
    +
    +#include 
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +  class EnumDescriptor;
    +}  // namespace protobuf
    +
    +namespace protobuf {
    +
    +// This type trait can be used to cause templates to only match proto2 enum
    +// types.
    +template  struct is_proto_enum : ::google::protobuf::internal::false_type {};
    +
    +// Returns the EnumDescriptor for enum type E, which must be a
    +// proto-declared enum type.  Code generated by the protocol compiler
    +// will include specializations of this template for each enum type declared.
    +template 
    +const EnumDescriptor* GetEnumDescriptor();
    +
    +namespace internal {
    +
    +// Helper for EnumType_Parse functions: try to parse the string 'name' as an
    +// enum name of the given type, returning true and filling in value on success,
    +// or returning false and leaving value unchanged on failure.
    +LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
    +                    const string& name,
    +                    int* value);
    +
    +template
    +bool ParseNamedEnum(const EnumDescriptor* descriptor,
    +                    const string& name,
    +                    EnumType* value) {
    +  int tmp;
    +  if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
    +  *value = static_cast(tmp);
    +  return true;
    +}
    +
    +// Just a wrapper around printing the name of a value. The main point of this
    +// function is not to be inlined, so that you can do this without including
    +// descriptor.h.
    +LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc
    new file mode 100644
    index 000000000000..536de7d92f6e
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc
    @@ -0,0 +1,1683 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#define GOOGLE_PROTOBUF_HAS_ONEOF
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +int StringSpaceUsedExcludingSelf(const string& str) {
    +  const void* start = &str;
    +  const void* end = &str + 1;
    +
    +  if (start <= str.data() && str.data() < end) {
    +    // The string's data is stored inside the string object itself.
    +    return 0;
    +  } else {
    +    return str.capacity();
    +  }
    +}
    +
    +bool ParseNamedEnum(const EnumDescriptor* descriptor,
    +                    const string& name,
    +                    int* value) {
    +  const EnumValueDescriptor* d = descriptor->FindValueByName(name);
    +  if (d == NULL) return false;
    +  *value = d->number();
    +  return true;
    +}
    +
    +const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
    +  const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
    +  return (d == NULL ? GetEmptyString() : d->name());
    +}
    +
    +// ===================================================================
    +// Helpers for reporting usage errors (e.g. trying to use GetInt32() on
    +// a string field).
    +
    +namespace {
    +
    +void ReportReflectionUsageError(
    +    const Descriptor* descriptor, const FieldDescriptor* field,
    +    const char* method, const char* description) {
    +  GOOGLE_LOG(FATAL)
    +    << "Protocol Buffer reflection usage error:\n"
    +       "  Method      : google::protobuf::Reflection::" << method << "\n"
    +       "  Message type: " << descriptor->full_name() << "\n"
    +       "  Field       : " << field->full_name() << "\n"
    +       "  Problem     : " << description;
    +}
    +
    +const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
    +  "INVALID_CPPTYPE",
    +  "CPPTYPE_INT32",
    +  "CPPTYPE_INT64",
    +  "CPPTYPE_UINT32",
    +  "CPPTYPE_UINT64",
    +  "CPPTYPE_DOUBLE",
    +  "CPPTYPE_FLOAT",
    +  "CPPTYPE_BOOL",
    +  "CPPTYPE_ENUM",
    +  "CPPTYPE_STRING",
    +  "CPPTYPE_MESSAGE"
    +};
    +
    +static void ReportReflectionUsageTypeError(
    +    const Descriptor* descriptor, const FieldDescriptor* field,
    +    const char* method,
    +    FieldDescriptor::CppType expected_type) {
    +  GOOGLE_LOG(FATAL)
    +    << "Protocol Buffer reflection usage error:\n"
    +       "  Method      : google::protobuf::Reflection::" << method << "\n"
    +       "  Message type: " << descriptor->full_name() << "\n"
    +       "  Field       : " << field->full_name() << "\n"
    +       "  Problem     : Field is not the right type for this message:\n"
    +       "    Expected  : " << cpptype_names_[expected_type] << "\n"
    +       "    Field type: " << cpptype_names_[field->cpp_type()];
    +}
    +
    +static void ReportReflectionUsageEnumTypeError(
    +    const Descriptor* descriptor, const FieldDescriptor* field,
    +    const char* method, const EnumValueDescriptor* value) {
    +  GOOGLE_LOG(FATAL)
    +    << "Protocol Buffer reflection usage error:\n"
    +       "  Method      : google::protobuf::Reflection::" << method << "\n"
    +       "  Message type: " << descriptor->full_name() << "\n"
    +       "  Field       : " << field->full_name() << "\n"
    +       "  Problem     : Enum value did not match field type:\n"
    +       "    Expected  : " << field->enum_type()->full_name() << "\n"
    +       "    Actual    : " << value->full_name();
    +}
    +
    +#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION)                      \
    +  if (!(CONDITION))                                                            \
    +    ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
    +#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION)                        \
    +  USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
    +#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION)                        \
    +  USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
    +
    +#define USAGE_CHECK_TYPE(METHOD, CPPTYPE)                                      \
    +  if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE)                 \
    +    ReportReflectionUsageTypeError(descriptor_, field, #METHOD,                \
    +                                   FieldDescriptor::CPPTYPE_##CPPTYPE)
    +
    +#define USAGE_CHECK_ENUM_VALUE(METHOD)                                         \
    +  if (value->type() != field->enum_type())                                     \
    +    ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
    +
    +#define USAGE_CHECK_MESSAGE_TYPE(METHOD)                                       \
    +  USAGE_CHECK_EQ(field->containing_type(), descriptor_,                        \
    +                 METHOD, "Field does not match message type.");
    +#define USAGE_CHECK_SINGULAR(METHOD)                                           \
    +  USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD,      \
    +                 "Field is repeated; the method requires a singular field.")
    +#define USAGE_CHECK_REPEATED(METHOD)                                           \
    +  USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD,      \
    +                 "Field is singular; the method requires a repeated field.")
    +
    +#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE)                       \
    +    USAGE_CHECK_MESSAGE_TYPE(METHOD);                                 \
    +    USAGE_CHECK_##LABEL(METHOD);                                      \
    +    USAGE_CHECK_TYPE(METHOD, CPPTYPE)
    +
    +}  // namespace
    +
    +// ===================================================================
    +
    +GeneratedMessageReflection::GeneratedMessageReflection(
    +    const Descriptor* descriptor,
    +    const Message* default_instance,
    +    const int offsets[],
    +    int has_bits_offset,
    +    int unknown_fields_offset,
    +    int extensions_offset,
    +    const DescriptorPool* descriptor_pool,
    +    MessageFactory* factory,
    +    int object_size)
    +  : descriptor_       (descriptor),
    +    default_instance_ (default_instance),
    +    offsets_          (offsets),
    +    has_bits_offset_  (has_bits_offset),
    +    unknown_fields_offset_(unknown_fields_offset),
    +    extensions_offset_(extensions_offset),
    +    object_size_      (object_size),
    +    descriptor_pool_  ((descriptor_pool == NULL) ?
    +                         DescriptorPool::generated_pool() :
    +                         descriptor_pool),
    +    message_factory_  (factory) {
    +}
    +
    +GeneratedMessageReflection::GeneratedMessageReflection(
    +    const Descriptor* descriptor,
    +    const Message* default_instance,
    +    const int offsets[],
    +    int has_bits_offset,
    +    int unknown_fields_offset,
    +    int extensions_offset,
    +    const void* default_oneof_instance,
    +    int oneof_case_offset,
    +    const DescriptorPool* descriptor_pool,
    +    MessageFactory* factory,
    +    int object_size)
    +  : descriptor_       (descriptor),
    +    default_instance_ (default_instance),
    +    default_oneof_instance_ (default_oneof_instance),
    +    offsets_          (offsets),
    +    has_bits_offset_  (has_bits_offset),
    +    oneof_case_offset_(oneof_case_offset),
    +    unknown_fields_offset_(unknown_fields_offset),
    +    extensions_offset_(extensions_offset),
    +    object_size_      (object_size),
    +    descriptor_pool_  ((descriptor_pool == NULL) ?
    +                         DescriptorPool::generated_pool() :
    +                         descriptor_pool),
    +    message_factory_  (factory) {
    +}
    +
    +GeneratedMessageReflection::~GeneratedMessageReflection() {}
    +
    +const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
    +    const Message& message) const {
    +  const void* ptr = reinterpret_cast(&message) +
    +                    unknown_fields_offset_;
    +  return *reinterpret_cast(ptr);
    +}
    +UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
    +    Message* message) const {
    +  void* ptr = reinterpret_cast(message) + unknown_fields_offset_;
    +  return reinterpret_cast(ptr);
    +}
    +
    +int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
    +  // object_size_ already includes the in-memory representation of each field
    +  // in the message, so we only need to account for additional memory used by
    +  // the fields.
    +  int total_size = object_size_;
    +
    +  total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
    +
    +  if (extensions_offset_ != -1) {
    +    total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
    +  }
    +
    +  for (int i = 0; i < descriptor_->field_count(); i++) {
    +    const FieldDescriptor* field = descriptor_->field(i);
    +
    +    if (field->is_repeated()) {
    +      switch (field->cpp_type()) {
    +#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
    +        case FieldDescriptor::CPPTYPE_##UPPERCASE :                           \
    +          total_size += GetRaw >(message, field)     \
    +                          .SpaceUsedExcludingSelf();                          \
    +          break
    +
    +        HANDLE_TYPE( INT32,  int32);
    +        HANDLE_TYPE( INT64,  int64);
    +        HANDLE_TYPE(UINT32, uint32);
    +        HANDLE_TYPE(UINT64, uint64);
    +        HANDLE_TYPE(DOUBLE, double);
    +        HANDLE_TYPE( FLOAT,  float);
    +        HANDLE_TYPE(  BOOL,   bool);
    +        HANDLE_TYPE(  ENUM,    int);
    +#undef HANDLE_TYPE
    +
    +        case FieldDescriptor::CPPTYPE_STRING:
    +          switch (field->options().ctype()) {
    +            default:  // TODO(kenton):  Support other string reps.
    +            case FieldOptions::STRING:
    +              total_size += GetRaw >(message, field)
    +                              .SpaceUsedExcludingSelf();
    +              break;
    +          }
    +          break;
    +
    +        case FieldDescriptor::CPPTYPE_MESSAGE:
    +          // We don't know which subclass of RepeatedPtrFieldBase the type is,
    +          // so we use RepeatedPtrFieldBase directly.
    +          total_size +=
    +              GetRaw(message, field)
    +                .SpaceUsedExcludingSelf >();
    +          break;
    +      }
    +    } else {
    +      if (field->containing_oneof() && !HasOneofField(message, field)) {
    +        continue;
    +      }
    +      switch (field->cpp_type()) {
    +        case FieldDescriptor::CPPTYPE_INT32 :
    +        case FieldDescriptor::CPPTYPE_INT64 :
    +        case FieldDescriptor::CPPTYPE_UINT32:
    +        case FieldDescriptor::CPPTYPE_UINT64:
    +        case FieldDescriptor::CPPTYPE_DOUBLE:
    +        case FieldDescriptor::CPPTYPE_FLOAT :
    +        case FieldDescriptor::CPPTYPE_BOOL  :
    +        case FieldDescriptor::CPPTYPE_ENUM  :
    +          // Field is inline, so we've already counted it.
    +          break;
    +
    +        case FieldDescriptor::CPPTYPE_STRING: {
    +          switch (field->options().ctype()) {
    +            default:  // TODO(kenton):  Support other string reps.
    +            case FieldOptions::STRING: {
    +              const string* ptr = GetField(message, field);
    +
    +              // Initially, the string points to the default value stored in
    +              // the prototype. Only count the string if it has been changed
    +              // from the default value.
    +              const string* default_ptr = DefaultRaw(field);
    +
    +              if (ptr != default_ptr) {
    +                // string fields are represented by just a pointer, so also
    +                // include sizeof(string) as well.
    +                total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
    +              }
    +              break;
    +            }
    +          }
    +          break;
    +        }
    +
    +        case FieldDescriptor::CPPTYPE_MESSAGE:
    +          if (&message == default_instance_) {
    +            // For singular fields, the prototype just stores a pointer to the
    +            // external type's prototype, so there is no extra memory usage.
    +          } else {
    +            const Message* sub_message = GetRaw(message, field);
    +            if (sub_message != NULL) {
    +              total_size += sub_message->SpaceUsed();
    +            }
    +          }
    +          break;
    +      }
    +    }
    +  }
    +
    +  return total_size;
    +}
    +
    +void GeneratedMessageReflection::SwapField(
    +    Message* message1,
    +    Message* message2,
    +    const FieldDescriptor* field) const {
    +  if (field->is_repeated()) {
    +    switch (field->cpp_type()) {
    +#define SWAP_ARRAYS(CPPTYPE, TYPE)                                      \
    +      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
    +        MutableRaw >(message1, field)->Swap(        \
    +            MutableRaw >(message2, field));         \
    +        break;
    +
    +      SWAP_ARRAYS(INT32 , int32 );
    +      SWAP_ARRAYS(INT64 , int64 );
    +      SWAP_ARRAYS(UINT32, uint32);
    +      SWAP_ARRAYS(UINT64, uint64);
    +      SWAP_ARRAYS(FLOAT , float );
    +      SWAP_ARRAYS(DOUBLE, double);
    +      SWAP_ARRAYS(BOOL  , bool  );
    +      SWAP_ARRAYS(ENUM  , int   );
    +#undef SWAP_ARRAYS
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        MutableRaw(message1, field)->Swap(
    +            MutableRaw(message2, field));
    +        break;
    +
    +      default:
    +        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
    +    }
    +  } else {
    +    switch (field->cpp_type()) {
    +#define SWAP_VALUES(CPPTYPE, TYPE)                                      \
    +      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
    +        std::swap(*MutableRaw(message1, field),                   \
    +                  *MutableRaw(message2, field));                  \
    +        break;
    +
    +      SWAP_VALUES(INT32 , int32 );
    +      SWAP_VALUES(INT64 , int64 );
    +      SWAP_VALUES(UINT32, uint32);
    +      SWAP_VALUES(UINT64, uint64);
    +      SWAP_VALUES(FLOAT , float );
    +      SWAP_VALUES(DOUBLE, double);
    +      SWAP_VALUES(BOOL  , bool  );
    +      SWAP_VALUES(ENUM  , int   );
    +#undef SWAP_VALUES
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        std::swap(*MutableRaw(message1, field),
    +                  *MutableRaw(message2, field));
    +        break;
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +        switch (field->options().ctype()) {
    +          default:  // TODO(kenton):  Support other string reps.
    +          case FieldOptions::STRING:
    +            std::swap(*MutableRaw(message1, field),
    +                      *MutableRaw(message2, field));
    +            break;
    +        }
    +        break;
    +
    +      default:
    +        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
    +    }
    +  }
    +}
    +
    +void GeneratedMessageReflection::SwapOneofField(
    +    Message* message1,
    +    Message* message2,
    +    const OneofDescriptor* oneof_descriptor) const {
    +  uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
    +  uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
    +
    +  int32 temp_int32;
    +  int64 temp_int64;
    +  uint32 temp_uint32;
    +  uint64 temp_uint64;
    +  float temp_float;
    +  double temp_double;
    +  bool temp_bool;
    +  int temp_int;
    +  Message* temp_message;
    +  string temp_string;
    +
    +  // Stores message1's oneof field to a temp variable.
    +  const FieldDescriptor* field1;
    +  if (oneof_case1 > 0) {
    +    field1 = descriptor_->FindFieldByNumber(oneof_case1);
    +    //oneof_descriptor->field(oneof_case1);
    +    switch (field1->cpp_type()) {
    +#define GET_TEMP_VALUE(CPPTYPE, TYPE)                                   \
    +      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
    +        temp_##TYPE = GetField(*message1, field1);                \
    +        break;
    +
    +      GET_TEMP_VALUE(INT32 , int32 );
    +      GET_TEMP_VALUE(INT64 , int64 );
    +      GET_TEMP_VALUE(UINT32, uint32);
    +      GET_TEMP_VALUE(UINT64, uint64);
    +      GET_TEMP_VALUE(FLOAT , float );
    +      GET_TEMP_VALUE(DOUBLE, double);
    +      GET_TEMP_VALUE(BOOL  , bool  );
    +      GET_TEMP_VALUE(ENUM  , int   );
    +#undef GET_TEMP_VALUE
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        temp_message = ReleaseMessage(message1, field1);
    +        break;
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +        temp_string = GetString(*message1, field1);
    +        break;
    +
    +      default:
    +        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
    +    }
    +  }
    +
    +  // Sets message1's oneof field from the message2's oneof field.
    +  if (oneof_case2 > 0) {
    +    const FieldDescriptor* field2 =
    +        descriptor_->FindFieldByNumber(oneof_case2);
    +    switch (field2->cpp_type()) {
    +#define SET_ONEOF_VALUE1(CPPTYPE, TYPE)                                 \
    +      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
    +        SetField(message1, field2, GetField(*message2, field2)); \
    +        break;
    +
    +      SET_ONEOF_VALUE1(INT32 , int32 );
    +      SET_ONEOF_VALUE1(INT64 , int64 );
    +      SET_ONEOF_VALUE1(UINT32, uint32);
    +      SET_ONEOF_VALUE1(UINT64, uint64);
    +      SET_ONEOF_VALUE1(FLOAT , float );
    +      SET_ONEOF_VALUE1(DOUBLE, double);
    +      SET_ONEOF_VALUE1(BOOL  , bool  );
    +      SET_ONEOF_VALUE1(ENUM  , int   );
    +#undef SET_ONEOF_VALUE1
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        SetAllocatedMessage(message1,
    +                            ReleaseMessage(message2, field2),
    +                            field2);
    +        break;
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +        SetString(message1, field2, GetString(*message2, field2));
    +        break;
    +
    +      default:
    +        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
    +    }
    +  } else {
    +    ClearOneof(message1, oneof_descriptor);
    +  }
    +
    +  // Sets message2's oneof field from the temp variable.
    +  if (oneof_case1 > 0) {
    +    switch (field1->cpp_type()) {
    +#define SET_ONEOF_VALUE2(CPPTYPE, TYPE)                                 \
    +      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
    +        SetField(message2, field1, temp_##TYPE);                  \
    +        break;
    +
    +      SET_ONEOF_VALUE2(INT32 , int32 );
    +      SET_ONEOF_VALUE2(INT64 , int64 );
    +      SET_ONEOF_VALUE2(UINT32, uint32);
    +      SET_ONEOF_VALUE2(UINT64, uint64);
    +      SET_ONEOF_VALUE2(FLOAT , float );
    +      SET_ONEOF_VALUE2(DOUBLE, double);
    +      SET_ONEOF_VALUE2(BOOL  , bool  );
    +      SET_ONEOF_VALUE2(ENUM  , int   );
    +#undef SET_ONEOF_VALUE2
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        SetAllocatedMessage(message2, temp_message, field1);
    +        break;
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +        SetString(message2, field1, temp_string);
    +        break;
    +
    +      default:
    +        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
    +    }
    +  } else {
    +    ClearOneof(message2, oneof_descriptor);
    +  }
    +}
    +
    +void GeneratedMessageReflection::Swap(
    +    Message* message1,
    +    Message* message2) const {
    +  if (message1 == message2) return;
    +
    +  // TODO(kenton):  Other Reflection methods should probably check this too.
    +  GOOGLE_CHECK_EQ(message1->GetReflection(), this)
    +    << "First argument to Swap() (of type \""
    +    << message1->GetDescriptor()->full_name()
    +    << "\") is not compatible with this reflection object (which is for type \""
    +    << descriptor_->full_name()
    +    << "\").  Note that the exact same class is required; not just the same "
    +       "descriptor.";
    +  GOOGLE_CHECK_EQ(message2->GetReflection(), this)
    +    << "Second argument to Swap() (of type \""
    +    << message2->GetDescriptor()->full_name()
    +    << "\") is not compatible with this reflection object (which is for type \""
    +    << descriptor_->full_name()
    +    << "\").  Note that the exact same class is required; not just the same "
    +       "descriptor.";
    +
    +  uint32* has_bits1 = MutableHasBits(message1);
    +  uint32* has_bits2 = MutableHasBits(message2);
    +  int has_bits_size = (descriptor_->field_count() + 31) / 32;
    +
    +  for (int i = 0; i < has_bits_size; i++) {
    +    std::swap(has_bits1[i], has_bits2[i]);
    +  }
    +
    +  for (int i = 0; i < descriptor_->field_count(); i++) {
    +    const FieldDescriptor* field = descriptor_->field(i);
    +    if (!field->containing_oneof()) {
    +      SwapField(message1, message2, field);
    +    }
    +  }
    +
    +  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    +    SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
    +  }
    +
    +  if (extensions_offset_ != -1) {
    +    MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
    +  }
    +
    +  MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
    +}
    +
    +void GeneratedMessageReflection::SwapFields(
    +    Message* message1,
    +    Message* message2,
    +    const vector& fields) const {
    +  if (message1 == message2) return;
    +
    +  // TODO(kenton):  Other Reflection methods should probably check this too.
    +  GOOGLE_CHECK_EQ(message1->GetReflection(), this)
    +    << "First argument to SwapFields() (of type \""
    +    << message1->GetDescriptor()->full_name()
    +    << "\") is not compatible with this reflection object (which is for type \""
    +    << descriptor_->full_name()
    +    << "\").  Note that the exact same class is required; not just the same "
    +       "descriptor.";
    +  GOOGLE_CHECK_EQ(message2->GetReflection(), this)
    +    << "Second argument to SwapFields() (of type \""
    +    << message2->GetDescriptor()->full_name()
    +    << "\") is not compatible with this reflection object (which is for type \""
    +    << descriptor_->full_name()
    +    << "\").  Note that the exact same class is required; not just the same "
    +       "descriptor.";
    +
    +  std::set swapped_oneof;
    +
    +  for (int i = 0; i < fields.size(); i++) {
    +    const FieldDescriptor* field = fields[i];
    +    if (field->is_extension()) {
    +      MutableExtensionSet(message1)->SwapExtension(
    +          MutableExtensionSet(message2),
    +          field->number());
    +    } else {
    +      if (field->containing_oneof()) {
    +        int oneof_index = field->containing_oneof()->index();
    +        // Only swap the oneof field once.
    +        if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
    +          continue;
    +        }
    +        swapped_oneof.insert(oneof_index);
    +        SwapOneofField(message1, message2, field->containing_oneof());
    +      } else {
    +        // Swap has bit.
    +        SwapBit(message1, message2, field);
    +        // Swap field.
    +        SwapField(message1, message2, field);
    +      }
    +    }
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +
    +bool GeneratedMessageReflection::HasField(const Message& message,
    +                                          const FieldDescriptor* field) const {
    +  USAGE_CHECK_MESSAGE_TYPE(HasField);
    +  USAGE_CHECK_SINGULAR(HasField);
    +
    +  if (field->is_extension()) {
    +    return GetExtensionSet(message).Has(field->number());
    +  } else {
    +    if (field->containing_oneof()) {
    +      return HasOneofField(message, field);
    +    } else {
    +      return HasBit(message, field);
    +    }
    +  }
    +}
    +
    +int GeneratedMessageReflection::FieldSize(const Message& message,
    +                                          const FieldDescriptor* field) const {
    +  USAGE_CHECK_MESSAGE_TYPE(FieldSize);
    +  USAGE_CHECK_REPEATED(FieldSize);
    +
    +  if (field->is_extension()) {
    +    return GetExtensionSet(message).ExtensionSize(field->number());
    +  } else {
    +    switch (field->cpp_type()) {
    +#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
    +      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
    +        return GetRaw >(message, field).size()
    +
    +      HANDLE_TYPE( INT32,  int32);
    +      HANDLE_TYPE( INT64,  int64);
    +      HANDLE_TYPE(UINT32, uint32);
    +      HANDLE_TYPE(UINT64, uint64);
    +      HANDLE_TYPE(DOUBLE, double);
    +      HANDLE_TYPE( FLOAT,  float);
    +      HANDLE_TYPE(  BOOL,   bool);
    +      HANDLE_TYPE(  ENUM,    int);
    +#undef HANDLE_TYPE
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        return GetRaw(message, field).size();
    +    }
    +
    +    GOOGLE_LOG(FATAL) << "Can't get here.";
    +    return 0;
    +  }
    +}
    +
    +void GeneratedMessageReflection::ClearField(
    +    Message* message, const FieldDescriptor* field) const {
    +  USAGE_CHECK_MESSAGE_TYPE(ClearField);
    +
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->ClearExtension(field->number());
    +  } else if (!field->is_repeated()) {
    +    if (field->containing_oneof()) {
    +      ClearOneofField(message, field);
    +      return;
    +    }
    +
    +    if (HasBit(*message, field)) {
    +      ClearBit(message, field);
    +
    +      // We need to set the field back to its default value.
    +      switch (field->cpp_type()) {
    +#define CLEAR_TYPE(CPPTYPE, TYPE)                                            \
    +        case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
    +          *MutableRaw(message, field) =                                \
    +            field->default_value_##TYPE();                                   \
    +          break;
    +
    +        CLEAR_TYPE(INT32 , int32 );
    +        CLEAR_TYPE(INT64 , int64 );
    +        CLEAR_TYPE(UINT32, uint32);
    +        CLEAR_TYPE(UINT64, uint64);
    +        CLEAR_TYPE(FLOAT , float );
    +        CLEAR_TYPE(DOUBLE, double);
    +        CLEAR_TYPE(BOOL  , bool  );
    +#undef CLEAR_TYPE
    +
    +        case FieldDescriptor::CPPTYPE_ENUM:
    +          *MutableRaw(message, field) =
    +            field->default_value_enum()->number();
    +          break;
    +
    +        case FieldDescriptor::CPPTYPE_STRING: {
    +          switch (field->options().ctype()) {
    +            default:  // TODO(kenton):  Support other string reps.
    +            case FieldOptions::STRING:
    +              const string* default_ptr = DefaultRaw(field);
    +              string** value = MutableRaw(message, field);
    +              if (*value != default_ptr) {
    +                if (field->has_default_value()) {
    +                  (*value)->assign(field->default_value_string());
    +                } else {
    +                  (*value)->clear();
    +                }
    +              }
    +              break;
    +          }
    +          break;
    +        }
    +
    +        case FieldDescriptor::CPPTYPE_MESSAGE:
    +          (*MutableRaw(message, field))->Clear();
    +          break;
    +      }
    +    }
    +  } else {
    +    switch (field->cpp_type()) {
    +#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
    +      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
    +        MutableRaw >(message, field)->Clear();       \
    +        break
    +
    +      HANDLE_TYPE( INT32,  int32);
    +      HANDLE_TYPE( INT64,  int64);
    +      HANDLE_TYPE(UINT32, uint32);
    +      HANDLE_TYPE(UINT64, uint64);
    +      HANDLE_TYPE(DOUBLE, double);
    +      HANDLE_TYPE( FLOAT,  float);
    +      HANDLE_TYPE(  BOOL,   bool);
    +      HANDLE_TYPE(  ENUM,    int);
    +#undef HANDLE_TYPE
    +
    +      case FieldDescriptor::CPPTYPE_STRING: {
    +        switch (field->options().ctype()) {
    +          default:  // TODO(kenton):  Support other string reps.
    +          case FieldOptions::STRING:
    +            MutableRaw >(message, field)->Clear();
    +            break;
    +        }
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_MESSAGE: {
    +        // We don't know which subclass of RepeatedPtrFieldBase the type is,
    +        // so we use RepeatedPtrFieldBase directly.
    +        MutableRaw(message, field)
    +            ->Clear >();
    +        break;
    +      }
    +    }
    +  }
    +}
    +
    +void GeneratedMessageReflection::RemoveLast(
    +    Message* message,
    +    const FieldDescriptor* field) const {
    +  USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
    +  USAGE_CHECK_REPEATED(RemoveLast);
    +
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->RemoveLast(field->number());
    +  } else {
    +    switch (field->cpp_type()) {
    +#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
    +      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
    +        MutableRaw >(message, field)->RemoveLast();  \
    +        break
    +
    +      HANDLE_TYPE( INT32,  int32);
    +      HANDLE_TYPE( INT64,  int64);
    +      HANDLE_TYPE(UINT32, uint32);
    +      HANDLE_TYPE(UINT64, uint64);
    +      HANDLE_TYPE(DOUBLE, double);
    +      HANDLE_TYPE( FLOAT,  float);
    +      HANDLE_TYPE(  BOOL,   bool);
    +      HANDLE_TYPE(  ENUM,    int);
    +#undef HANDLE_TYPE
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +        switch (field->options().ctype()) {
    +          default:  // TODO(kenton):  Support other string reps.
    +          case FieldOptions::STRING:
    +            MutableRaw >(message, field)->RemoveLast();
    +            break;
    +        }
    +        break;
    +
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        MutableRaw(message, field)
    +            ->RemoveLast >();
    +        break;
    +    }
    +  }
    +}
    +
    +Message* GeneratedMessageReflection::ReleaseLast(
    +    Message* message,
    +    const FieldDescriptor* field) const {
    +  USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
    +
    +  if (field->is_extension()) {
    +    return static_cast(
    +        MutableExtensionSet(message)->ReleaseLast(field->number()));
    +  } else {
    +    return MutableRaw(message, field)
    +        ->ReleaseLast >();
    +  }
    +}
    +
    +void GeneratedMessageReflection::SwapElements(
    +    Message* message,
    +    const FieldDescriptor* field,
    +    int index1,
    +    int index2) const {
    +  USAGE_CHECK_MESSAGE_TYPE(Swap);
    +  USAGE_CHECK_REPEATED(Swap);
    +
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
    +  } else {
    +    switch (field->cpp_type()) {
    +#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
    +      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
    +        MutableRaw >(message, field)                 \
    +            ->SwapElements(index1, index2);                                   \
    +        break
    +
    +      HANDLE_TYPE( INT32,  int32);
    +      HANDLE_TYPE( INT64,  int64);
    +      HANDLE_TYPE(UINT32, uint32);
    +      HANDLE_TYPE(UINT64, uint64);
    +      HANDLE_TYPE(DOUBLE, double);
    +      HANDLE_TYPE( FLOAT,  float);
    +      HANDLE_TYPE(  BOOL,   bool);
    +      HANDLE_TYPE(  ENUM,    int);
    +#undef HANDLE_TYPE
    +
    +      case FieldDescriptor::CPPTYPE_STRING:
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        MutableRaw(message, field)
    +            ->SwapElements(index1, index2);
    +        break;
    +    }
    +  }
    +}
    +
    +namespace {
    +// Comparison functor for sorting FieldDescriptors by field number.
    +struct FieldNumberSorter {
    +  bool operator()(const FieldDescriptor* left,
    +                  const FieldDescriptor* right) const {
    +    return left->number() < right->number();
    +  }
    +};
    +}  // namespace
    +
    +void GeneratedMessageReflection::ListFields(
    +    const Message& message,
    +    vector* output) const {
    +  output->clear();
    +
    +  // Optimization:  The default instance never has any fields set.
    +  if (&message == default_instance_) return;
    +
    +  for (int i = 0; i < descriptor_->field_count(); i++) {
    +    const FieldDescriptor* field = descriptor_->field(i);
    +    if (field->is_repeated()) {
    +      if (FieldSize(message, field) > 0) {
    +        output->push_back(field);
    +      }
    +    } else {
    +      if (field->containing_oneof()) {
    +        if (HasOneofField(message, field)) {
    +          output->push_back(field);
    +        }
    +      } else if (HasBit(message, field)) {
    +        output->push_back(field);
    +      }
    +    }
    +  }
    +
    +  if (extensions_offset_ != -1) {
    +    GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
    +                                          output);
    +  }
    +
    +  // ListFields() must sort output by field number.
    +  sort(output->begin(), output->end(), FieldNumberSorter());
    +}
    +
    +// -------------------------------------------------------------------
    +
    +#undef DEFINE_PRIMITIVE_ACCESSORS
    +#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE)        \
    +  PASSTYPE GeneratedMessageReflection::Get##TYPENAME(                        \
    +      const Message& message, const FieldDescriptor* field) const {          \
    +    USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                       \
    +    if (field->is_extension()) {                                             \
    +      return GetExtensionSet(message).Get##TYPENAME(                         \
    +        field->number(), field->default_value_##PASSTYPE());                 \
    +    } else {                                                                 \
    +      return GetField(message, field);                                 \
    +    }                                                                        \
    +  }                                                                          \
    +                                                                             \
    +  void GeneratedMessageReflection::Set##TYPENAME(                            \
    +      Message* message, const FieldDescriptor* field,                        \
    +      PASSTYPE value) const {                                                \
    +    USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                       \
    +    if (field->is_extension()) {                                             \
    +      return MutableExtensionSet(message)->Set##TYPENAME(                    \
    +        field->number(), field->type(), value, field);                       \
    +    } else {                                                                 \
    +      SetField(message, field, value);                                 \
    +    }                                                                        \
    +  }                                                                          \
    +                                                                             \
    +  PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME(                \
    +      const Message& message,                                                \
    +      const FieldDescriptor* field, int index) const {                       \
    +    USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
    +    if (field->is_extension()) {                                             \
    +      return GetExtensionSet(message).GetRepeated##TYPENAME(                 \
    +        field->number(), index);                                             \
    +    } else {                                                                 \
    +      return GetRepeatedField(message, field, index);                  \
    +    }                                                                        \
    +  }                                                                          \
    +                                                                             \
    +  void GeneratedMessageReflection::SetRepeated##TYPENAME(                    \
    +      Message* message, const FieldDescriptor* field,                        \
    +      int index, PASSTYPE value) const {                                     \
    +    USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
    +    if (field->is_extension()) {                                             \
    +      MutableExtensionSet(message)->SetRepeated##TYPENAME(                   \
    +        field->number(), index, value);                                      \
    +    } else {                                                                 \
    +      SetRepeatedField(message, field, index, value);                  \
    +    }                                                                        \
    +  }                                                                          \
    +                                                                             \
    +  void GeneratedMessageReflection::Add##TYPENAME(                            \
    +      Message* message, const FieldDescriptor* field,                        \
    +      PASSTYPE value) const {                                                \
    +    USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                       \
    +    if (field->is_extension()) {                                             \
    +      MutableExtensionSet(message)->Add##TYPENAME(                           \
    +        field->number(), field->type(), field->options().packed(), value,    \
    +        field);                                                              \
    +    } else {                                                                 \
    +      AddField(message, field, value);                                 \
    +    }                                                                        \
    +  }
    +
    +DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 )
    +DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 )
    +DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
    +DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
    +DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT )
    +DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
    +DEFINE_PRIMITIVE_ACCESSORS(Bool  , bool  , bool  , BOOL  )
    +#undef DEFINE_PRIMITIVE_ACCESSORS
    +
    +// -------------------------------------------------------------------
    +
    +string GeneratedMessageReflection::GetString(
    +    const Message& message, const FieldDescriptor* field) const {
    +  USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
    +  if (field->is_extension()) {
    +    return GetExtensionSet(message).GetString(field->number(),
    +                                              field->default_value_string());
    +  } else {
    +    switch (field->options().ctype()) {
    +      default:  // TODO(kenton):  Support other string reps.
    +      case FieldOptions::STRING:
    +        return *GetField(message, field);
    +    }
    +
    +    GOOGLE_LOG(FATAL) << "Can't get here.";
    +    return GetEmptyString();  // Make compiler happy.
    +  }
    +}
    +
    +const string& GeneratedMessageReflection::GetStringReference(
    +    const Message& message,
    +    const FieldDescriptor* field, string* scratch) const {
    +  USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
    +  if (field->is_extension()) {
    +    return GetExtensionSet(message).GetString(field->number(),
    +                                              field->default_value_string());
    +  } else {
    +    switch (field->options().ctype()) {
    +      default:  // TODO(kenton):  Support other string reps.
    +      case FieldOptions::STRING:
    +        return *GetField(message, field);
    +    }
    +
    +    GOOGLE_LOG(FATAL) << "Can't get here.";
    +    return GetEmptyString();  // Make compiler happy.
    +  }
    +}
    +
    +
    +void GeneratedMessageReflection::SetString(
    +    Message* message, const FieldDescriptor* field,
    +    const string& value) const {
    +  USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
    +  if (field->is_extension()) {
    +    return MutableExtensionSet(message)->SetString(field->number(),
    +                                                   field->type(), value, field);
    +  } else {
    +    switch (field->options().ctype()) {
    +      default:  // TODO(kenton):  Support other string reps.
    +      case FieldOptions::STRING: {
    +        if (field->containing_oneof() && !HasOneofField(*message, field)) {
    +          ClearOneof(message, field->containing_oneof());
    +          *MutableField(message, field) = new string;
    +        }
    +        string** ptr = MutableField(message, field);
    +        if (*ptr == DefaultRaw(field)) {
    +          *ptr = new string(value);
    +        } else {
    +          (*ptr)->assign(value);
    +        }
    +        break;
    +      }
    +    }
    +  }
    +}
    +
    +
    +string GeneratedMessageReflection::GetRepeatedString(
    +    const Message& message, const FieldDescriptor* field, int index) const {
    +  USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
    +  if (field->is_extension()) {
    +    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
    +  } else {
    +    switch (field->options().ctype()) {
    +      default:  // TODO(kenton):  Support other string reps.
    +      case FieldOptions::STRING:
    +        return GetRepeatedPtrField(message, field, index);
    +    }
    +
    +    GOOGLE_LOG(FATAL) << "Can't get here.";
    +    return GetEmptyString();  // Make compiler happy.
    +  }
    +}
    +
    +const string& GeneratedMessageReflection::GetRepeatedStringReference(
    +    const Message& message, const FieldDescriptor* field,
    +    int index, string* scratch) const {
    +  USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
    +  if (field->is_extension()) {
    +    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
    +  } else {
    +    switch (field->options().ctype()) {
    +      default:  // TODO(kenton):  Support other string reps.
    +      case FieldOptions::STRING:
    +        return GetRepeatedPtrField(message, field, index);
    +    }
    +
    +    GOOGLE_LOG(FATAL) << "Can't get here.";
    +    return GetEmptyString();  // Make compiler happy.
    +  }
    +}
    +
    +
    +void GeneratedMessageReflection::SetRepeatedString(
    +    Message* message, const FieldDescriptor* field,
    +    int index, const string& value) const {
    +  USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->SetRepeatedString(
    +      field->number(), index, value);
    +  } else {
    +    switch (field->options().ctype()) {
    +      default:  // TODO(kenton):  Support other string reps.
    +      case FieldOptions::STRING:
    +        *MutableRepeatedField(message, field, index) = value;
    +        break;
    +    }
    +  }
    +}
    +
    +
    +void GeneratedMessageReflection::AddString(
    +    Message* message, const FieldDescriptor* field,
    +    const string& value) const {
    +  USAGE_CHECK_ALL(AddString, REPEATED, STRING);
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->AddString(field->number(),
    +                                            field->type(), value, field);
    +  } else {
    +    switch (field->options().ctype()) {
    +      default:  // TODO(kenton):  Support other string reps.
    +      case FieldOptions::STRING:
    +        *AddField(message, field) = value;
    +        break;
    +    }
    +  }
    +}
    +
    +
    +// -------------------------------------------------------------------
    +
    +const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
    +    const Message& message, const FieldDescriptor* field) const {
    +  USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM);
    +
    +  int value;
    +  if (field->is_extension()) {
    +    value = GetExtensionSet(message).GetEnum(
    +      field->number(), field->default_value_enum()->number());
    +  } else {
    +    value = GetField(message, field);
    +  }
    +  const EnumValueDescriptor* result =
    +    field->enum_type()->FindValueByNumber(value);
    +  GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
    +                        << field->full_name() << " of type "
    +                        << field->enum_type()->full_name() << ".";
    +  return result;
    +}
    +
    +void GeneratedMessageReflection::SetEnum(
    +    Message* message, const FieldDescriptor* field,
    +    const EnumValueDescriptor* value) const {
    +  USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM);
    +  USAGE_CHECK_ENUM_VALUE(SetEnum);
    +
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
    +                                          value->number(), field);
    +  } else {
    +    SetField(message, field, value->number());
    +  }
    +}
    +
    +const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
    +    const Message& message, const FieldDescriptor* field, int index) const {
    +  USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM);
    +
    +  int value;
    +  if (field->is_extension()) {
    +    value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
    +  } else {
    +    value = GetRepeatedField(message, field, index);
    +  }
    +  const EnumValueDescriptor* result =
    +    field->enum_type()->FindValueByNumber(value);
    +  GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
    +                        << field->full_name() << " of type "
    +                        << field->enum_type()->full_name() << ".";
    +  return result;
    +}
    +
    +void GeneratedMessageReflection::SetRepeatedEnum(
    +    Message* message,
    +    const FieldDescriptor* field, int index,
    +    const EnumValueDescriptor* value) const {
    +  USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
    +  USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
    +
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->SetRepeatedEnum(
    +      field->number(), index, value->number());
    +  } else {
    +    SetRepeatedField(message, field, index, value->number());
    +  }
    +}
    +
    +void GeneratedMessageReflection::AddEnum(
    +    Message* message, const FieldDescriptor* field,
    +    const EnumValueDescriptor* value) const {
    +  USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
    +  USAGE_CHECK_ENUM_VALUE(AddEnum);
    +
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
    +                                          field->options().packed(),
    +                                          value->number(), field);
    +  } else {
    +    AddField(message, field, value->number());
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +
    +const Message& GeneratedMessageReflection::GetMessage(
    +    const Message& message, const FieldDescriptor* field,
    +    MessageFactory* factory) const {
    +  USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
    +
    +  if (factory == NULL) factory = message_factory_;
    +
    +  if (field->is_extension()) {
    +    return static_cast(
    +        GetExtensionSet(message).GetMessage(
    +          field->number(), field->message_type(), factory));
    +  } else {
    +    const Message* result;
    +    result = GetRaw(message, field);
    +    if (result == NULL) {
    +      result = DefaultRaw(field);
    +    }
    +    return *result;
    +  }
    +}
    +
    +Message* GeneratedMessageReflection::MutableMessage(
    +    Message* message, const FieldDescriptor* field,
    +    MessageFactory* factory) const {
    +  if (factory == NULL) factory = message_factory_;
    +
    +  if (field->is_extension()) {
    +    return static_cast(
    +        MutableExtensionSet(message)->MutableMessage(field, factory));
    +  } else {
    +    Message* result;
    +    Message** result_holder = MutableRaw(message, field);
    +
    +    if (field->containing_oneof()) {
    +      if (!HasOneofField(*message, field)) {
    +        ClearOneof(message, field->containing_oneof());
    +        result_holder = MutableField(message, field);
    +        const Message* default_message = DefaultRaw(field);
    +        *result_holder = default_message->New();
    +      }
    +    } else {
    +      SetBit(message, field);
    +    }
    +
    +    if (*result_holder == NULL) {
    +      const Message* default_message = DefaultRaw(field);
    +      *result_holder = default_message->New();
    +    }
    +    result = *result_holder;
    +    return result;
    +  }
    +}
    +
    +void GeneratedMessageReflection::SetAllocatedMessage(
    +    Message* message,
    +    Message* sub_message,
    +    const FieldDescriptor* field) const {
    +  USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
    +
    +  if (field->is_extension()) {
    +    MutableExtensionSet(message)->SetAllocatedMessage(
    +        field->number(), field->type(), field, sub_message);
    +  } else {
    +    if (field->containing_oneof()) {
    +      if (sub_message == NULL) {
    +        ClearOneof(message, field->containing_oneof());
    +        return;
    +      }
    +        ClearOneof(message, field->containing_oneof());
    +        *MutableRaw(message, field) = sub_message;
    +      SetOneofCase(message, field);
    +      return;
    +    }
    +
    +    if (sub_message == NULL) {
    +      ClearBit(message, field);
    +    } else {
    +      SetBit(message, field);
    +    }
    +    Message** sub_message_holder = MutableRaw(message, field);
    +    delete *sub_message_holder;
    +    *sub_message_holder = sub_message;
    +  }
    +}
    +
    +Message* GeneratedMessageReflection::ReleaseMessage(
    +    Message* message,
    +    const FieldDescriptor* field,
    +    MessageFactory* factory) const {
    +  USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
    +
    +  if (factory == NULL) factory = message_factory_;
    +
    +  if (field->is_extension()) {
    +    return static_cast(
    +        MutableExtensionSet(message)->ReleaseMessage(field, factory));
    +  } else {
    +    ClearBit(message, field);
    +    if (field->containing_oneof()) {
    +      if (HasOneofField(*message, field)) {
    +        *MutableOneofCase(message, field->containing_oneof()) = 0;
    +      } else {
    +        return NULL;
    +      }
    +    }
    +    Message** result = MutableRaw(message, field);
    +    Message* ret = *result;
    +    *result = NULL;
    +    return ret;
    +  }
    +}
    +
    +const Message& GeneratedMessageReflection::GetRepeatedMessage(
    +    const Message& message, const FieldDescriptor* field, int index) const {
    +  USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
    +
    +  if (field->is_extension()) {
    +    return static_cast(
    +        GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
    +  } else {
    +    return GetRaw(message, field)
    +        .Get >(index);
    +  }
    +}
    +
    +Message* GeneratedMessageReflection::MutableRepeatedMessage(
    +    Message* message, const FieldDescriptor* field, int index) const {
    +  USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
    +
    +  if (field->is_extension()) {
    +    return static_cast(
    +        MutableExtensionSet(message)->MutableRepeatedMessage(
    +          field->number(), index));
    +  } else {
    +    return MutableRaw(message, field)
    +        ->Mutable >(index);
    +  }
    +}
    +
    +Message* GeneratedMessageReflection::AddMessage(
    +    Message* message, const FieldDescriptor* field,
    +    MessageFactory* factory) const {
    +  USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
    +
    +  if (factory == NULL) factory = message_factory_;
    +
    +  if (field->is_extension()) {
    +    return static_cast(
    +        MutableExtensionSet(message)->AddMessage(field, factory));
    +  } else {
    +    // We can't use AddField() because RepeatedPtrFieldBase doesn't
    +    // know how to allocate one.
    +    RepeatedPtrFieldBase* repeated =
    +        MutableRaw(message, field);
    +    Message* result = repeated->AddFromCleared >();
    +    if (result == NULL) {
    +      // We must allocate a new object.
    +      const Message* prototype;
    +      if (repeated->size() == 0) {
    +        prototype = factory->GetPrototype(field->message_type());
    +      } else {
    +        prototype = &repeated->Get >(0);
    +      }
    +      result = prototype->New();
    +      repeated->AddAllocated >(result);
    +    }
    +    return result;
    +  }
    +}
    +
    +void* GeneratedMessageReflection::MutableRawRepeatedField(
    +    Message* message, const FieldDescriptor* field,
    +    FieldDescriptor::CppType cpptype,
    +    int ctype, const Descriptor* desc) const {
    +  USAGE_CHECK_REPEATED("MutableRawRepeatedField");
    +  if (field->cpp_type() != cpptype)
    +    ReportReflectionUsageTypeError(descriptor_,
    +        field, "MutableRawRepeatedField", cpptype);
    +  if (ctype >= 0)
    +    GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
    +  if (desc != NULL)
    +    GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
    +  if (field->is_extension())
    +    return MutableExtensionSet(message)->MutableRawRepeatedField(
    +        field->number(), field->type(), field->is_packed(), field);
    +  else
    +    return reinterpret_cast(message) + offsets_[field->index()];
    +}
    +
    +const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
    +    const Message& message,
    +    const OneofDescriptor* oneof_descriptor) const {
    +  uint32 field_number = GetOneofCase(message, oneof_descriptor);
    +  if (field_number == 0) {
    +    return NULL;
    +  }
    +  return descriptor_->FindFieldByNumber(field_number);
    +}
    +
    +// -----------------------------------------------------------------------------
    +
    +const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
    +    const string& name) const {
    +  if (extensions_offset_ == -1) return NULL;
    +
    +  const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
    +  if (result != NULL && result->containing_type() == descriptor_) {
    +    return result;
    +  }
    +
    +  if (descriptor_->options().message_set_wire_format()) {
    +    // MessageSet extensions may be identified by type name.
    +    const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
    +    if (type != NULL) {
    +      // Look for a matching extension in the foreign type's scope.
    +      for (int i = 0; i < type->extension_count(); i++) {
    +        const FieldDescriptor* extension = type->extension(i);
    +        if (extension->containing_type() == descriptor_ &&
    +            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
    +            extension->is_optional() &&
    +            extension->message_type() == type) {
    +          // Found it.
    +          return extension;
    +        }
    +      }
    +    }
    +  }
    +
    +  return NULL;
    +}
    +
    +const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
    +    int number) const {
    +  if (extensions_offset_ == -1) return NULL;
    +  return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
    +}
    +
    +// ===================================================================
    +// Some private helpers.
    +
    +// These simple template accessors obtain pointers (or references) to
    +// the given field.
    +template 
    +inline const Type& GeneratedMessageReflection::GetRaw(
    +    const Message& message, const FieldDescriptor* field) const {
    +  if (field->containing_oneof() && !HasOneofField(message, field)) {
    +    return DefaultRaw(field);
    +  }
    +  int index = field->containing_oneof() ?
    +      descriptor_->field_count() + field->containing_oneof()->index() :
    +      field->index();
    +  const void* ptr = reinterpret_cast(&message) +
    +      offsets_[index];
    +  return *reinterpret_cast(ptr);
    +}
    +
    +template 
    +inline Type* GeneratedMessageReflection::MutableRaw(
    +    Message* message, const FieldDescriptor* field) const {
    +  int index = field->containing_oneof() ?
    +      descriptor_->field_count() + field->containing_oneof()->index() :
    +      field->index();
    +  void* ptr = reinterpret_cast(message) + offsets_[index];
    +  return reinterpret_cast(ptr);
    +}
    +
    +template 
    +inline const Type& GeneratedMessageReflection::DefaultRaw(
    +    const FieldDescriptor* field) const {
    +  const void* ptr = field->containing_oneof() ?
    +      reinterpret_cast(default_oneof_instance_) +
    +      offsets_[field->index()] :
    +      reinterpret_cast(default_instance_) +
    +      offsets_[field->index()];
    +  return *reinterpret_cast(ptr);
    +}
    +
    +inline const uint32* GeneratedMessageReflection::GetHasBits(
    +    const Message& message) const {
    +  const void* ptr = reinterpret_cast(&message) + has_bits_offset_;
    +  return reinterpret_cast(ptr);
    +}
    +inline uint32* GeneratedMessageReflection::MutableHasBits(
    +    Message* message) const {
    +  void* ptr = reinterpret_cast(message) + has_bits_offset_;
    +  return reinterpret_cast(ptr);
    +}
    +
    +inline uint32 GeneratedMessageReflection::GetOneofCase(
    +    const Message& message,
    +    const OneofDescriptor* oneof_descriptor) const {
    +  const void* ptr = reinterpret_cast(&message)
    +      + oneof_case_offset_;
    +  return reinterpret_cast(ptr)[oneof_descriptor->index()];
    +}
    +
    +inline uint32* GeneratedMessageReflection::MutableOneofCase(
    +    Message* message,
    +    const OneofDescriptor* oneof_descriptor) const {
    +  void* ptr = reinterpret_cast(message) + oneof_case_offset_;
    +  return &(reinterpret_cast(ptr)[oneof_descriptor->index()]);
    +}
    +
    +inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
    +    const Message& message) const {
    +  GOOGLE_DCHECK_NE(extensions_offset_, -1);
    +  const void* ptr = reinterpret_cast(&message) +
    +                    extensions_offset_;
    +  return *reinterpret_cast(ptr);
    +}
    +inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
    +    Message* message) const {
    +  GOOGLE_DCHECK_NE(extensions_offset_, -1);
    +  void* ptr = reinterpret_cast(message) + extensions_offset_;
    +  return reinterpret_cast(ptr);
    +}
    +
    +// Simple accessors for manipulating has_bits_.
    +inline bool GeneratedMessageReflection::HasBit(
    +    const Message& message, const FieldDescriptor* field) const {
    +  return GetHasBits(message)[field->index() / 32] &
    +    (1 << (field->index() % 32));
    +}
    +
    +inline void GeneratedMessageReflection::SetBit(
    +    Message* message, const FieldDescriptor* field) const {
    +  MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
    +}
    +
    +inline void GeneratedMessageReflection::ClearBit(
    +    Message* message, const FieldDescriptor* field) const {
    +  MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
    +}
    +
    +inline void GeneratedMessageReflection::SwapBit(
    +    Message* message1, Message* message2, const FieldDescriptor* field) const {
    +  bool temp_has_bit = HasBit(*message1, field);
    +  if (HasBit(*message2, field)) {
    +    SetBit(message1, field);
    +  } else {
    +    ClearBit(message1, field);
    +  }
    +  if (temp_has_bit) {
    +    SetBit(message2, field);
    +  } else {
    +    ClearBit(message2, field);
    +  }
    +}
    +
    +inline bool GeneratedMessageReflection::HasOneof(
    +    const Message& message, const OneofDescriptor* oneof_descriptor) const {
    +  return (GetOneofCase(message, oneof_descriptor) > 0);
    +}
    +
    +inline bool GeneratedMessageReflection::HasOneofField(
    +    const Message& message, const FieldDescriptor* field) const {
    +  return (GetOneofCase(message, field->containing_oneof()) == field->number());
    +}
    +
    +inline void GeneratedMessageReflection::SetOneofCase(
    +    Message* message, const FieldDescriptor* field) const {
    +  *MutableOneofCase(message, field->containing_oneof()) = field->number();
    +}
    +
    +inline void GeneratedMessageReflection::ClearOneofField(
    +    Message* message, const FieldDescriptor* field) const {
    +  if (HasOneofField(*message, field)) {
    +    ClearOneof(message, field->containing_oneof());
    +  }
    +}
    +
    +inline void GeneratedMessageReflection::ClearOneof(
    +    Message* message, const OneofDescriptor* oneof_descriptor) const {
    +  // TODO(jieluo): Consider to cache the unused object instead of deleting
    +  // it. It will be much faster if an aplication switches a lot from
    +  // a few oneof fields.  Time/space tradeoff
    +  uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
    +  if (oneof_case > 0) {
    +    const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
    +    switch (field->cpp_type()) {
    +      case FieldDescriptor::CPPTYPE_STRING: {
    +        switch (field->options().ctype()) {
    +          default:  // TODO(kenton):  Support other string reps.
    +          case FieldOptions::STRING:
    +            delete *MutableRaw(message, field);
    +            break;
    +        }
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_MESSAGE:
    +        delete *MutableRaw(message, field);
    +        break;
    +      default:
    +        break;
    +    }
    +
    +    *MutableOneofCase(message, oneof_descriptor) = 0;
    +  }
    +}
    +
    +// Template implementations of basic accessors.  Inline because each
    +// template instance is only called from one location.  These are
    +// used for all types except messages.
    +template 
    +inline const Type& GeneratedMessageReflection::GetField(
    +    const Message& message, const FieldDescriptor* field) const {
    +  return GetRaw(message, field);
    +}
    +
    +template 
    +inline void GeneratedMessageReflection::SetField(
    +    Message* message, const FieldDescriptor* field, const Type& value) const {
    +  if (field->containing_oneof() && !HasOneofField(*message, field)) {
    +    ClearOneof(message, field->containing_oneof());
    +  }
    +  *MutableRaw(message, field) = value;
    +  field->containing_oneof() ?
    +      SetOneofCase(message, field) : SetBit(message, field);
    +}
    +
    +template 
    +inline Type* GeneratedMessageReflection::MutableField(
    +    Message* message, const FieldDescriptor* field) const {
    +  field->containing_oneof() ?
    +      SetOneofCase(message, field) : SetBit(message, field);
    +  return MutableRaw(message, field);
    +}
    +
    +template 
    +inline const Type& GeneratedMessageReflection::GetRepeatedField(
    +    const Message& message, const FieldDescriptor* field, int index) const {
    +  return GetRaw >(message, field).Get(index);
    +}
    +
    +template 
    +inline const Type& GeneratedMessageReflection::GetRepeatedPtrField(
    +    const Message& message, const FieldDescriptor* field, int index) const {
    +  return GetRaw >(message, field).Get(index);
    +}
    +
    +template 
    +inline void GeneratedMessageReflection::SetRepeatedField(
    +    Message* message, const FieldDescriptor* field,
    +    int index, Type value) const {
    +  MutableRaw >(message, field)->Set(index, value);
    +}
    +
    +template 
    +inline Type* GeneratedMessageReflection::MutableRepeatedField(
    +    Message* message, const FieldDescriptor* field, int index) const {
    +  RepeatedPtrField* repeated =
    +    MutableRaw >(message, field);
    +  return repeated->Mutable(index);
    +}
    +
    +template 
    +inline void GeneratedMessageReflection::AddField(
    +    Message* message, const FieldDescriptor* field, const Type& value) const {
    +  MutableRaw >(message, field)->Add(value);
    +}
    +
    +template 
    +inline Type* GeneratedMessageReflection::AddField(
    +    Message* message, const FieldDescriptor* field) const {
    +  RepeatedPtrField* repeated =
    +    MutableRaw >(message, field);
    +  return repeated->Add();
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h
    new file mode 100644
    index 000000000000..b6671ad06b04
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h
    @@ -0,0 +1,504 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// This header is logically internal, but is made public because it is used
    +// from protocol-compiler-generated code, which may reside in other components.
    +
    +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
    +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
    +
    +#include 
    +#include 
    +#include 
    +// TODO(jasonh): Remove this once the compiler change to directly include this
    +// is released to components.
    +#include 
    +#include 
    +#include 
    +
    +
    +namespace google {
    +namespace upb {
    +namespace google_opensource {
    +class GMR_Handlers;
    +}  // namespace google_opensource
    +}  // namespace upb
    +
    +namespace protobuf {
    +  class DescriptorPool;
    +}
    +
    +namespace protobuf {
    +namespace internal {
    +class DefaultEmptyOneof;
    +
    +// Defined in this file.
    +class GeneratedMessageReflection;
    +
    +// Defined in other files.
    +class ExtensionSet;             // extension_set.h
    +
    +// THIS CLASS IS NOT INTENDED FOR DIRECT USE.  It is intended for use
    +// by generated code.  This class is just a big hack that reduces code
    +// size.
    +//
    +// A GeneratedMessageReflection is an implementation of Reflection
    +// which expects all fields to be backed by simple variables located in
    +// memory.  The locations are given using a base pointer and a set of
    +// offsets.
    +//
    +// It is required that the user represents fields of each type in a standard
    +// way, so that GeneratedMessageReflection can cast the void* pointer to
    +// the appropriate type.  For primitive fields and string fields, each field
    +// should be represented using the obvious C++ primitive type.  Enums and
    +// Messages are different:
    +//  - Singular Message fields are stored as a pointer to a Message.  These
    +//    should start out NULL, except for in the default instance where they
    +//    should start out pointing to other default instances.
    +//  - Enum fields are stored as an int.  This int must always contain
    +//    a valid value, such that EnumDescriptor::FindValueByNumber() would
    +//    not return NULL.
    +//  - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
    +//    of whatever type the individual field would be.  Strings and
    +//    Messages use RepeatedPtrFields while everything else uses
    +//    RepeatedFields.
    +class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
    + public:
    +  // Constructs a GeneratedMessageReflection.
    +  // Parameters:
    +  //   descriptor:    The descriptor for the message type being implemented.
    +  //   default_instance:  The default instance of the message.  This is only
    +  //                  used to obtain pointers to default instances of embedded
    +  //                  messages, which GetMessage() will return if the particular
    +  //                  sub-message has not been initialized yet.  (Thus, all
    +  //                  embedded message fields *must* have non-NULL pointers
    +  //                  in the default instance.)
    +  //   offsets:       An array of ints giving the byte offsets, relative to
    +  //                  the start of the message object, of each field.  These can
    +  //                  be computed at compile time using the
    +  //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
    +  //                  below.
    +  //   has_bits_offset:  Offset in the message of an array of uint32s of size
    +  //                  descriptor->field_count()/32, rounded up.  This is a
    +  //                  bitfield where each bit indicates whether or not the
    +  //                  corresponding field of the message has been initialized.
    +  //                  The bit for field index i is obtained by the expression:
    +  //                    has_bits[i / 32] & (1 << (i % 32))
    +  //   unknown_fields_offset:  Offset in the message of the UnknownFieldSet for
    +  //                  the message.
    +  //   extensions_offset:  Offset in the message of the ExtensionSet for the
    +  //                  message, or -1 if the message type has no extension
    +  //                  ranges.
    +  //   pool:          DescriptorPool to search for extension definitions.  Only
    +  //                  used by FindKnownExtensionByName() and
    +  //                  FindKnownExtensionByNumber().
    +  //   factory:       MessageFactory to use to construct extension messages.
    +  //   object_size:   The size of a message object of this type, as measured
    +  //                  by sizeof().
    +  GeneratedMessageReflection(const Descriptor* descriptor,
    +                             const Message* default_instance,
    +                             const int offsets[],
    +                             int has_bits_offset,
    +                             int unknown_fields_offset,
    +                             int extensions_offset,
    +                             const DescriptorPool* pool,
    +                             MessageFactory* factory,
    +                             int object_size);
    +
    +  // Similar with the construction above. Call this construction if the
    +  // message has oneof definition.
    +  // Parameters:
    +  //   offsets:       An array of ints giving the byte offsets.
    +  //                  For each oneof field, the offset is relative to the
    +  //                  default_oneof_instance. These can be computed at compile
    +  //                  time using the
    +  //                  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro.
    +  //                  For each none oneof field, the offset is related to
    +  //                  the start of the message object.  These can be computed
    +  //                  at compile time using the
    +  //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
    +  //                  Besides offsets for all fields, this array also contains
    +  //                  offsets for oneof unions. The offset of the i-th oneof
    +  //                  union is offsets[descriptor->field_count() + i].
    +  //   default_oneof_instance: The default instance of the oneofs. It is a
    +  //                  struct holding the default value of all oneof fields
    +  //                  for this message. It is only used to obtain pointers
    +  //                  to default instances of oneof fields, which Get
    +  //                  methods will return if the field is not set.
    +  //   oneof_case_offset:  Offset in the message of an array of uint32s of
    +  //                  size descriptor->oneof_decl_count().  Each uint32
    +  //                  indicates what field is set for each oneof.
    +  //   other parameters are the same with the construction above.
    +  GeneratedMessageReflection(const Descriptor* descriptor,
    +                             const Message* default_instance,
    +                             const int offsets[],
    +                             int has_bits_offset,
    +                             int unknown_fields_offset,
    +                             int extensions_offset,
    +                             const void* default_oneof_instance,
    +                             int oneof_case_offset,
    +                             const DescriptorPool* pool,
    +                             MessageFactory* factory,
    +                             int object_size);
    +  ~GeneratedMessageReflection();
    +
    +  // implements Reflection -------------------------------------------
    +
    +  const UnknownFieldSet& GetUnknownFields(const Message& message) const;
    +  UnknownFieldSet* MutableUnknownFields(Message* message) const;
    +
    +  int SpaceUsed(const Message& message) const;
    +
    +  bool HasField(const Message& message, const FieldDescriptor* field) const;
    +  int FieldSize(const Message& message, const FieldDescriptor* field) const;
    +  void ClearField(Message* message, const FieldDescriptor* field) const;
    +  bool HasOneof(const Message& message,
    +                const OneofDescriptor* oneof_descriptor) const;
    +  void ClearOneof(Message* message, const OneofDescriptor* field) const;
    +  void RemoveLast(Message* message, const FieldDescriptor* field) const;
    +  Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
    +  void Swap(Message* message1, Message* message2) const;
    +  void SwapFields(Message* message1, Message* message2,
    +                  const vector& fields) const;
    +  void SwapElements(Message* message, const FieldDescriptor* field,
    +                    int index1, int index2) const;
    +  void ListFields(const Message& message,
    +                  vector* output) const;
    +
    +  int32  GetInt32 (const Message& message,
    +                   const FieldDescriptor* field) const;
    +  int64  GetInt64 (const Message& message,
    +                   const FieldDescriptor* field) const;
    +  uint32 GetUInt32(const Message& message,
    +                   const FieldDescriptor* field) const;
    +  uint64 GetUInt64(const Message& message,
    +                   const FieldDescriptor* field) const;
    +  float  GetFloat (const Message& message,
    +                   const FieldDescriptor* field) const;
    +  double GetDouble(const Message& message,
    +                   const FieldDescriptor* field) const;
    +  bool   GetBool  (const Message& message,
    +                   const FieldDescriptor* field) const;
    +  string GetString(const Message& message,
    +                   const FieldDescriptor* field) const;
    +  const string& GetStringReference(const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   string* scratch) const;
    +  const EnumValueDescriptor* GetEnum(const Message& message,
    +                                     const FieldDescriptor* field) const;
    +  const Message& GetMessage(const Message& message,
    +                            const FieldDescriptor* field,
    +                            MessageFactory* factory = NULL) const;
    +
    +  const FieldDescriptor* GetOneofFieldDescriptor(
    +      const Message& message,
    +      const OneofDescriptor* oneof_descriptor) const;
    +
    + public:
    +  void SetInt32 (Message* message,
    +                 const FieldDescriptor* field, int32  value) const;
    +  void SetInt64 (Message* message,
    +                 const FieldDescriptor* field, int64  value) const;
    +  void SetUInt32(Message* message,
    +                 const FieldDescriptor* field, uint32 value) const;
    +  void SetUInt64(Message* message,
    +                 const FieldDescriptor* field, uint64 value) const;
    +  void SetFloat (Message* message,
    +                 const FieldDescriptor* field, float  value) const;
    +  void SetDouble(Message* message,
    +                 const FieldDescriptor* field, double value) const;
    +  void SetBool  (Message* message,
    +                 const FieldDescriptor* field, bool   value) const;
    +  void SetString(Message* message,
    +                 const FieldDescriptor* field,
    +                 const string& value) const;
    +  void SetEnum  (Message* message, const FieldDescriptor* field,
    +                 const EnumValueDescriptor* value) const;
    +  Message* MutableMessage(Message* message, const FieldDescriptor* field,
    +                          MessageFactory* factory = NULL) const;
    +  void SetAllocatedMessage(Message* message,
    +                           Message* sub_message,
    +                           const FieldDescriptor* field) const;
    +  Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
    +                          MessageFactory* factory = NULL) const;
    +
    +  int32  GetRepeatedInt32 (const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  int64  GetRepeatedInt64 (const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  uint32 GetRepeatedUInt32(const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  uint64 GetRepeatedUInt64(const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  float  GetRepeatedFloat (const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  double GetRepeatedDouble(const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  bool   GetRepeatedBool  (const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  string GetRepeatedString(const Message& message,
    +                           const FieldDescriptor* field, int index) const;
    +  const string& GetRepeatedStringReference(const Message& message,
    +                                           const FieldDescriptor* field,
    +                                           int index, string* scratch) const;
    +  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
    +                                             const FieldDescriptor* field,
    +                                             int index) const;
    +  const Message& GetRepeatedMessage(const Message& message,
    +                                    const FieldDescriptor* field,
    +                                    int index) const;
    +
    +  // Set the value of a field.
    +  void SetRepeatedInt32 (Message* message,
    +                         const FieldDescriptor* field, int index, int32  value) const;
    +  void SetRepeatedInt64 (Message* message,
    +                         const FieldDescriptor* field, int index, int64  value) const;
    +  void SetRepeatedUInt32(Message* message,
    +                         const FieldDescriptor* field, int index, uint32 value) const;
    +  void SetRepeatedUInt64(Message* message,
    +                         const FieldDescriptor* field, int index, uint64 value) const;
    +  void SetRepeatedFloat (Message* message,
    +                         const FieldDescriptor* field, int index, float  value) const;
    +  void SetRepeatedDouble(Message* message,
    +                         const FieldDescriptor* field, int index, double value) const;
    +  void SetRepeatedBool  (Message* message,
    +                         const FieldDescriptor* field, int index, bool   value) const;
    +  void SetRepeatedString(Message* message,
    +                         const FieldDescriptor* field, int index,
    +                         const string& value) const;
    +  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
    +                       int index, const EnumValueDescriptor* value) const;
    +  // Get a mutable pointer to a field with a message type.
    +  Message* MutableRepeatedMessage(Message* message,
    +                                  const FieldDescriptor* field,
    +                                  int index) const;
    +
    +  void AddInt32 (Message* message,
    +                 const FieldDescriptor* field, int32  value) const;
    +  void AddInt64 (Message* message,
    +                 const FieldDescriptor* field, int64  value) const;
    +  void AddUInt32(Message* message,
    +                 const FieldDescriptor* field, uint32 value) const;
    +  void AddUInt64(Message* message,
    +                 const FieldDescriptor* field, uint64 value) const;
    +  void AddFloat (Message* message,
    +                 const FieldDescriptor* field, float  value) const;
    +  void AddDouble(Message* message,
    +                 const FieldDescriptor* field, double value) const;
    +  void AddBool  (Message* message,
    +                 const FieldDescriptor* field, bool   value) const;
    +  void AddString(Message* message,
    +                 const FieldDescriptor* field, const string& value) const;
    +  void AddEnum(Message* message,
    +               const FieldDescriptor* field,
    +               const EnumValueDescriptor* value) const;
    +  Message* AddMessage(Message* message, const FieldDescriptor* field,
    +                      MessageFactory* factory = NULL) const;
    +
    +  const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
    +  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
    +
    + protected:
    +  virtual void* MutableRawRepeatedField(
    +      Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
    +      int ctype, const Descriptor* desc) const;
    +
    + private:
    +  friend class GeneratedMessage;
    +
    +  // To parse directly into a proto2 generated class, the class GMR_Handlers
    +  // needs access to member offsets and hasbits.
    +  friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
    +
    +  const Descriptor* descriptor_;
    +  const Message* default_instance_;
    +  const void* default_oneof_instance_;
    +  const int* offsets_;
    +
    +  int has_bits_offset_;
    +  int oneof_case_offset_;
    +  int unknown_fields_offset_;
    +  int extensions_offset_;
    +  int object_size_;
    +
    +  const DescriptorPool* descriptor_pool_;
    +  MessageFactory* message_factory_;
    +
    +  template 
    +  inline const Type& GetRaw(const Message& message,
    +                            const FieldDescriptor* field) const;
    +  template 
    +  inline Type* MutableRaw(Message* message,
    +                          const FieldDescriptor* field) const;
    +  template 
    +  inline const Type& DefaultRaw(const FieldDescriptor* field) const;
    +  template 
    +  inline const Type& DefaultOneofRaw(const FieldDescriptor* field) const;
    +
    +  inline const uint32* GetHasBits(const Message& message) const;
    +  inline uint32* MutableHasBits(Message* message) const;
    +  inline uint32 GetOneofCase(
    +      const Message& message,
    +      const OneofDescriptor* oneof_descriptor) const;
    +  inline uint32* MutableOneofCase(
    +      Message* message,
    +      const OneofDescriptor* oneof_descriptor) const;
    +  inline const ExtensionSet& GetExtensionSet(const Message& message) const;
    +  inline ExtensionSet* MutableExtensionSet(Message* message) const;
    +
    +  inline bool HasBit(const Message& message,
    +                     const FieldDescriptor* field) const;
    +  inline void SetBit(Message* message,
    +                     const FieldDescriptor* field) const;
    +  inline void ClearBit(Message* message,
    +                       const FieldDescriptor* field) const;
    +  inline void SwapBit(Message* message1,
    +                      Message* message2,
    +                      const FieldDescriptor* field) const;
    +
    +  // This function only swaps the field. Should swap corresponding has_bit
    +  // before or after using this function.
    +  void SwapField(Message* message1,
    +                 Message* message2,
    +                 const FieldDescriptor* field) const;
    +
    +  void SwapOneofField(Message* message1,
    +                      Message* message2,
    +                      const OneofDescriptor* oneof_descriptor) const;
    +
    +  inline bool HasOneofField(const Message& message,
    +                            const FieldDescriptor* field) const;
    +  inline void SetOneofCase(Message* message,
    +                           const FieldDescriptor* field) const;
    +  inline void ClearOneofField(Message* message,
    +                              const FieldDescriptor* field) const;
    +
    +  template 
    +  inline const Type& GetField(const Message& message,
    +                              const FieldDescriptor* field) const;
    +  template 
    +  inline void SetField(Message* message,
    +                       const FieldDescriptor* field, const Type& value) const;
    +  template 
    +  inline Type* MutableField(Message* message,
    +                            const FieldDescriptor* field) const;
    +  template 
    +  inline const Type& GetRepeatedField(const Message& message,
    +                                      const FieldDescriptor* field,
    +                                      int index) const;
    +  template 
    +  inline const Type& GetRepeatedPtrField(const Message& message,
    +                                         const FieldDescriptor* field,
    +                                         int index) const;
    +  template 
    +  inline void SetRepeatedField(Message* message,
    +                               const FieldDescriptor* field, int index,
    +                               Type value) const;
    +  template 
    +  inline Type* MutableRepeatedField(Message* message,
    +                                    const FieldDescriptor* field,
    +                                    int index) const;
    +  template 
    +  inline void AddField(Message* message,
    +                       const FieldDescriptor* field, const Type& value) const;
    +  template 
    +  inline Type* AddField(Message* message,
    +                        const FieldDescriptor* field) const;
    +
    +  int GetExtensionNumberOrDie(const Descriptor* type) const;
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
    +};
    +
    +// Returns the offset of the given field within the given aggregate type.
    +// This is equivalent to the ANSI C offsetof() macro.  However, according
    +// to the C++ standard, offsetof() only works on POD types, and GCC
    +// enforces this requirement with a warning.  In practice, this rule is
    +// unnecessarily strict; there is probably no compiler or platform on
    +// which the offsets of the direct fields of a class are non-constant.
    +// Fields inherited from superclasses *can* have non-constant offsets,
    +// but that's not what this macro will be used for.
    +//
    +// Note that we calculate relative to the pointer value 16 here since if we
    +// just use zero, GCC complains about dereferencing a NULL pointer.  We
    +// choose 16 rather than some other number just in case the compiler would
    +// be confused by an unaligned pointer.
    +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
    +  static_cast(                                           \
    +      reinterpret_cast(                          \
    +          &reinterpret_cast(16)->FIELD) -        \
    +      reinterpret_cast(16))
    +
    +#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD)     \
    +  static_cast(                                                   \
    +      reinterpret_cast(&(ONEOF->FIELD))                  \
    +      - reinterpret_cast(ONEOF))
    +
    +// There are some places in proto2 where dynamic_cast would be useful as an
    +// optimization.  For example, take Message::MergeFrom(const Message& other).
    +// For a given generated message FooMessage, we generate these two methods:
    +//   void MergeFrom(const FooMessage& other);
    +//   void MergeFrom(const Message& other);
    +// The former method can be implemented directly in terms of FooMessage's
    +// inline accessors, but the latter method must work with the reflection
    +// interface.  However, if the parameter to the latter method is actually of
    +// type FooMessage, then we'd like to be able to just call the other method
    +// as an optimization.  So, we use dynamic_cast to check this.
    +//
    +// That said, dynamic_cast requires RTTI, which many people like to disable
    +// for performance and code size reasons.  When RTTI is not available, we
    +// still need to produce correct results.  So, in this case we have to fall
    +// back to using reflection, which is what we would have done anyway if the
    +// objects were not of the exact same class.
    +//
    +// dynamic_cast_if_available() implements this logic.  If RTTI is
    +// enabled, it does a dynamic_cast.  If RTTI is disabled, it just returns
    +// NULL.
    +//
    +// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
    +// On MSVC, this should be detected automatically.
    +template
    +inline To dynamic_cast_if_available(From from) {
    +#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
    +  return NULL;
    +#else
    +  return dynamic_cast(from);
    +#endif
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/generated_message_util.cc b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc
    similarity index 87%
    rename from toolkit/components/protobuf/google/protobuf/generated_message_util.cc
    rename to toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc
    index 76e547bb8d13..0c20d81c8ccd 100644
    --- a/toolkit/components/protobuf/google/protobuf/generated_message_util.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -47,7 +47,17 @@ double NaN() {
       return std::numeric_limits::quiet_NaN();
     }
     
    -const ::std::string kEmptyString;
    +const ::std::string* empty_string_;
    +GOOGLE_PROTOBUF_DECLARE_ONCE(empty_string_once_init_);
    +
    +void DeleteEmptyString() {
    +  delete empty_string_;
    +}
    +
    +void InitEmptyString() {
    +  empty_string_ = new string;
    +  OnShutdown(&DeleteEmptyString);
    +}
     
     
     }  // namespace internal
    diff --git a/toolkit/components/protobuf/src/google/protobuf/generated_message_util.h b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.h
    new file mode 100644
    index 000000000000..678f92a7ee20
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/generated_message_util.h
    @@ -0,0 +1,113 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// This file contains miscellaneous helper code used by generated code --
    +// including lite types -- but which should not be used directly by users.
    +
    +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
    +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
    +
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +namespace google {
    +
    +namespace protobuf {
    +namespace internal {
    +
    +
    +// Annotation for the compiler to emit a deprecation message if a field marked
    +// with option 'deprecated=true' is used in the code, or for other things in
    +// generated code which are deprecated.
    +//
    +// For internal use in the pb.cc files, deprecation warnings are suppressed
    +// there.
    +#undef DEPRECATED_PROTOBUF_FIELD
    +#define PROTOBUF_DEPRECATED
    +
    +
    +// Constants for special floating point values.
    +LIBPROTOBUF_EXPORT double Infinity();
    +LIBPROTOBUF_EXPORT double NaN();
    +
    +// TODO(jieluo): Change to template. We have tried to use template,
    +// but it causes net/rpc/python:rpcutil_test fail (the empty string will
    +// init twice). It may related to swig. Change to template after we
    +// found the solution.
    +
    +// Default empty string object. Don't use the pointer directly. Instead, call
    +// GetEmptyString() to get the reference.
    +LIBPROTOBUF_EXPORT extern const ::std::string* empty_string_;
    +LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_;
    +LIBPROTOBUF_EXPORT void InitEmptyString();
    +
    +
    +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() {
    +  assert(empty_string_ != NULL);
    +  return *empty_string_;
    +}
    +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() {
    +  ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString);
    +  return GetEmptyStringAlreadyInited();
    +}
    +
    +// Defined in generated_message_reflection.cc -- not actually part of the lite
    +// library.
    +//
    +// TODO(jasonh): The various callers get this declaration from a variety of
    +// places: probably in most cases repeated_field.h. Clean these up so they all
    +// get the declaration from this file.
    +LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
    +
    +
    +// True if IsInitialized() is true for all elements of t.  Type is expected
    +// to be a RepeatedPtrField.  It's useful to have this
    +// helper here to keep the protobuf compiler from ever having to emit loops in
    +// IsInitialized() methods.  We want the C++ compiler to inline this or not
    +// as it sees fit.
    +template  bool AllAreInitialized(const Type& t) {
    +  for (int i = t.size(); --i >= 0; ) {
    +    if (!t.Get(i).IsInitialized()) return false;
    +  }
    +  return true;
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/io/coded_stream.cc b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc
    similarity index 85%
    rename from toolkit/components/protobuf/google/protobuf/io/coded_stream.cc
    rename to toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc
    index 57d486f958a2..53449755c164 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/coded_stream.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -43,7 +43,7 @@
     #include 
     #include 
     #include 
    -#include 
    +#include 
     
     
     namespace google {
    @@ -69,6 +69,23 @@ inline bool NextNonEmpty(ZeroCopyInputStream* input,
     
     // CodedInputStream ==================================================
     
    +CodedInputStream::~CodedInputStream() {
    +  if (input_ != NULL) {
    +    BackUpInputToCurrentPosition();
    +  }
    +
    +  if (total_bytes_warning_threshold_ == -2) {
    +    GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_;
    +  }
    +}
    +
    +// Static.
    +int CodedInputStream::default_recursion_limit_ = 100;
    +
    +
    +void CodedOutputStream::EnableAliasing(bool enabled) {
    +  aliasing_enabled_ = enabled && output_->AllowsAliasing();
    +}
     
     void CodedInputStream::BackUpInputToCurrentPosition() {
       int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
    @@ -98,8 +115,7 @@ inline void CodedInputStream::RecomputeBufferLimits() {
     
     CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
       // Current position relative to the beginning of the stream.
    -  int current_position = total_bytes_read_ -
    -      (BufferSize() + buffer_size_after_limit_);
    +  int current_position = CurrentPosition();
     
       Limit old_limit = current_limit_;
     
    @@ -133,10 +149,9 @@ void CodedInputStream::PopLimit(Limit limit) {
       legitimate_message_end_ = false;
     }
     
    -int CodedInputStream::BytesUntilLimit() {
    +int CodedInputStream::BytesUntilLimit() const {
       if (current_limit_ == INT_MAX) return -1;
    -  int current_position = total_bytes_read_ -
    -      (BufferSize() + buffer_size_after_limit_);
    +  int current_position = CurrentPosition();
     
       return current_limit_ - current_position;
     }
    @@ -145,13 +160,22 @@ void CodedInputStream::SetTotalBytesLimit(
         int total_bytes_limit, int warning_threshold) {
       // Make sure the limit isn't already past, since this could confuse other
       // code.
    -  int current_position = total_bytes_read_ -
    -      (BufferSize() + buffer_size_after_limit_);
    +  int current_position = CurrentPosition();
       total_bytes_limit_ = max(current_position, total_bytes_limit);
    -  total_bytes_warning_threshold_ = warning_threshold;
    +  if (warning_threshold >= 0) {
    +    total_bytes_warning_threshold_ = warning_threshold;
    +  } else {
    +    // warning_threshold is negative
    +    total_bytes_warning_threshold_ = -1;
    +  }
       RecomputeBufferLimits();
     }
     
    +int CodedInputStream::BytesUntilTotalBytesLimit() const {
    +  if (total_bytes_limit_ == INT_MAX) return -1;
    +  return total_bytes_limit_ - CurrentPosition();
    +}
    +
     void CodedInputStream::PrintTotalBytesLimitError() {
       GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
                     "big (more than " << total_bytes_limit_
    @@ -232,6 +256,14 @@ bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
         buffer->clear();
       }
     
    +  int closest_limit = min(current_limit_, total_bytes_limit_);
    +  if (closest_limit != INT_MAX) {
    +    int bytes_to_limit = closest_limit - CurrentPosition();
    +    if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) {
    +      buffer->reserve(size);
    +    }
    +  }
    +
       int current_buffer_size;
       while ((current_buffer_size = BufferSize()) < size) {
         // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
    @@ -298,11 +330,16 @@ inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
       uint32 b;
       uint32 result;
     
    -  b = *(ptr++); result  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
    -  b = *(ptr++); result |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
    -  b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
    -  b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
    -  b = *(ptr++); result |=  b         << 28; if (!(b & 0x80)) goto done;
    +  b = *(ptr++); result  = b      ; if (!(b & 0x80)) goto done;
    +  result -= 0x80;
    +  b = *(ptr++); result += b <<  7; if (!(b & 0x80)) goto done;
    +  result -= 0x80 << 7;
    +  b = *(ptr++); result += b << 14; if (!(b & 0x80)) goto done;
    +  result -= 0x80 << 14;
    +  b = *(ptr++); result += b << 21; if (!(b & 0x80)) goto done;
    +  result -= 0x80 << 21;
    +  b = *(ptr++); result += b << 28; if (!(b & 0x80)) goto done;
    +  // "result -= 0x80 << 28" is irrevelant.
     
       // If the input is larger than 32 bits, we still need to read it all
       // and discard the high-order bits.
    @@ -332,8 +369,8 @@ bool CodedInputStream::ReadVarint32Slow(uint32* value) {
     
     bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
       if (BufferSize() >= kMaxVarintBytes ||
    -      // Optimization:  If the varint ends at exactly the end of the buffer,
    -      // we can detect that and still use the fast path.
    +      // Optimization:  We're also safe if the buffer is non-empty and it ends
    +      // with a byte that would terminate a varint.
           (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
         const uint8* end = ReadVarint32FromArray(buffer_, value);
         if (end == NULL) return false;
    @@ -368,16 +405,17 @@ uint32 CodedInputStream::ReadTagSlow() {
     
       // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
       // again, since we have now refreshed the buffer.
    -  uint64 result;
    +  uint64 result = 0;
       if (!ReadVarint64(&result)) return 0;
       return static_cast(result);
     }
     
     uint32 CodedInputStream::ReadTagFallback() {
    -  if (BufferSize() >= kMaxVarintBytes ||
    -      // Optimization:  If the varint ends at exactly the end of the buffer,
    -      // we can detect that and still use the fast path.
    -      (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
    +  const int buf_size = BufferSize();
    +  if (buf_size >= kMaxVarintBytes ||
    +      // Optimization:  We're also safe if the buffer is non-empty and it ends
    +      // with a byte that would terminate a varint.
    +      (buf_size > 0 && !(buffer_end_[-1] & 0x80))) {
         uint32 tag;
         const uint8* end = ReadVarint32FromArray(buffer_, &tag);
         if (end == NULL) {
    @@ -388,7 +426,9 @@ uint32 CodedInputStream::ReadTagFallback() {
       } else {
         // We are commonly at a limit when attempting to read tags. Try to quickly
         // detect this case without making another function call.
    -    if (buffer_ == buffer_end_ && buffer_size_after_limit_ > 0 &&
    +    if ((buf_size == 0) &&
    +        ((buffer_size_after_limit_ > 0) ||
    +         (total_bytes_read_ == current_limit_)) &&
             // Make sure that the limit we hit is not total_bytes_limit_, since
             // in that case we still need to call Refresh() so that it prints an
             // error.
    @@ -426,8 +466,8 @@ bool CodedInputStream::ReadVarint64Slow(uint64* value) {
     
     bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
       if (BufferSize() >= kMaxVarintBytes ||
    -      // Optimization:  If the varint ends at exactly the end of the buffer,
    -      // we can detect that and still use the fast path.
    +      // Optimization:  We're also safe if the buffer is non-empty and it ends
    +      // with a byte that would terminate a varint.
           (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
         // Fast path:  We have enough bytes left in the buffer to guarantee that
         // this read won't cross the end, so we can skip the checks.
    @@ -439,20 +479,30 @@ bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
         // processors.
         uint32 part0 = 0, part1 = 0, part2 = 0;
     
    -    b = *(ptr++); part0  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part0 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part1  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part1 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part2  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
    -    b = *(ptr++); part2 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
    +    b = *(ptr++); part0  = b      ; if (!(b & 0x80)) goto done;
    +    part0 -= 0x80;
    +    b = *(ptr++); part0 += b <<  7; if (!(b & 0x80)) goto done;
    +    part0 -= 0x80 << 7;
    +    b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
    +    part0 -= 0x80 << 14;
    +    b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
    +    part0 -= 0x80 << 21;
    +    b = *(ptr++); part1  = b      ; if (!(b & 0x80)) goto done;
    +    part1 -= 0x80;
    +    b = *(ptr++); part1 += b <<  7; if (!(b & 0x80)) goto done;
    +    part1 -= 0x80 << 7;
    +    b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
    +    part1 -= 0x80 << 14;
    +    b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
    +    part1 -= 0x80 << 21;
    +    b = *(ptr++); part2  = b      ; if (!(b & 0x80)) goto done;
    +    part2 -= 0x80;
    +    b = *(ptr++); part2 += b <<  7; if (!(b & 0x80)) goto done;
    +    // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
     
         // We have overrun the maximum size of a varint (10 bytes).  The data
         // must be corrupt.
    -    return NULL;
    +    return false;
     
        done:
         Advance(ptr - buffer_);
    @@ -492,8 +542,8 @@ bool CodedInputStream::Refresh() {
                           "CodedInputStream::SetTotalBytesLimit() in "
                           "google/protobuf/io/coded_stream.h.";
     
    -    // Don't warn again for this stream.
    -    total_bytes_warning_threshold_ = -1;
    +    // Don't warn again for this stream, and print total size at the end.
    +    total_bytes_warning_threshold_ = -2;
       }
     
       const void* void_buffer;
    @@ -537,7 +587,8 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
         buffer_(NULL),
         buffer_size_(0),
         total_bytes_(0),
    -    had_error_(false) {
    +    had_error_(false),
    +    aliasing_enabled_(false) {
       // Eagerly Refresh() so buffer space is immediately available.
       Refresh();
       // The Refresh() may have failed. If the client doesn't write any data,
    @@ -591,6 +642,23 @@ uint8* CodedOutputStream::WriteRawToArray(
     }
     
     
    +void CodedOutputStream::WriteAliasedRaw(const void* data, int size) {
    +  if (size < buffer_size_
    +      ) {
    +    WriteRaw(data, size);
    +  } else {
    +    if (buffer_size_ > 0) {
    +      output_->BackUp(buffer_size_);
    +      total_bytes_ -= buffer_size_;
    +      buffer_ = NULL;
    +      buffer_size_ = 0;
    +    }
    +
    +    total_bytes_ += size;
    +    had_error_ |= !output_->WriteAliasedRaw(data, size);
    +  }
    +}
    +
     void CodedOutputStream::WriteLittleEndian32(uint32 value) {
       uint8 bytes[sizeof(value)];
     
    @@ -834,6 +902,13 @@ int CodedOutputStream::VarintSize64(uint64 value) {
       }
     }
     
    +uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
    +                                                     uint8* target) {
    +  GOOGLE_DCHECK_LE(str.size(), kuint32max);
    +  target = WriteVarint32ToArray(str.size(), target);
    +  return WriteStringToArray(str, target);
    +}
    +
     }  // namespace io
     }  // namespace protobuf
     }  // namespace google
    diff --git a/toolkit/components/protobuf/google/protobuf/io/coded_stream.h b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h
    similarity index 87%
    rename from toolkit/components/protobuf/google/protobuf/io/coded_stream.h
    rename to toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h
    index 1b6b4e18b4fa..81fabb1d842c 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/coded_stream.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -170,6 +170,9 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       // successfully and the stream's byte limit.
       ~CodedInputStream();
     
    +  // Return true if this CodedInputStream reads from a flat array instead of
    +  // a ZeroCopyInputStream.
    +  inline bool IsFlat() const;
     
       // Skips a number of bytes.  Returns false if an underlying read error
       // occurs.
    @@ -230,11 +233,22 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       // Read a tag.  This calls ReadVarint32() and returns the result, or returns
       // zero (which is not a valid tag) if ReadVarint32() fails.  Also, it updates
       // the last tag value, which can be checked with LastTagWas().
    -  // Always inline because this is only called in once place per parse loop
    +  // Always inline because this is only called in one place per parse loop
       // but it is called for every iteration of said loop, so it should be fast.
       // GCC doesn't want to inline this by default.
       uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
     
    +  // This usually a faster alternative to ReadTag() when cutoff is a manifest
    +  // constant.  It does particularly well for cutoff >= 127.  The first part
    +  // of the return value is the tag that was read, though it can also be 0 in
    +  // the cases where ReadTag() would return 0.  If the second part is true
    +  // then the tag is known to be in [0, cutoff].  If not, the tag either is
    +  // above cutoff or is 0.  (There's intentional wiggle room when tag is 0,
    +  // because that can arise in several ways, and for best performance we want
    +  // to avoid an extra "is tag == 0?" check here.)
    +  inline std::pair ReadTagWithCutoff(uint32 cutoff)
    +      GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
    +
       // Usually returns true if calling ReadVarint32() now would produce the given
       // value.  Will always return false if ReadVarint32() would not return the
       // given value.  If ExpectTag() returns true, it also advances past
    @@ -261,8 +275,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       // zero, and ConsumedEntireMessage() will return true.
       bool ExpectAtEnd();
     
    -  // If the last call to ReadTag() returned the given value, returns true.
    -  // Otherwise, returns false;
    +  // If the last call to ReadTag() or ReadTagWithCutoff() returned the
    +  // given value, returns true.  Otherwise, returns false;
       //
       // This is needed because parsers for some types of embedded messages
       // (with field type TYPE_GROUP) don't actually know that they've reached the
    @@ -311,7 +325,10 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
     
       // Returns the number of bytes left until the nearest limit on the
       // stack is hit, or -1 if no limits are in place.
    -  int BytesUntilLimit();
    +  int BytesUntilLimit() const;
    +
    +  // Returns current position relative to the beginning of the input stream.
    +  int CurrentPosition() const;
     
       // Total Bytes Limit -----------------------------------------------
       // To prevent malicious users from sending excessively large messages
    @@ -327,8 +344,9 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       // cause integer overflows is 512MB.  The default limit is 64MB.  Apps
       // should set shorter limits if possible.  If warning_threshold is not -1,
       // a warning will be printed to stderr after warning_threshold bytes are
    -  // read.  An error will always be printed to stderr if the limit is
    -  // reached.
    +  // read.  For backwards compatibility all negative values get squashed to -1,
    +  // as other negative values might have special internal meanings.
    +  // An error will always be printed to stderr if the limit is reached.
       //
       // This is unrelated to PushLimit()/PopLimit().
       //
    @@ -349,15 +367,20 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       //   something unusual.
       void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold);
     
    +  // The Total Bytes Limit minus the Current Position, or -1 if there
    +  // is no Total Bytes Limit.
    +  int BytesUntilTotalBytesLimit() const;
    +
       // Recursion Limit -------------------------------------------------
       // To prevent corrupt or malicious messages from causing stack overflows,
       // we must keep track of the depth of recursion when parsing embedded
       // messages and groups.  CodedInputStream keeps track of this because it
       // is the only object that is passed down the stack during parsing.
     
    -  // Sets the maximum recursion depth.  The default is 64.
    +  // Sets the maximum recursion depth.  The default is 100.
       void SetRecursionLimit(int limit);
     
    +
       // Increments the current recursion depth.  Returns true if the depth is
       // under the limit, false if it has gone over.
       bool IncrementRecursionDepth();
    @@ -433,7 +456,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       //
       // Note that this feature is ignored when parsing "lite" messages as they do
       // not have descriptors.
    -  void SetExtensionRegistry(DescriptorPool* pool, MessageFactory* factory);
    +  void SetExtensionRegistry(const DescriptorPool* pool,
    +                            MessageFactory* factory);
     
       // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool
       // has been provided.
    @@ -457,7 +481,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       int overflow_bytes_;
     
       // LastTagWas() stuff.
    -  uint32 last_tag_;         // result of last ReadTag().
    +  uint32 last_tag_;         // result of last ReadTag() or ReadTagWithCutoff().
     
       // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly
       // at EOF, or by ExpectAtEnd() when it returns true.  This happens when we
    @@ -482,6 +506,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       // Maximum number of bytes to read, period.  This is unrelated to
       // current_limit_.  Set using SetTotalBytesLimit().
       int total_bytes_limit_;
    +
    +  // If positive/0: Limit for bytes read after which a warning due to size
    +  // should be logged.
    +  // If -1: Printing of warning disabled. Can be set by client.
    +  // If -2: Internal: Limit has been reached, print full size when destructing.
       int total_bytes_warning_threshold_;
     
       // Current recursion depth, controlled by IncrementRecursionDepth() and
    @@ -539,7 +568,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
       static const int kDefaultTotalBytesLimit = 64 << 20;  // 64MB
     
       static const int kDefaultTotalBytesWarningThreshold = 32 << 20;  // 32MB
    -  static const int kDefaultRecursionLimit = 64;
    +
    +  static int default_recursion_limit_;  // 100 by default.
     };
     
     // Class which encodes and writes binary data which is composed of varint-
    @@ -623,6 +653,9 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
     
       // Write raw bytes, copying them from the given buffer.
       void WriteRaw(const void* buffer, int size);
    +  // Like WriteRaw()  but will try to write aliased data if aliasing is
    +  // turned on.
    +  void WriteRawMaybeAliased(const void* data, int size);
       // Like WriteRaw()  but writing directly to the target array.
       // This is _not_ inlined, as the compiler often optimizes memcpy into inline
       // copy loops. Since this gets called by every field with string or bytes
    @@ -634,8 +667,21 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
       void WriteString(const string& str);
       // Like WriteString()  but writing directly to the target array.
       static uint8* WriteStringToArray(const string& str, uint8* target);
    +  // Write the varint-encoded size of str followed by str.
    +  static uint8* WriteStringWithSizeToArray(const string& str, uint8* target);
     
     
    +  // Instructs the CodedOutputStream to allow the underlying
    +  // ZeroCopyOutputStream to hold pointers to the original structure instead of
    +  // copying, if it supports it (i.e. output->AllowsAliasing() is true).  If the
    +  // underlying stream does not support aliasing, then enabling it has no
    +  // affect.  For now, this only affects the behavior of
    +  // WriteRawMaybeAliased().
    +  //
    +  // NOTE: It is caller's responsibility to ensure that the chunk of memory
    +  // remains live until all of the data has been consumed from the stream.
    +  void EnableAliasing(bool enabled);
    +
       // Write a 32-bit little-endian integer.
       void WriteLittleEndian32(uint32 value);
       // Like WriteLittleEndian32()  but writing directly to the target array.
    @@ -680,6 +726,21 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
       // If negative, 10 bytes.  Otheriwse, same as VarintSize32().
       static int VarintSize32SignExtended(int32 value);
     
    +  // Compile-time equivalent of VarintSize32().
    +  template 
    +  struct StaticVarintSize32 {
    +    static const int value =
    +        (Value < (1 << 7))
    +            ? 1
    +            : (Value < (1 << 14))
    +                ? 2
    +                : (Value < (1 << 21))
    +                    ? 3
    +                    : (Value < (1 << 28))
    +                        ? 4
    +                        : 5;
    +  };
    +
       // Returns the total number of bytes written since this object was created.
       inline int ByteCount() const;
     
    @@ -695,6 +756,7 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
       int buffer_size_;
       int total_bytes_;  // Sum of sizes of all buffers seen so far.
       bool had_error_;   // Whether an error occurred during output.
    +  bool aliasing_enabled_;  // See EnableAliasing().
     
       // Advance the buffer by a given number of bytes.
       void Advance(int amount);
    @@ -703,6 +765,10 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
       // Advance(buffer_size_).
       bool Refresh();
     
    +  // Like WriteRaw() but may avoid copying if the underlying
    +  // ZeroCopyOutputStream supports it.
    +  void WriteAliasedRaw(const void* buffer, int size);
    +
       static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target);
     
       // Always-inlined versions of WriteVarint* functions so that code can be
    @@ -820,6 +886,45 @@ inline uint32 CodedInputStream::ReadTag() {
       }
     }
     
    +inline std::pair CodedInputStream::ReadTagWithCutoff(
    +    uint32 cutoff) {
    +  // In performance-sensitive code we can expect cutoff to be a compile-time
    +  // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at
    +  // compile time.
    +  if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
    +    // Hot case: buffer_ non_empty, buffer_[0] in [1, 128).
    +    // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields
    +    // is large enough then is it better to check for the two-byte case first?
    +    if (static_cast(buffer_[0]) > 0) {
    +      const uint32 kMax1ByteVarint = 0x7f;
    +      uint32 tag = last_tag_ = buffer_[0];
    +      Advance(1);
    +      return make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff);
    +    }
    +    // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available,
    +    // and tag is two bytes.  The latter is tested by bitwise-and-not of the
    +    // first byte and the second byte.
    +    if (cutoff >= 0x80 &&
    +        GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) &&
    +        GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) {
    +      const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f;
    +      uint32 tag = last_tag_ = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80);
    +      Advance(2);
    +      // It might make sense to test for tag == 0 now, but it is so rare that
    +      // that we don't bother.  A varint-encoded 0 should be one byte unless
    +      // the encoder lost its mind.  The second part of the return value of
    +      // this function is allowed to be either true or false if the tag is 0,
    +      // so we don't have to check for tag == 0.  We may need to check whether
    +      // it exceeds cutoff.
    +      bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff;
    +      return make_pair(tag, at_or_below_cutoff);
    +    }
    +  }
    +  // Slow path
    +  last_tag_ = ReadTagFallback();
    +  return make_pair(last_tag_, static_cast(last_tag_ - 1) < cutoff);
    +}
    +
     inline bool CodedInputStream::LastTagWas(uint32 expected) {
       return last_tag_ == expected;
     }
    @@ -876,7 +981,9 @@ inline bool CodedInputStream::ExpectAtEnd() {
       // If we are at a limit we know no more bytes can be read.  Otherwise, it's
       // hard to say without calling Refresh(), and we'd rather not do that.
     
    -  if (buffer_ == buffer_end_ && buffer_size_after_limit_ != 0) {
    +  if (buffer_ == buffer_end_ &&
    +      ((buffer_size_after_limit_ != 0) ||
    +       (total_bytes_read_ == current_limit_))) {
         last_tag_ = 0;                   // Pretend we called ReadTag()...
         legitimate_message_end_ = true;  // ... and it hit EOF.
         return true;
    @@ -885,6 +992,10 @@ inline bool CodedInputStream::ExpectAtEnd() {
       }
     }
     
    +inline int CodedInputStream::CurrentPosition() const {
    +  return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_);
    +}
    +
     inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) {
       if (buffer_size_ < size) {
         return NULL;
    @@ -993,6 +1104,15 @@ inline void CodedOutputStream::WriteString(const string& str) {
       WriteRaw(str.data(), static_cast(str.size()));
     }
     
    +inline void CodedOutputStream::WriteRawMaybeAliased(
    +    const void* data, int size) {
    +  if (aliasing_enabled_) {
    +    WriteAliasedRaw(data, size);
    +  } else {
    +    WriteRaw(data, size);
    +  }
    +}
    +
     inline uint8* CodedOutputStream::WriteStringToArray(
         const string& str, uint8* target) {
       return WriteRawToArray(str.data(), static_cast(str.size()), target);
    @@ -1024,7 +1144,7 @@ inline void CodedInputStream::DecrementRecursionDepth() {
       if (recursion_depth_ > 0) --recursion_depth_;
     }
     
    -inline void CodedInputStream::SetExtensionRegistry(DescriptorPool* pool,
    +inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool,
                                                        MessageFactory* factory) {
       extension_pool_ = pool;
       extension_factory_ = factory;
    @@ -1056,7 +1176,7 @@ inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
         total_bytes_limit_(kDefaultTotalBytesLimit),
         total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
         recursion_depth_(0),
    -    recursion_limit_(kDefaultRecursionLimit),
    +    recursion_limit_(default_recursion_limit_),
         extension_pool_(NULL),
         extension_factory_(NULL) {
       // Eagerly Refresh() so buffer space is immediately available.
    @@ -1077,17 +1197,15 @@ inline CodedInputStream::CodedInputStream(const uint8* buffer, int size)
         total_bytes_limit_(kDefaultTotalBytesLimit),
         total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
         recursion_depth_(0),
    -    recursion_limit_(kDefaultRecursionLimit),
    +    recursion_limit_(default_recursion_limit_),
         extension_pool_(NULL),
         extension_factory_(NULL) {
       // Note that setting current_limit_ == size is important to prevent some
       // code paths from trying to access input_ and segfaulting.
     }
     
    -inline CodedInputStream::~CodedInputStream() {
    -  if (input_ != NULL) {
    -    BackUpInputToCurrentPosition();
    -  }
    +inline bool CodedInputStream::IsFlat() const {
    +  return input_ == NULL;
     }
     
     }  // namespace io
    diff --git a/toolkit/components/protobuf/google/protobuf/io/coded_stream_inl.h b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream_inl.h
    similarity index 85%
    rename from toolkit/components/protobuf/google/protobuf/io/coded_stream_inl.h
    rename to toolkit/components/protobuf/src/google/protobuf/io/coded_stream_inl.h
    index e9799d477252..88c14cab4090 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/coded_stream_inl.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/coded_stream_inl.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -37,8 +37,9 @@
     #define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
     
     #include 
    +#include 
     #include 
    -#include 
    +#include 
     
     namespace google {
     namespace protobuf {
    @@ -50,8 +51,12 @@ inline bool CodedInputStream::InternalReadStringInline(string* buffer,
     
       if (BufferSize() >= size) {
         STLStringResizeUninitialized(buffer, size);
    -    memcpy(string_as_array(buffer), buffer_, size);
    -    Advance(size);
    +    // When buffer is empty, string_as_array(buffer) will return NULL but memcpy
    +    // requires non-NULL pointers even when size is 0. Hench this check.
    +    if (size > 0) {
    +      memcpy(mutable_string_data(buffer), buffer_, size);
    +      Advance(size);
    +    }
         return true;
       }
     
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc
    new file mode 100644
    index 000000000000..6e4054edaf49
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc
    @@ -0,0 +1,325 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: brianolson@google.com (Brian Olson)
    +//
    +// This file contains the implementation of classes GzipInputStream and
    +// GzipOutputStream.
    +
    +
    +#if HAVE_ZLIB
    +#include 
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +static const int kDefaultBufferSize = 65536;
    +
    +GzipInputStream::GzipInputStream(
    +    ZeroCopyInputStream* sub_stream, Format format, int buffer_size)
    +    : format_(format), sub_stream_(sub_stream), zerror_(Z_OK) {
    +  zcontext_.zalloc = Z_NULL;
    +  zcontext_.zfree = Z_NULL;
    +  zcontext_.opaque = Z_NULL;
    +  zcontext_.total_out = 0;
    +  zcontext_.next_in = NULL;
    +  zcontext_.avail_in = 0;
    +  zcontext_.total_in = 0;
    +  zcontext_.msg = NULL;
    +  if (buffer_size == -1) {
    +    output_buffer_length_ = kDefaultBufferSize;
    +  } else {
    +    output_buffer_length_ = buffer_size;
    +  }
    +  output_buffer_ = operator new(output_buffer_length_);
    +  GOOGLE_CHECK(output_buffer_ != NULL);
    +  zcontext_.next_out = static_cast(output_buffer_);
    +  zcontext_.avail_out = output_buffer_length_;
    +  output_position_ = output_buffer_;
    +}
    +GzipInputStream::~GzipInputStream() {
    +  operator delete(output_buffer_);
    +  zerror_ = inflateEnd(&zcontext_);
    +}
    +
    +static inline int internalInflateInit2(
    +    z_stream* zcontext, GzipInputStream::Format format) {
    +  int windowBitsFormat = 0;
    +  switch (format) {
    +    case GzipInputStream::GZIP: windowBitsFormat = 16; break;
    +    case GzipInputStream::AUTO: windowBitsFormat = 32; break;
    +    case GzipInputStream::ZLIB: windowBitsFormat = 0; break;
    +  }
    +  return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat);
    +}
    +
    +int GzipInputStream::Inflate(int flush) {
    +  if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
    +    // previous inflate filled output buffer. don't change input params yet.
    +  } else if (zcontext_.avail_in == 0) {
    +    const void* in;
    +    int in_size;
    +    bool first = zcontext_.next_in == NULL;
    +    bool ok = sub_stream_->Next(&in, &in_size);
    +    if (!ok) {
    +      zcontext_.next_out = NULL;
    +      zcontext_.avail_out = 0;
    +      return Z_STREAM_END;
    +    }
    +    zcontext_.next_in = static_cast(const_cast(in));
    +    zcontext_.avail_in = in_size;
    +    if (first) {
    +      int error = internalInflateInit2(&zcontext_, format_);
    +      if (error != Z_OK) {
    +        return error;
    +      }
    +    }
    +  }
    +  zcontext_.next_out = static_cast(output_buffer_);
    +  zcontext_.avail_out = output_buffer_length_;
    +  output_position_ = output_buffer_;
    +  int error = inflate(&zcontext_, flush);
    +  return error;
    +}
    +
    +void GzipInputStream::DoNextOutput(const void** data, int* size) {
    +  *data = output_position_;
    +  *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_);
    +  output_position_ = zcontext_.next_out;
    +}
    +
    +// implements ZeroCopyInputStream ----------------------------------
    +bool GzipInputStream::Next(const void** data, int* size) {
    +  bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
    +      || (zerror_ == Z_BUF_ERROR);
    +  if ((!ok) || (zcontext_.next_out == NULL)) {
    +    return false;
    +  }
    +  if (zcontext_.next_out != output_position_) {
    +    DoNextOutput(data, size);
    +    return true;
    +  }
    +  if (zerror_ == Z_STREAM_END) {
    +    if (zcontext_.next_out != NULL) {
    +      // sub_stream_ may have concatenated streams to follow
    +      zerror_ = inflateEnd(&zcontext_);
    +      if (zerror_ != Z_OK) {
    +        return false;
    +      }
    +      zerror_ = internalInflateInit2(&zcontext_, format_);
    +      if (zerror_ != Z_OK) {
    +        return false;
    +      }
    +    } else {
    +      *data = NULL;
    +      *size = 0;
    +      return false;
    +    }
    +  }
    +  zerror_ = Inflate(Z_NO_FLUSH);
    +  if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
    +    // The underlying stream's Next returned false inside Inflate.
    +    return false;
    +  }
    +  ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
    +      || (zerror_ == Z_BUF_ERROR);
    +  if (!ok) {
    +    return false;
    +  }
    +  DoNextOutput(data, size);
    +  return true;
    +}
    +void GzipInputStream::BackUp(int count) {
    +  output_position_ = reinterpret_cast(
    +      reinterpret_cast(output_position_) - count);
    +}
    +bool GzipInputStream::Skip(int count) {
    +  const void* data;
    +  int size;
    +  bool ok = Next(&data, &size);
    +  while (ok && (size < count)) {
    +    count -= size;
    +    ok = Next(&data, &size);
    +  }
    +  if (size > count) {
    +    BackUp(size - count);
    +  }
    +  return ok;
    +}
    +int64 GzipInputStream::ByteCount() const {
    +  return zcontext_.total_out +
    +    (((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_));
    +}
    +
    +// =========================================================================
    +
    +GzipOutputStream::Options::Options()
    +    : format(GZIP),
    +      buffer_size(kDefaultBufferSize),
    +      compression_level(Z_DEFAULT_COMPRESSION),
    +      compression_strategy(Z_DEFAULT_STRATEGY) {}
    +
    +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) {
    +  Init(sub_stream, Options());
    +}
    +
    +GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream,
    +                                   const Options& options) {
    +  Init(sub_stream, options);
    +}
    +
    +void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
    +                            const Options& options) {
    +  sub_stream_ = sub_stream;
    +  sub_data_ = NULL;
    +  sub_data_size_ = 0;
    +
    +  input_buffer_length_ = options.buffer_size;
    +  input_buffer_ = operator new(input_buffer_length_);
    +  GOOGLE_CHECK(input_buffer_ != NULL);
    +
    +  zcontext_.zalloc = Z_NULL;
    +  zcontext_.zfree = Z_NULL;
    +  zcontext_.opaque = Z_NULL;
    +  zcontext_.next_out = NULL;
    +  zcontext_.avail_out = 0;
    +  zcontext_.total_out = 0;
    +  zcontext_.next_in = NULL;
    +  zcontext_.avail_in = 0;
    +  zcontext_.total_in = 0;
    +  zcontext_.msg = NULL;
    +  // default to GZIP format
    +  int windowBitsFormat = 16;
    +  if (options.format == ZLIB) {
    +    windowBitsFormat = 0;
    +  }
    +  zerror_ = deflateInit2(
    +      &zcontext_,
    +      options.compression_level,
    +      Z_DEFLATED,
    +      /* windowBits */15 | windowBitsFormat,
    +      /* memLevel (default) */8,
    +      options.compression_strategy);
    +}
    +
    +GzipOutputStream::~GzipOutputStream() {
    +  Close();
    +  if (input_buffer_ != NULL) {
    +    operator delete(input_buffer_);
    +  }
    +}
    +
    +// private
    +int GzipOutputStream::Deflate(int flush) {
    +  int error = Z_OK;
    +  do {
    +    if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) {
    +      bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_);
    +      if (!ok) {
    +        sub_data_ = NULL;
    +        sub_data_size_ = 0;
    +        return Z_BUF_ERROR;
    +      }
    +      GOOGLE_CHECK_GT(sub_data_size_, 0);
    +      zcontext_.next_out = static_cast(sub_data_);
    +      zcontext_.avail_out = sub_data_size_;
    +    }
    +    error = deflate(&zcontext_, flush);
    +  } while (error == Z_OK && zcontext_.avail_out == 0);
    +  if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
    +    // Notify lower layer of data.
    +    sub_stream_->BackUp(zcontext_.avail_out);
    +    // We don't own the buffer anymore.
    +    sub_data_ = NULL;
    +    sub_data_size_ = 0;
    +  }
    +  return error;
    +}
    +
    +// implements ZeroCopyOutputStream ---------------------------------
    +bool GzipOutputStream::Next(void** data, int* size) {
    +  if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
    +    return false;
    +  }
    +  if (zcontext_.avail_in != 0) {
    +    zerror_ = Deflate(Z_NO_FLUSH);
    +    if (zerror_ != Z_OK) {
    +      return false;
    +    }
    +  }
    +  if (zcontext_.avail_in == 0) {
    +    // all input was consumed. reset the buffer.
    +    zcontext_.next_in = static_cast(input_buffer_);
    +    zcontext_.avail_in = input_buffer_length_;
    +    *data = input_buffer_;
    +    *size = input_buffer_length_;
    +  } else {
    +    // The loop in Deflate should consume all avail_in
    +    GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed";
    +  }
    +  return true;
    +}
    +void GzipOutputStream::BackUp(int count) {
    +  GOOGLE_CHECK_GE(zcontext_.avail_in, count);
    +  zcontext_.avail_in -= count;
    +}
    +int64 GzipOutputStream::ByteCount() const {
    +  return zcontext_.total_in + zcontext_.avail_in;
    +}
    +
    +bool GzipOutputStream::Flush() {
    +  zerror_ = Deflate(Z_FULL_FLUSH);
    +  // Return true if the flush succeeded or if it was a no-op.
    +  return  (zerror_ == Z_OK) ||
    +      (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 &&
    +       zcontext_.avail_out != 0);
    +}
    +
    +bool GzipOutputStream::Close() {
    +  if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
    +    return false;
    +  }
    +  do {
    +    zerror_ = Deflate(Z_FINISH);
    +  } while (zerror_ == Z_OK);
    +  zerror_ = deflateEnd(&zcontext_);
    +  bool ok = zerror_ == Z_OK;
    +  zerror_ = Z_STREAM_END;
    +  return ok;
    +}
    +
    +}  // namespace io
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // HAVE_ZLIB
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h
    new file mode 100644
    index 000000000000..c7ccc260d001
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h
    @@ -0,0 +1,209 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: brianolson@google.com (Brian Olson)
    +//
    +// This file contains the definition for classes GzipInputStream and
    +// GzipOutputStream.
    +//
    +// GzipInputStream decompresses data from an underlying
    +// ZeroCopyInputStream and provides the decompressed data as a
    +// ZeroCopyInputStream.
    +//
    +// GzipOutputStream is an ZeroCopyOutputStream that compresses data to
    +// an underlying ZeroCopyOutputStream.
    +
    +#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
    +#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
    +
    +#include 
    +
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +// A ZeroCopyInputStream that reads compressed data through zlib
    +class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
    + public:
    +  // Format key for constructor
    +  enum Format {
    +    // zlib will autodetect gzip header or deflate stream
    +    AUTO = 0,
    +
    +    // GZIP streams have some extra header data for file attributes.
    +    GZIP = 1,
    +
    +    // Simpler zlib stream format.
    +    ZLIB = 2,
    +  };
    +
    +  // buffer_size and format may be -1 for default of 64kB and GZIP format
    +  explicit GzipInputStream(
    +      ZeroCopyInputStream* sub_stream,
    +      Format format = AUTO,
    +      int buffer_size = -1);
    +  virtual ~GzipInputStream();
    +
    +  // Return last error message or NULL if no error.
    +  inline const char* ZlibErrorMessage() const {
    +    return zcontext_.msg;
    +  }
    +  inline int ZlibErrorCode() const {
    +    return zerror_;
    +  }
    +
    +  // implements ZeroCopyInputStream ----------------------------------
    +  bool Next(const void** data, int* size);
    +  void BackUp(int count);
    +  bool Skip(int count);
    +  int64 ByteCount() const;
    +
    + private:
    +  Format format_;
    +
    +  ZeroCopyInputStream* sub_stream_;
    +
    +  z_stream zcontext_;
    +  int zerror_;
    +
    +  void* output_buffer_;
    +  void* output_position_;
    +  size_t output_buffer_length_;
    +
    +  int Inflate(int flush);
    +  void DoNextOutput(const void** data, int* size);
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
    +};
    +
    +
    +class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
    + public:
    +  // Format key for constructor
    +  enum Format {
    +    // GZIP streams have some extra header data for file attributes.
    +    GZIP = 1,
    +
    +    // Simpler zlib stream format.
    +    ZLIB = 2,
    +  };
    +
    +  struct Options {
    +    // Defaults to GZIP.
    +    Format format;
    +
    +    // What size buffer to use internally.  Defaults to 64kB.
    +    int buffer_size;
    +
    +    // A number between 0 and 9, where 0 is no compression and 9 is best
    +    // compression.  Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
    +    int compression_level;
    +
    +    // Defaults to Z_DEFAULT_STRATEGY.  Can also be set to Z_FILTERED,
    +    // Z_HUFFMAN_ONLY, or Z_RLE.  See the documentation for deflateInit2 in
    +    // zlib.h for definitions of these constants.
    +    int compression_strategy;
    +
    +    Options();  // Initializes with default values.
    +  };
    +
    +  // Create a GzipOutputStream with default options.
    +  explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
    +
    +  // Create a GzipOutputStream with the given options.
    +  GzipOutputStream(
    +      ZeroCopyOutputStream* sub_stream,
    +      const Options& options);
    +
    +  virtual ~GzipOutputStream();
    +
    +  // Return last error message or NULL if no error.
    +  inline const char* ZlibErrorMessage() const {
    +    return zcontext_.msg;
    +  }
    +  inline int ZlibErrorCode() const {
    +    return zerror_;
    +  }
    +
    +  // Flushes data written so far to zipped data in the underlying stream.
    +  // It is the caller's responsibility to flush the underlying stream if
    +  // necessary.
    +  // Compression may be less efficient stopping and starting around flushes.
    +  // Returns true if no error.
    +  //
    +  // Please ensure that block size is > 6. Here is an excerpt from the zlib
    +  // doc that explains why:
    +  //
    +  // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out
    +  // is greater than six to avoid repeated flush markers due to
    +  // avail_out == 0 on return.
    +  bool Flush();
    +
    +  // Writes out all data and closes the gzip stream.
    +  // It is the caller's responsibility to close the underlying stream if
    +  // necessary.
    +  // Returns true if no error.
    +  bool Close();
    +
    +  // implements ZeroCopyOutputStream ---------------------------------
    +  bool Next(void** data, int* size);
    +  void BackUp(int count);
    +  int64 ByteCount() const;
    +
    + private:
    +  ZeroCopyOutputStream* sub_stream_;
    +  // Result from calling Next() on sub_stream_
    +  void* sub_data_;
    +  int sub_data_size_;
    +
    +  z_stream zcontext_;
    +  int zerror_;
    +  void* input_buffer_;
    +  size_t input_buffer_length_;
    +
    +  // Shared constructor code.
    +  void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
    +
    +  // Do some compression.
    +  // Takes zlib flush mode.
    +  // Returns zlib error code.
    +  int Deflate(int flush);
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
    +};
    +
    +}  // namespace io
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/io/package_info.h b/toolkit/components/protobuf/src/google/protobuf/io/package_info.h
    similarity index 97%
    rename from toolkit/components/protobuf/google/protobuf/io/package_info.h
    rename to toolkit/components/protobuf/src/google/protobuf/io/package_info.h
    index 7a7a4e7738d2..dc1fc91e5b4e 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/package_info.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/package_info.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/printer.cc b/toolkit/components/protobuf/src/google/protobuf/io/printer.cc
    new file mode 100644
    index 000000000000..c8df41778e9c
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/printer.cc
    @@ -0,0 +1,198 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
    +  : variable_delimiter_(variable_delimiter),
    +    output_(output),
    +    buffer_(NULL),
    +    buffer_size_(0),
    +    at_start_of_line_(true),
    +    failed_(false) {
    +}
    +
    +Printer::~Printer() {
    +  // Only BackUp() if we have called Next() at least once and never failed.
    +  if (buffer_size_ > 0 && !failed_) {
    +    output_->BackUp(buffer_size_);
    +  }
    +}
    +
    +void Printer::Print(const map& variables, const char* text) {
    +  int size = strlen(text);
    +  int pos = 0;  // The number of bytes we've written so far.
    +
    +  for (int i = 0; i < size; i++) {
    +    if (text[i] == '\n') {
    +      // Saw newline.  If there is more text, we may need to insert an indent
    +      // here.  So, write what we have so far, including the '\n'.
    +      WriteRaw(text + pos, i - pos + 1);
    +      pos = i + 1;
    +
    +      // Setting this true will cause the next WriteRaw() to insert an indent
    +      // first.
    +      at_start_of_line_ = true;
    +
    +    } else if (text[i] == variable_delimiter_) {
    +      // Saw the start of a variable name.
    +
    +      // Write what we have so far.
    +      WriteRaw(text + pos, i - pos);
    +      pos = i + 1;
    +
    +      // Find closing delimiter.
    +      const char* end = strchr(text + pos, variable_delimiter_);
    +      if (end == NULL) {
    +        GOOGLE_LOG(DFATAL) << " Unclosed variable name.";
    +        end = text + pos;
    +      }
    +      int endpos = end - text;
    +
    +      string varname(text + pos, endpos - pos);
    +      if (varname.empty()) {
    +        // Two delimiters in a row reduce to a literal delimiter character.
    +        WriteRaw(&variable_delimiter_, 1);
    +      } else {
    +        // Replace with the variable's value.
    +        map::const_iterator iter = variables.find(varname);
    +        if (iter == variables.end()) {
    +          GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
    +        } else {
    +          WriteRaw(iter->second.data(), iter->second.size());
    +        }
    +      }
    +
    +      // Advance past this variable.
    +      i = endpos;
    +      pos = endpos + 1;
    +    }
    +  }
    +
    +  // Write the rest.
    +  WriteRaw(text + pos, size - pos);
    +}
    +
    +void Printer::Print(const char* text) {
    +  static map empty;
    +  Print(empty, text);
    +}
    +
    +void Printer::Print(const char* text,
    +                    const char* variable, const string& value) {
    +  map vars;
    +  vars[variable] = value;
    +  Print(vars, text);
    +}
    +
    +void Printer::Print(const char* text,
    +                    const char* variable1, const string& value1,
    +                    const char* variable2, const string& value2) {
    +  map vars;
    +  vars[variable1] = value1;
    +  vars[variable2] = value2;
    +  Print(vars, text);
    +}
    +
    +void Printer::Print(const char* text,
    +                    const char* variable1, const string& value1,
    +                    const char* variable2, const string& value2,
    +                    const char* variable3, const string& value3) {
    +  map vars;
    +  vars[variable1] = value1;
    +  vars[variable2] = value2;
    +  vars[variable3] = value3;
    +  Print(vars, text);
    +}
    +
    +void Printer::Indent() {
    +  indent_ += "  ";
    +}
    +
    +void Printer::Outdent() {
    +  if (indent_.empty()) {
    +    GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
    +    return;
    +  }
    +
    +  indent_.resize(indent_.size() - 2);
    +}
    +
    +void Printer::PrintRaw(const string& data) {
    +  WriteRaw(data.data(), data.size());
    +}
    +
    +void Printer::PrintRaw(const char* data) {
    +  if (failed_) return;
    +  WriteRaw(data, strlen(data));
    +}
    +
    +void Printer::WriteRaw(const char* data, int size) {
    +  if (failed_) return;
    +  if (size == 0) return;
    +
    +  if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) {
    +    // Insert an indent.
    +    at_start_of_line_ = false;
    +    WriteRaw(indent_.data(), indent_.size());
    +    if (failed_) return;
    +  }
    +
    +  while (size > buffer_size_) {
    +    // Data exceeds space in the buffer.  Copy what we can and request a
    +    // new buffer.
    +    memcpy(buffer_, data, buffer_size_);
    +    data += buffer_size_;
    +    size -= buffer_size_;
    +    void* void_buffer;
    +    failed_ = !output_->Next(&void_buffer, &buffer_size_);
    +    if (failed_) return;
    +    buffer_ = reinterpret_cast(void_buffer);
    +  }
    +
    +  // Buffer is big enough to receive the data; copy it.
    +  memcpy(buffer_, data, size);
    +  buffer_ += size;
    +  buffer_size_ -= size;
    +}
    +
    +}  // namespace io
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/printer.h b/toolkit/components/protobuf/src/google/protobuf/io/printer.h
    new file mode 100644
    index 000000000000..f06cbf2f0cf2
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/printer.h
    @@ -0,0 +1,136 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Utility class for writing text to a ZeroCopyOutputStream.
    +
    +#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__
    +#define GOOGLE_PROTOBUF_IO_PRINTER_H__
    +
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +class ZeroCopyOutputStream;     // zero_copy_stream.h
    +
    +// This simple utility class assists in code generation.  It basically
    +// allows the caller to define a set of variables and then output some
    +// text with variable substitutions.  Example usage:
    +//
    +//   Printer printer(output, '$');
    +//   map vars;
    +//   vars["name"] = "Bob";
    +//   printer.Print(vars, "My name is $name$.");
    +//
    +// The above writes "My name is Bob." to the output stream.
    +//
    +// Printer aggressively enforces correct usage, crashing (with assert failures)
    +// in the case of undefined variables in debug builds. This helps greatly in
    +// debugging code which uses it.
    +class LIBPROTOBUF_EXPORT Printer {
    + public:
    +  // Create a printer that writes text to the given output stream.  Use the
    +  // given character as the delimiter for variables.
    +  Printer(ZeroCopyOutputStream* output, char variable_delimiter);
    +  ~Printer();
    +
    +  // Print some text after applying variable substitutions.  If a particular
    +  // variable in the text is not defined, this will crash.  Variables to be
    +  // substituted are identified by their names surrounded by delimiter
    +  // characters (as given to the constructor).  The variable bindings are
    +  // defined by the given map.
    +  void Print(const map& variables, const char* text);
    +
    +  // Like the first Print(), except the substitutions are given as parameters.
    +  void Print(const char* text);
    +  // Like the first Print(), except the substitutions are given as parameters.
    +  void Print(const char* text, const char* variable, const string& value);
    +  // Like the first Print(), except the substitutions are given as parameters.
    +  void Print(const char* text, const char* variable1, const string& value1,
    +                               const char* variable2, const string& value2);
    +  // Like the first Print(), except the substitutions are given as parameters.
    +  void Print(const char* text, const char* variable1, const string& value1,
    +                               const char* variable2, const string& value2,
    +                               const char* variable3, const string& value3);
    +  // TODO(kenton):  Overloaded versions with more variables?  Three seems
    +  //   to be enough.
    +
    +  // Indent text by two spaces.  After calling Indent(), two spaces will be
    +  // inserted at the beginning of each line of text.  Indent() may be called
    +  // multiple times to produce deeper indents.
    +  void Indent();
    +
    +  // Reduces the current indent level by two spaces, or crashes if the indent
    +  // level is zero.
    +  void Outdent();
    +
    +  // Write a string to the output buffer.
    +  // This method does not look for newlines to add indentation.
    +  void PrintRaw(const string& data);
    +
    +  // Write a zero-delimited string to output buffer.
    +  // This method does not look for newlines to add indentation.
    +  void PrintRaw(const char* data);
    +
    +  // Write some bytes to the output buffer.
    +  // This method does not look for newlines to add indentation.
    +  void WriteRaw(const char* data, int size);
    +
    +  // True if any write to the underlying stream failed.  (We don't just
    +  // crash in this case because this is an I/O failure, not a programming
    +  // error.)
    +  bool failed() const { return failed_; }
    +
    + private:
    +  const char variable_delimiter_;
    +
    +  ZeroCopyOutputStream* const output_;
    +  char* buffer_;
    +  int buffer_size_;
    +
    +  string indent_;
    +  bool at_start_of_line_;
    +  bool failed_;
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer);
    +};
    +
    +}  // namespace io
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_IO_PRINTER_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/strtod.cc b/toolkit/components/protobuf/src/google/protobuf/io/strtod.cc
    new file mode 100644
    index 000000000000..56973439d953
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/strtod.cc
    @@ -0,0 +1,113 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +// ----------------------------------------------------------------------
    +// NoLocaleStrtod()
    +//   This code will make you cry.
    +// ----------------------------------------------------------------------
    +
    +namespace {
    +
    +// Returns a string identical to *input except that the character pointed to
    +// by radix_pos (which should be '.') is replaced with the locale-specific
    +// radix character.
    +string LocalizeRadix(const char* input, const char* radix_pos) {
    +  // Determine the locale-specific radix character by calling sprintf() to
    +  // print the number 1.5, then stripping off the digits.  As far as I can
    +  // tell, this is the only portable, thread-safe way to get the C library
    +  // to divuldge the locale's radix character.  No, localeconv() is NOT
    +  // thread-safe.
    +  char temp[16];
    +  int size = sprintf(temp, "%.1f", 1.5);
    +  GOOGLE_CHECK_EQ(temp[0], '1');
    +  GOOGLE_CHECK_EQ(temp[size-1], '5');
    +  GOOGLE_CHECK_LE(size, 6);
    +
    +  // Now replace the '.' in the input with it.
    +  string result;
    +  result.reserve(strlen(input) + size - 3);
    +  result.append(input, radix_pos);
    +  result.append(temp + 1, size - 2);
    +  result.append(radix_pos + 1);
    +  return result;
    +}
    +
    +}  // namespace
    +
    +double NoLocaleStrtod(const char* text, char** original_endptr) {
    +  // We cannot simply set the locale to "C" temporarily with setlocale()
    +  // as this is not thread-safe.  Instead, we try to parse in the current
    +  // locale first.  If parsing stops at a '.' character, then this is a
    +  // pretty good hint that we're actually in some other locale in which
    +  // '.' is not the radix character.
    +
    +  char* temp_endptr;
    +  double result = strtod(text, &temp_endptr);
    +  if (original_endptr != NULL) *original_endptr = temp_endptr;
    +  if (*temp_endptr != '.') return result;
    +
    +  // Parsing halted on a '.'.  Perhaps we're in a different locale?  Let's
    +  // try to replace the '.' with a locale-specific radix character and
    +  // try again.
    +  string localized = LocalizeRadix(text, temp_endptr);
    +  const char* localized_cstr = localized.c_str();
    +  char* localized_endptr;
    +  result = strtod(localized_cstr, &localized_endptr);
    +  if ((localized_endptr - localized_cstr) >
    +      (temp_endptr - text)) {
    +    // This attempt got further, so replacing the decimal must have helped.
    +    // Update original_endptr to point at the right location.
    +    if (original_endptr != NULL) {
    +      // size_diff is non-zero if the localized radix has multiple bytes.
    +      int size_diff = localized.size() - strlen(text);
    +      // const_cast is necessary to match the strtod() interface.
    +      *original_endptr = const_cast(
    +        text + (localized_endptr - localized_cstr - size_diff));
    +    }
    +  }
    +
    +  return result;
    +}
    +
    +}  // namespace io
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/strtod.h b/toolkit/components/protobuf/src/google/protobuf/io/strtod.h
    new file mode 100644
    index 000000000000..c2efc8d3e41d
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/strtod.h
    @@ -0,0 +1,50 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// A locale-independent version of strtod(), used to parse floating
    +// point default values in .proto files, where the decimal separator
    +// is always a dot.
    +
    +#ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__
    +#define GOOGLE_PROTOBUF_IO_STRTOD_H__
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +// A locale-independent version of the standard strtod(), which always
    +// uses a dot as the decimal separator.
    +double NoLocaleStrtod(const char* str, char** endptr);
    +
    +}  // namespace io
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_IO_STRTOD_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc
    new file mode 100644
    index 000000000000..ef2de300bfd8
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc
    @@ -0,0 +1,1127 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Here we have a hand-written lexer.  At first you might ask yourself,
    +// "Hand-written text processing?  Is Kenton crazy?!"  Well, first of all,
    +// yes I am crazy, but that's beside the point.  There are actually reasons
    +// why I ended up writing this this way.
    +//
    +// The traditional approach to lexing is to use lex to generate a lexer for
    +// you.  Unfortunately, lex's output is ridiculously ugly and difficult to
    +// integrate cleanly with C++ code, especially abstract code or code meant
    +// as a library.  Better parser-generators exist but would add dependencies
    +// which most users won't already have, which we'd like to avoid.  (GNU flex
    +// has a C++ output option, but it's still ridiculously ugly, non-abstract,
    +// and not library-friendly.)
    +//
    +// The next approach that any good software engineer should look at is to
    +// use regular expressions.  And, indeed, I did.  I have code which
    +// implements this same class using regular expressions.  It's about 200
    +// lines shorter.  However:
    +// - Rather than error messages telling you "This string has an invalid
    +//   escape sequence at line 5, column 45", you get error messages like
    +//   "Parse error on line 5".  Giving more precise errors requires adding
    +//   a lot of code that ends up basically as complex as the hand-coded
    +//   version anyway.
    +// - The regular expression to match a string literal looks like this:
    +//     kString  = new RE("(\"([^\"\\\\]|"              // non-escaped
    +//                       "\\\\[abfnrtv?\"'\\\\0-7]|"   // normal escape
    +//                       "\\\\x[0-9a-fA-F])*\"|"       // hex escape
    +//                       "\'([^\'\\\\]|"        // Also support single-quotes.
    +//                       "\\\\[abfnrtv?\"'\\\\0-7]|"
    +//                       "\\\\x[0-9a-fA-F])*\')");
    +//   Verifying the correctness of this line noise is actually harder than
    +//   verifying the correctness of ConsumeString(), defined below.  I'm not
    +//   even confident that the above is correct, after staring at it for some
    +//   time.
    +// - PCRE is fast, but there's still more overhead involved than the code
    +//   below.
    +// - Sadly, regular expressions are not part of the C standard library, so
    +//   using them would require depending on some other library.  For the
    +//   open source release, this could be really annoying.  Nobody likes
    +//   downloading one piece of software just to find that they need to
    +//   download something else to make it work, and in all likelihood
    +//   people downloading Protocol Buffers will already be doing so just
    +//   to make something else work.  We could include a copy of PCRE with
    +//   our code, but that obligates us to keep it up-to-date and just seems
    +//   like a big waste just to save 200 lines of code.
    +//
    +// On a similar but unrelated note, I'm even scared to use ctype.h.
    +// Apparently functions like isalpha() are locale-dependent.  So, if we used
    +// that, then if this code is being called from some program that doesn't
    +// have its locale set to "C", it would behave strangely.  We can't just set
    +// the locale to "C" ourselves since we might break the calling program that
    +// way, particularly if it is multi-threaded.  WTF?  Someone please let me
    +// (Kenton) know if I'm missing something here...
    +//
    +// I'd love to hear about other alternatives, though, as this code isn't
    +// exactly pretty.
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +namespace {
    +
    +// As mentioned above, I don't trust ctype.h due to the presence of "locales".
    +// So, I have written replacement functions here.  Someone please smack me if
    +// this is a bad idea or if there is some way around this.
    +//
    +// These "character classes" are designed to be used in template methods.
    +// For instance, Tokenizer::ConsumeZeroOrMore() will eat
    +// whitespace.
    +
    +// Note:  No class is allowed to contain '\0', since this is used to mark end-
    +//   of-input and is handled specially.
    +
    +#define CHARACTER_CLASS(NAME, EXPRESSION)      \
    +  class NAME {                                 \
    +   public:                                     \
    +    static inline bool InClass(char c) {       \
    +      return EXPRESSION;                       \
    +    }                                          \
    +  }
    +
    +CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' ||
    +                            c == '\r' || c == '\v' || c == '\f');
    +CHARACTER_CLASS(WhitespaceNoNewline, c == ' ' || c == '\t' ||
    +                                     c == '\r' || c == '\v' || c == '\f');
    +
    +CHARACTER_CLASS(Unprintable, c < ' ' && c > '\0');
    +
    +CHARACTER_CLASS(Digit, '0' <= c && c <= '9');
    +CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7');
    +CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') ||
    +                          ('a' <= c && c <= 'f') ||
    +                          ('A' <= c && c <= 'F'));
    +
    +CHARACTER_CLASS(Letter, ('a' <= c && c <= 'z') ||
    +                        ('A' <= c && c <= 'Z') ||
    +                        (c == '_'));
    +
    +CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') ||
    +                              ('A' <= c && c <= 'Z') ||
    +                              ('0' <= c && c <= '9') ||
    +                              (c == '_'));
    +
    +CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' ||
    +                        c == 'r' || c == 't' || c == 'v' || c == '\\' ||
    +                        c == '?' || c == '\'' || c == '\"');
    +
    +#undef CHARACTER_CLASS
    +
    +// Given a char, interpret it as a numeric digit and return its value.
    +// This supports any number base up to 36.
    +inline int DigitValue(char digit) {
    +  if ('0' <= digit && digit <= '9') return digit - '0';
    +  if ('a' <= digit && digit <= 'z') return digit - 'a' + 10;
    +  if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10;
    +  return -1;
    +}
    +
    +// Inline because it's only used in one place.
    +inline char TranslateEscape(char c) {
    +  switch (c) {
    +    case 'a':  return '\a';
    +    case 'b':  return '\b';
    +    case 'f':  return '\f';
    +    case 'n':  return '\n';
    +    case 'r':  return '\r';
    +    case 't':  return '\t';
    +    case 'v':  return '\v';
    +    case '\\': return '\\';
    +    case '?':  return '\?';    // Trigraphs = :(
    +    case '\'': return '\'';
    +    case '"':  return '\"';
    +
    +    // We expect escape sequences to have been validated separately.
    +    default:   return '?';
    +  }
    +}
    +
    +}  // anonymous namespace
    +
    +ErrorCollector::~ErrorCollector() {}
    +
    +// ===================================================================
    +
    +Tokenizer::Tokenizer(ZeroCopyInputStream* input,
    +                     ErrorCollector* error_collector)
    +  : input_(input),
    +    error_collector_(error_collector),
    +    buffer_(NULL),
    +    buffer_size_(0),
    +    buffer_pos_(0),
    +    read_error_(false),
    +    line_(0),
    +    column_(0),
    +    record_target_(NULL),
    +    record_start_(-1),
    +    allow_f_after_float_(false),
    +    comment_style_(CPP_COMMENT_STYLE),
    +    require_space_after_number_(true),
    +    allow_multiline_strings_(false) {
    +
    +  current_.line = 0;
    +  current_.column = 0;
    +  current_.end_column = 0;
    +  current_.type = TYPE_START;
    +
    +  Refresh();
    +}
    +
    +Tokenizer::~Tokenizer() {
    +  // If we had any buffer left unread, return it to the underlying stream
    +  // so that someone else can read it.
    +  if (buffer_size_ > buffer_pos_) {
    +    input_->BackUp(buffer_size_ - buffer_pos_);
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +// Internal helpers.
    +
    +void Tokenizer::NextChar() {
    +  // Update our line and column counters based on the character being
    +  // consumed.
    +  if (current_char_ == '\n') {
    +    ++line_;
    +    column_ = 0;
    +  } else if (current_char_ == '\t') {
    +    column_ += kTabWidth - column_ % kTabWidth;
    +  } else {
    +    ++column_;
    +  }
    +
    +  // Advance to the next character.
    +  ++buffer_pos_;
    +  if (buffer_pos_ < buffer_size_) {
    +    current_char_ = buffer_[buffer_pos_];
    +  } else {
    +    Refresh();
    +  }
    +}
    +
    +void Tokenizer::Refresh() {
    +  if (read_error_) {
    +    current_char_ = '\0';
    +    return;
    +  }
    +
    +  // If we're in a token, append the rest of the buffer to it.
    +  if (record_target_ != NULL && record_start_ < buffer_size_) {
    +    record_target_->append(buffer_ + record_start_, buffer_size_ - record_start_);
    +    record_start_ = 0;
    +  }
    +
    +  const void* data = NULL;
    +  buffer_ = NULL;
    +  buffer_pos_ = 0;
    +  do {
    +    if (!input_->Next(&data, &buffer_size_)) {
    +      // end of stream (or read error)
    +      buffer_size_ = 0;
    +      read_error_ = true;
    +      current_char_ = '\0';
    +      return;
    +    }
    +  } while (buffer_size_ == 0);
    +
    +  buffer_ = static_cast(data);
    +
    +  current_char_ = buffer_[0];
    +}
    +
    +inline void Tokenizer::RecordTo(string* target) {
    +  record_target_ = target;
    +  record_start_ = buffer_pos_;
    +}
    +
    +inline void Tokenizer::StopRecording() {
    +  // Note:  The if() is necessary because some STL implementations crash when
    +  //   you call string::append(NULL, 0), presumably because they are trying to
    +  //   be helpful by detecting the NULL pointer, even though there's nothing
    +  //   wrong with reading zero bytes from NULL.
    +  if (buffer_pos_ != record_start_) {
    +    record_target_->append(buffer_ + record_start_, buffer_pos_ - record_start_);
    +  }
    +  record_target_ = NULL;
    +  record_start_ = -1;
    +}
    +
    +inline void Tokenizer::StartToken() {
    +  current_.type = TYPE_START;    // Just for the sake of initializing it.
    +  current_.text.clear();
    +  current_.line = line_;
    +  current_.column = column_;
    +  RecordTo(¤t_.text);
    +}
    +
    +inline void Tokenizer::EndToken() {
    +  StopRecording();
    +  current_.end_column = column_;
    +}
    +
    +// -------------------------------------------------------------------
    +// Helper methods that consume characters.
    +
    +template
    +inline bool Tokenizer::LookingAt() {
    +  return CharacterClass::InClass(current_char_);
    +}
    +
    +template
    +inline bool Tokenizer::TryConsumeOne() {
    +  if (CharacterClass::InClass(current_char_)) {
    +    NextChar();
    +    return true;
    +  } else {
    +    return false;
    +  }
    +}
    +
    +inline bool Tokenizer::TryConsume(char c) {
    +  if (current_char_ == c) {
    +    NextChar();
    +    return true;
    +  } else {
    +    return false;
    +  }
    +}
    +
    +template
    +inline void Tokenizer::ConsumeZeroOrMore() {
    +  while (CharacterClass::InClass(current_char_)) {
    +    NextChar();
    +  }
    +}
    +
    +template
    +inline void Tokenizer::ConsumeOneOrMore(const char* error) {
    +  if (!CharacterClass::InClass(current_char_)) {
    +    AddError(error);
    +  } else {
    +    do {
    +      NextChar();
    +    } while (CharacterClass::InClass(current_char_));
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +// Methods that read whole patterns matching certain kinds of tokens
    +// or comments.
    +
    +void Tokenizer::ConsumeString(char delimiter) {
    +  while (true) {
    +    switch (current_char_) {
    +      case '\0':
    +        AddError("Unexpected end of string.");
    +        return;
    +
    +      case '\n': {
    +        if (!allow_multiline_strings_) {
    +          AddError("String literals cannot cross line boundaries.");
    +          return;
    +        }
    +        NextChar();
    +        break;
    +      }
    +
    +      case '\\': {
    +        // An escape sequence.
    +        NextChar();
    +        if (TryConsumeOne()) {
    +          // Valid escape sequence.
    +        } else if (TryConsumeOne()) {
    +          // Possibly followed by two more octal digits, but these will
    +          // just be consumed by the main loop anyway so we don't need
    +          // to do so explicitly here.
    +        } else if (TryConsume('x') || TryConsume('X')) {
    +          if (!TryConsumeOne()) {
    +            AddError("Expected hex digits for escape sequence.");
    +          }
    +          // Possibly followed by another hex digit, but again we don't care.
    +        } else if (TryConsume('u')) {
    +          if (!TryConsumeOne() ||
    +              !TryConsumeOne() ||
    +              !TryConsumeOne() ||
    +              !TryConsumeOne()) {
    +            AddError("Expected four hex digits for \\u escape sequence.");
    +          }
    +        } else if (TryConsume('U')) {
    +          // We expect 8 hex digits; but only the range up to 0x10ffff is
    +          // legal.
    +          if (!TryConsume('0') ||
    +              !TryConsume('0') ||
    +              !(TryConsume('0') || TryConsume('1')) ||
    +              !TryConsumeOne() ||
    +              !TryConsumeOne() ||
    +              !TryConsumeOne() ||
    +              !TryConsumeOne() ||
    +              !TryConsumeOne()) {
    +            AddError("Expected eight hex digits up to 10ffff for \\U escape "
    +                     "sequence");
    +          }
    +        } else {
    +          AddError("Invalid escape sequence in string literal.");
    +        }
    +        break;
    +      }
    +
    +      default: {
    +        if (current_char_ == delimiter) {
    +          NextChar();
    +          return;
    +        }
    +        NextChar();
    +        break;
    +      }
    +    }
    +  }
    +}
    +
    +Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero,
    +                                              bool started_with_dot) {
    +  bool is_float = false;
    +
    +  if (started_with_zero && (TryConsume('x') || TryConsume('X'))) {
    +    // A hex number (started with "0x").
    +    ConsumeOneOrMore("\"0x\" must be followed by hex digits.");
    +
    +  } else if (started_with_zero && LookingAt()) {
    +    // An octal number (had a leading zero).
    +    ConsumeZeroOrMore();
    +    if (LookingAt()) {
    +      AddError("Numbers starting with leading zero must be in octal.");
    +      ConsumeZeroOrMore();
    +    }
    +
    +  } else {
    +    // A decimal number.
    +    if (started_with_dot) {
    +      is_float = true;
    +      ConsumeZeroOrMore();
    +    } else {
    +      ConsumeZeroOrMore();
    +
    +      if (TryConsume('.')) {
    +        is_float = true;
    +        ConsumeZeroOrMore();
    +      }
    +    }
    +
    +    if (TryConsume('e') || TryConsume('E')) {
    +      is_float = true;
    +      TryConsume('-') || TryConsume('+');
    +      ConsumeOneOrMore("\"e\" must be followed by exponent.");
    +    }
    +
    +    if (allow_f_after_float_ && (TryConsume('f') || TryConsume('F'))) {
    +      is_float = true;
    +    }
    +  }
    +
    +  if (LookingAt() && require_space_after_number_) {
    +    AddError("Need space between number and identifier.");
    +  } else if (current_char_ == '.') {
    +    if (is_float) {
    +      AddError(
    +        "Already saw decimal point or exponent; can't have another one.");
    +    } else {
    +      AddError("Hex and octal numbers must be integers.");
    +    }
    +  }
    +
    +  return is_float ? TYPE_FLOAT : TYPE_INTEGER;
    +}
    +
    +void Tokenizer::ConsumeLineComment(string* content) {
    +  if (content != NULL) RecordTo(content);
    +
    +  while (current_char_ != '\0' && current_char_ != '\n') {
    +    NextChar();
    +  }
    +  TryConsume('\n');
    +
    +  if (content != NULL) StopRecording();
    +}
    +
    +void Tokenizer::ConsumeBlockComment(string* content) {
    +  int start_line = line_;
    +  int start_column = column_ - 2;
    +
    +  if (content != NULL) RecordTo(content);
    +
    +  while (true) {
    +    while (current_char_ != '\0' &&
    +           current_char_ != '*' &&
    +           current_char_ != '/' &&
    +           current_char_ != '\n') {
    +      NextChar();
    +    }
    +
    +    if (TryConsume('\n')) {
    +      if (content != NULL) StopRecording();
    +
    +      // Consume leading whitespace and asterisk;
    +      ConsumeZeroOrMore();
    +      if (TryConsume('*')) {
    +        if (TryConsume('/')) {
    +          // End of comment.
    +          break;
    +        }
    +      }
    +
    +      if (content != NULL) RecordTo(content);
    +    } else if (TryConsume('*') && TryConsume('/')) {
    +      // End of comment.
    +      if (content != NULL) {
    +        StopRecording();
    +        // Strip trailing "*/".
    +        content->erase(content->size() - 2);
    +      }
    +      break;
    +    } else if (TryConsume('/') && current_char_ == '*') {
    +      // Note:  We didn't consume the '*' because if there is a '/' after it
    +      //   we want to interpret that as the end of the comment.
    +      AddError(
    +        "\"/*\" inside block comment.  Block comments cannot be nested.");
    +    } else if (current_char_ == '\0') {
    +      AddError("End-of-file inside block comment.");
    +      error_collector_->AddError(
    +        start_line, start_column, "  Comment started here.");
    +      if (content != NULL) StopRecording();
    +      break;
    +    }
    +  }
    +}
    +
    +Tokenizer::NextCommentStatus Tokenizer::TryConsumeCommentStart() {
    +  if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) {
    +    if (TryConsume('/')) {
    +      return LINE_COMMENT;
    +    } else if (TryConsume('*')) {
    +      return BLOCK_COMMENT;
    +    } else {
    +      // Oops, it was just a slash.  Return it.
    +      current_.type = TYPE_SYMBOL;
    +      current_.text = "/";
    +      current_.line = line_;
    +      current_.column = column_ - 1;
    +      current_.end_column = column_;
    +      return SLASH_NOT_COMMENT;
    +    }
    +  } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) {
    +    return LINE_COMMENT;
    +  } else {
    +    return NO_COMMENT;
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +
    +bool Tokenizer::Next() {
    +  previous_ = current_;
    +
    +  while (!read_error_) {
    +    ConsumeZeroOrMore();
    +
    +    switch (TryConsumeCommentStart()) {
    +      case LINE_COMMENT:
    +        ConsumeLineComment(NULL);
    +        continue;
    +      case BLOCK_COMMENT:
    +        ConsumeBlockComment(NULL);
    +        continue;
    +      case SLASH_NOT_COMMENT:
    +        return true;
    +      case NO_COMMENT:
    +        break;
    +    }
    +
    +    // Check for EOF before continuing.
    +    if (read_error_) break;
    +
    +    if (LookingAt() || current_char_ == '\0') {
    +      AddError("Invalid control characters encountered in text.");
    +      NextChar();
    +      // Skip more unprintable characters, too.  But, remember that '\0' is
    +      // also what current_char_ is set to after EOF / read error.  We have
    +      // to be careful not to go into an infinite loop of trying to consume
    +      // it, so make sure to check read_error_ explicitly before consuming
    +      // '\0'.
    +      while (TryConsumeOne() ||
    +             (!read_error_ && TryConsume('\0'))) {
    +        // Ignore.
    +      }
    +
    +    } else {
    +      // Reading some sort of token.
    +      StartToken();
    +
    +      if (TryConsumeOne()) {
    +        ConsumeZeroOrMore();
    +        current_.type = TYPE_IDENTIFIER;
    +      } else if (TryConsume('0')) {
    +        current_.type = ConsumeNumber(true, false);
    +      } else if (TryConsume('.')) {
    +        // This could be the beginning of a floating-point number, or it could
    +        // just be a '.' symbol.
    +
    +        if (TryConsumeOne()) {
    +          // It's a floating-point number.
    +          if (previous_.type == TYPE_IDENTIFIER &&
    +              current_.line == previous_.line &&
    +              current_.column == previous_.end_column) {
    +            // We don't accept syntax like "blah.123".
    +            error_collector_->AddError(line_, column_ - 2,
    +              "Need space between identifier and decimal point.");
    +          }
    +          current_.type = ConsumeNumber(false, true);
    +        } else {
    +          current_.type = TYPE_SYMBOL;
    +        }
    +      } else if (TryConsumeOne()) {
    +        current_.type = ConsumeNumber(false, false);
    +      } else if (TryConsume('\"')) {
    +        ConsumeString('\"');
    +        current_.type = TYPE_STRING;
    +      } else if (TryConsume('\'')) {
    +        ConsumeString('\'');
    +        current_.type = TYPE_STRING;
    +      } else {
    +        // Check if the high order bit is set.
    +        if (current_char_ & 0x80) {
    +          error_collector_->AddError(line_, column_,
    +              StringPrintf("Interpreting non ascii codepoint %d.",
    +                           static_cast(current_char_)));
    +        }
    +        NextChar();
    +        current_.type = TYPE_SYMBOL;
    +      }
    +
    +      EndToken();
    +      return true;
    +    }
    +  }
    +
    +  // EOF
    +  current_.type = TYPE_END;
    +  current_.text.clear();
    +  current_.line = line_;
    +  current_.column = column_;
    +  current_.end_column = column_;
    +  return false;
    +}
    +
    +namespace {
    +
    +// Helper class for collecting comments and putting them in the right places.
    +//
    +// This basically just buffers the most recent comment until it can be decided
    +// exactly where that comment should be placed.  When Flush() is called, the
    +// current comment goes into either prev_trailing_comments or detached_comments.
    +// When the CommentCollector is destroyed, the last buffered comment goes into
    +// next_leading_comments.
    +class CommentCollector {
    + public:
    +  CommentCollector(string* prev_trailing_comments,
    +                   vector* detached_comments,
    +                   string* next_leading_comments)
    +      : prev_trailing_comments_(prev_trailing_comments),
    +        detached_comments_(detached_comments),
    +        next_leading_comments_(next_leading_comments),
    +        has_comment_(false),
    +        is_line_comment_(false),
    +        can_attach_to_prev_(true) {
    +    if (prev_trailing_comments != NULL) prev_trailing_comments->clear();
    +    if (detached_comments != NULL) detached_comments->clear();
    +    if (next_leading_comments != NULL) next_leading_comments->clear();
    +  }
    +
    +  ~CommentCollector() {
    +    // Whatever is in the buffer is a leading comment.
    +    if (next_leading_comments_ != NULL && has_comment_) {
    +      comment_buffer_.swap(*next_leading_comments_);
    +    }
    +  }
    +
    +  // About to read a line comment.  Get the comment buffer pointer in order to
    +  // read into it.
    +  string* GetBufferForLineComment() {
    +    // We want to combine with previous line comments, but not block comments.
    +    if (has_comment_ && !is_line_comment_) {
    +      Flush();
    +    }
    +    has_comment_ = true;
    +    is_line_comment_ = true;
    +    return &comment_buffer_;
    +  }
    +
    +  // About to read a block comment.  Get the comment buffer pointer in order to
    +  // read into it.
    +  string* GetBufferForBlockComment() {
    +    if (has_comment_) {
    +      Flush();
    +    }
    +    has_comment_ = true;
    +    is_line_comment_ = false;
    +    return &comment_buffer_;
    +  }
    +
    +  void ClearBuffer() {
    +    comment_buffer_.clear();
    +    has_comment_ = false;
    +  }
    +
    +  // Called once we know that the comment buffer is complete and is *not*
    +  // connected to the next token.
    +  void Flush() {
    +    if (has_comment_) {
    +      if (can_attach_to_prev_) {
    +        if (prev_trailing_comments_ != NULL) {
    +          prev_trailing_comments_->append(comment_buffer_);
    +        }
    +        can_attach_to_prev_ = false;
    +      } else {
    +        if (detached_comments_ != NULL) {
    +          detached_comments_->push_back(comment_buffer_);
    +        }
    +      }
    +      ClearBuffer();
    +    }
    +  }
    +
    +  void DetachFromPrev() {
    +    can_attach_to_prev_ = false;
    +  }
    +
    + private:
    +  string* prev_trailing_comments_;
    +  vector* detached_comments_;
    +  string* next_leading_comments_;
    +
    +  string comment_buffer_;
    +
    +  // True if any comments were read into comment_buffer_.  This can be true even
    +  // if comment_buffer_ is empty, namely if the comment was "/**/".
    +  bool has_comment_;
    +
    +  // Is the comment in the comment buffer a line comment?
    +  bool is_line_comment_;
    +
    +  // Is it still possible that we could be reading a comment attached to the
    +  // previous token?
    +  bool can_attach_to_prev_;
    +};
    +
    +} // namespace
    +
    +bool Tokenizer::NextWithComments(string* prev_trailing_comments,
    +                                 vector* detached_comments,
    +                                 string* next_leading_comments) {
    +  CommentCollector collector(prev_trailing_comments, detached_comments,
    +                             next_leading_comments);
    +
    +  if (current_.type == TYPE_START) {
    +    collector.DetachFromPrev();
    +  } else {
    +    // A comment appearing on the same line must be attached to the previous
    +    // declaration.
    +    ConsumeZeroOrMore();
    +    switch (TryConsumeCommentStart()) {
    +      case LINE_COMMENT:
    +        ConsumeLineComment(collector.GetBufferForLineComment());
    +
    +        // Don't allow comments on subsequent lines to be attached to a trailing
    +        // comment.
    +        collector.Flush();
    +        break;
    +      case BLOCK_COMMENT:
    +        ConsumeBlockComment(collector.GetBufferForBlockComment());
    +
    +        ConsumeZeroOrMore();
    +        if (!TryConsume('\n')) {
    +          // Oops, the next token is on the same line.  If we recorded a comment
    +          // we really have no idea which token it should be attached to.
    +          collector.ClearBuffer();
    +          return Next();
    +        }
    +
    +        // Don't allow comments on subsequent lines to be attached to a trailing
    +        // comment.
    +        collector.Flush();
    +        break;
    +      case SLASH_NOT_COMMENT:
    +        return true;
    +      case NO_COMMENT:
    +        if (!TryConsume('\n')) {
    +          // The next token is on the same line.  There are no comments.
    +          return Next();
    +        }
    +        break;
    +    }
    +  }
    +
    +  // OK, we are now on the line *after* the previous token.
    +  while (true) {
    +    ConsumeZeroOrMore();
    +
    +    switch (TryConsumeCommentStart()) {
    +      case LINE_COMMENT:
    +        ConsumeLineComment(collector.GetBufferForLineComment());
    +        break;
    +      case BLOCK_COMMENT:
    +        ConsumeBlockComment(collector.GetBufferForBlockComment());
    +
    +        // Consume the rest of the line so that we don't interpret it as a
    +        // blank line the next time around the loop.
    +        ConsumeZeroOrMore();
    +        TryConsume('\n');
    +        break;
    +      case SLASH_NOT_COMMENT:
    +        return true;
    +      case NO_COMMENT:
    +        if (TryConsume('\n')) {
    +          // Completely blank line.
    +          collector.Flush();
    +          collector.DetachFromPrev();
    +        } else {
    +          bool result = Next();
    +          if (!result ||
    +              current_.text == "}" ||
    +              current_.text == "]" ||
    +              current_.text == ")") {
    +            // It looks like we're at the end of a scope.  In this case it
    +            // makes no sense to attach a comment to the following token.
    +            collector.Flush();
    +          }
    +          return result;
    +        }
    +        break;
    +    }
    +  }
    +}
    +
    +// -------------------------------------------------------------------
    +// Token-parsing helpers.  Remember that these don't need to report
    +// errors since any errors should already have been reported while
    +// tokenizing.  Also, these can assume that whatever text they
    +// are given is text that the tokenizer actually parsed as a token
    +// of the given type.
    +
    +bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
    +                             uint64* output) {
    +  // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull()
    +  // is non-standard.  I hate the C standard library.  :(
    +
    +//  return strtoull(text.c_str(), NULL, 0);
    +
    +  const char* ptr = text.c_str();
    +  int base = 10;
    +  if (ptr[0] == '0') {
    +    if (ptr[1] == 'x' || ptr[1] == 'X') {
    +      // This is hex.
    +      base = 16;
    +      ptr += 2;
    +    } else {
    +      // This is octal.
    +      base = 8;
    +    }
    +  }
    +
    +  uint64 result = 0;
    +  for (; *ptr != '\0'; ptr++) {
    +    int digit = DigitValue(*ptr);
    +    GOOGLE_LOG_IF(DFATAL, digit < 0 || digit >= base)
    +      << " Tokenizer::ParseInteger() passed text that could not have been"
    +         " tokenized as an integer: " << CEscape(text);
    +    if (digit > max_value || result > (max_value - digit) / base) {
    +      // Overflow.
    +      return false;
    +    }
    +    result = result * base + digit;
    +  }
    +
    +  *output = result;
    +  return true;
    +}
    +
    +double Tokenizer::ParseFloat(const string& text) {
    +  const char* start = text.c_str();
    +  char* end;
    +  double result = NoLocaleStrtod(start, &end);
    +
    +  // "1e" is not a valid float, but if the tokenizer reads it, it will
    +  // report an error but still return it as a valid token.  We need to
    +  // accept anything the tokenizer could possibly return, error or not.
    +  if (*end == 'e' || *end == 'E') {
    +    ++end;
    +    if (*end == '-' || *end == '+') ++end;
    +  }
    +
    +  // If the Tokenizer had allow_f_after_float_ enabled, the float may be
    +  // suffixed with the letter 'f'.
    +  if (*end == 'f' || *end == 'F') {
    +    ++end;
    +  }
    +
    +  GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-')
    +    << " Tokenizer::ParseFloat() passed text that could not have been"
    +       " tokenized as a float: " << CEscape(text);
    +  return result;
    +}
    +
    +// Helper to append a Unicode code point to a string as UTF8, without bringing
    +// in any external dependencies.
    +static void AppendUTF8(uint32 code_point, string* output) {
    +  uint32 tmp = 0;
    +  int len = 0;
    +  if (code_point <= 0x7f) {
    +    tmp = code_point;
    +    len = 1;
    +  } else if (code_point <= 0x07ff) {
    +    tmp = 0x0000c080 |
    +        ((code_point & 0x07c0) << 2) |
    +        (code_point & 0x003f);
    +    len = 2;
    +  } else if (code_point <= 0xffff) {
    +    tmp = 0x00e08080 |
    +        ((code_point & 0xf000) << 4) |
    +        ((code_point & 0x0fc0) << 2) |
    +        (code_point & 0x003f);
    +    len = 3;
    +  } else if (code_point <= 0x1fffff) {
    +    tmp = 0xf0808080 |
    +        ((code_point & 0x1c0000) << 6) |
    +        ((code_point & 0x03f000) << 4) |
    +        ((code_point & 0x000fc0) << 2) |
    +        (code_point & 0x003f);
    +    len = 4;
    +  } else {
    +    // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is
    +    // normally only defined up to there as well.
    +    StringAppendF(output, "\\U%08x", code_point);
    +    return;
    +  }
    +  tmp = ghtonl(tmp);
    +  output->append(reinterpret_cast(&tmp) + sizeof(tmp) - len, len);
    +}
    +
    +// Try to read  hex digits from ptr, and stuff the numeric result into
    +// *result. Returns true if that many digits were successfully consumed.
    +static bool ReadHexDigits(const char* ptr, int len, uint32* result) {
    +  *result = 0;
    +  if (len == 0) return false;
    +  for (const char* end = ptr + len; ptr < end; ++ptr) {
    +    if (*ptr == '\0') return false;
    +    *result = (*result << 4) + DigitValue(*ptr);
    +  }
    +  return true;
    +}
    +
    +// Handling UTF-16 surrogate pairs. UTF-16 encodes code points in the range
    +// 0x10000...0x10ffff as a pair of numbers, a head surrogate followed by a trail
    +// surrogate. These numbers are in a reserved range of Unicode code points, so
    +// if we encounter such a pair we know how to parse it and convert it into a
    +// single code point.
    +static const uint32 kMinHeadSurrogate = 0xd800;
    +static const uint32 kMaxHeadSurrogate = 0xdc00;
    +static const uint32 kMinTrailSurrogate = 0xdc00;
    +static const uint32 kMaxTrailSurrogate = 0xe000;
    +
    +static inline bool IsHeadSurrogate(uint32 code_point) {
    +  return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate);
    +}
    +
    +static inline bool IsTrailSurrogate(uint32 code_point) {
    +  return (code_point >= kMinTrailSurrogate) &&
    +      (code_point < kMaxTrailSurrogate);
    +}
    +
    +// Combine a head and trail surrogate into a single Unicode code point.
    +static uint32 AssembleUTF16(uint32 head_surrogate, uint32 trail_surrogate) {
    +  GOOGLE_DCHECK(IsHeadSurrogate(head_surrogate));
    +  GOOGLE_DCHECK(IsTrailSurrogate(trail_surrogate));
    +  return 0x10000 + (((head_surrogate - kMinHeadSurrogate) << 10) |
    +      (trail_surrogate - kMinTrailSurrogate));
    +}
    +
    +// Convert the escape sequence parameter to a number of expected hex digits.
    +static inline int UnicodeLength(char key) {
    +  if (key == 'u') return 4;
    +  if (key == 'U') return 8;
    +  return 0;
    +}
    +
    +// Given a pointer to the 'u' or 'U' starting a Unicode escape sequence, attempt
    +// to parse that sequence. On success, returns a pointer to the first char
    +// beyond that sequence, and fills in *code_point. On failure, returns ptr
    +// itself.
    +static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) {
    +  const char* p = ptr;
    +  // Fetch the code point.
    +  const int len = UnicodeLength(*p++);
    +  if (!ReadHexDigits(p, len, code_point))
    +    return ptr;
    +  p += len;
    +
    +  // Check if the code point we read is a "head surrogate." If so, then we
    +  // expect it to be immediately followed by another code point which is a valid
    +  // "trail surrogate," and together they form a UTF-16 pair which decodes into
    +  // a single Unicode point. Trail surrogates may only use \u, not \U.
    +  if (IsHeadSurrogate(*code_point) && *p == '\\' && *(p + 1) == 'u') {
    +    uint32 trail_surrogate;
    +    if (ReadHexDigits(p + 2, 4, &trail_surrogate) &&
    +        IsTrailSurrogate(trail_surrogate)) {
    +      *code_point = AssembleUTF16(*code_point, trail_surrogate);
    +      p += 6;
    +    }
    +    // If this failed, then we just emit the head surrogate as a code point.
    +    // It's bogus, but so is the string.
    +  }
    +
    +  return p;
    +}
    +
    +// The text string must begin and end with single or double quote
    +// characters.
    +void Tokenizer::ParseStringAppend(const string& text, string* output) {
    +  // Reminder: text[0] is always a quote character.  (If text is
    +  // empty, it's invalid, so we'll just return).
    +  const size_t text_size = text.size();
    +  if (text_size == 0) {
    +    GOOGLE_LOG(DFATAL)
    +      << " Tokenizer::ParseStringAppend() passed text that could not"
    +         " have been tokenized as a string: " << CEscape(text);
    +    return;
    +  }
    +
    +  // Reserve room for new string. The branch is necessary because if
    +  // there is already space available the reserve() call might
    +  // downsize the output.
    +  const size_t new_len = text_size + output->size();
    +  if (new_len > output->capacity()) {
    +    output->reserve(new_len);
    +  }
    +
    +  // Loop through the string copying characters to "output" and
    +  // interpreting escape sequences.  Note that any invalid escape
    +  // sequences or other errors were already reported while tokenizing.
    +  // In this case we do not need to produce valid results.
    +  for (const char* ptr = text.c_str() + 1; *ptr != '\0'; ptr++) {
    +    if (*ptr == '\\' && ptr[1] != '\0') {
    +      // An escape sequence.
    +      ++ptr;
    +
    +      if (OctalDigit::InClass(*ptr)) {
    +        // An octal escape.  May one, two, or three digits.
    +        int code = DigitValue(*ptr);
    +        if (OctalDigit::InClass(ptr[1])) {
    +          ++ptr;
    +          code = code * 8 + DigitValue(*ptr);
    +        }
    +        if (OctalDigit::InClass(ptr[1])) {
    +          ++ptr;
    +          code = code * 8 + DigitValue(*ptr);
    +        }
    +        output->push_back(static_cast(code));
    +
    +      } else if (*ptr == 'x') {
    +        // A hex escape.  May zero, one, or two digits.  (The zero case
    +        // will have been caught as an error earlier.)
    +        int code = 0;
    +        if (HexDigit::InClass(ptr[1])) {
    +          ++ptr;
    +          code = DigitValue(*ptr);
    +        }
    +        if (HexDigit::InClass(ptr[1])) {
    +          ++ptr;
    +          code = code * 16 + DigitValue(*ptr);
    +        }
    +        output->push_back(static_cast(code));
    +
    +      } else if (*ptr == 'u' || *ptr == 'U') {
    +        uint32 unicode;
    +        const char* end = FetchUnicodePoint(ptr, &unicode);
    +        if (end == ptr) {
    +          // Failure: Just dump out what we saw, don't try to parse it.
    +          output->push_back(*ptr);
    +        } else {
    +          AppendUTF8(unicode, output);
    +          ptr = end - 1;  // Because we're about to ++ptr.
    +        }
    +      } else {
    +        // Some other escape code.
    +        output->push_back(TranslateEscape(*ptr));
    +      }
    +
    +    } else if (*ptr == text[0] && ptr[1] == '\0') {
    +      // Ignore final quote matching the starting quote.
    +    } else {
    +      output->push_back(*ptr);
    +    }
    +  }
    +}
    +
    +template
    +static bool AllInClass(const string& s) {
    +  for (int i = 0; i < s.size(); ++i) {
    +    if (!CharacterClass::InClass(s[i]))
    +      return false;
    +  }
    +  return true;
    +}
    +
    +bool Tokenizer::IsIdentifier(const string& text) {
    +  // Mirrors IDENTIFIER definition in Tokenizer::Next() above.
    +  if (text.size() == 0)
    +    return false;
    +  if (!Letter::InClass(text.at(0)))
    +    return false;
    +  if (!AllInClass(text.substr(1)))
    +    return false;
    +  return true;
    +}
    +
    +}  // namespace io
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h
    new file mode 100644
    index 000000000000..8c6220a1d088
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h
    @@ -0,0 +1,402 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Class for parsing tokenized text from a ZeroCopyInputStream.
    +
    +#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__
    +#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
    +
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +class ZeroCopyInputStream;     // zero_copy_stream.h
    +
    +// Defined in this file.
    +class ErrorCollector;
    +class Tokenizer;
    +
    +// Abstract interface for an object which collects the errors that occur
    +// during parsing.  A typical implementation might simply print the errors
    +// to stdout.
    +class LIBPROTOBUF_EXPORT ErrorCollector {
    + public:
    +  inline ErrorCollector() {}
    +  virtual ~ErrorCollector();
    +
    +  // Indicates that there was an error in the input at the given line and
    +  // column numbers.  The numbers are zero-based, so you may want to add
    +  // 1 to each before printing them.
    +  virtual void AddError(int line, int column, const string& message) = 0;
    +
    +  // Indicates that there was a warning in the input at the given line and
    +  // column numbers.  The numbers are zero-based, so you may want to add
    +  // 1 to each before printing them.
    +  virtual void AddWarning(int /* line */, int /* column */,
    +                          const string& /* message */) { }
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
    +};
    +
    +// This class converts a stream of raw text into a stream of tokens for
    +// the protocol definition parser to parse.  The tokens recognized are
    +// similar to those that make up the C language; see the TokenType enum for
    +// precise descriptions.  Whitespace and comments are skipped.  By default,
    +// C- and C++-style comments are recognized, but other styles can be used by
    +// calling set_comment_style().
    +class LIBPROTOBUF_EXPORT Tokenizer {
    + public:
    +  // Construct a Tokenizer that reads and tokenizes text from the given
    +  // input stream and writes errors to the given error_collector.
    +  // The caller keeps ownership of input and error_collector.
    +  Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector);
    +  ~Tokenizer();
    +
    +  enum TokenType {
    +    TYPE_START,       // Next() has not yet been called.
    +    TYPE_END,         // End of input reached.  "text" is empty.
    +
    +    TYPE_IDENTIFIER,  // A sequence of letters, digits, and underscores, not
    +                      // starting with a digit.  It is an error for a number
    +                      // to be followed by an identifier with no space in
    +                      // between.
    +    TYPE_INTEGER,     // A sequence of digits representing an integer.  Normally
    +                      // the digits are decimal, but a prefix of "0x" indicates
    +                      // a hex number and a leading zero indicates octal, just
    +                      // like with C numeric literals.  A leading negative sign
    +                      // is NOT included in the token; it's up to the parser to
    +                      // interpret the unary minus operator on its own.
    +    TYPE_FLOAT,       // A floating point literal, with a fractional part and/or
    +                      // an exponent.  Always in decimal.  Again, never
    +                      // negative.
    +    TYPE_STRING,      // A quoted sequence of escaped characters.  Either single
    +                      // or double quotes can be used, but they must match.
    +                      // A string literal cannot cross a line break.
    +    TYPE_SYMBOL,      // Any other printable character, like '!' or '+'.
    +                      // Symbols are always a single character, so "!+$%" is
    +                      // four tokens.
    +  };
    +
    +  // Structure representing a token read from the token stream.
    +  struct Token {
    +    TokenType type;
    +    string text;       // The exact text of the token as it appeared in
    +                       // the input.  e.g. tokens of TYPE_STRING will still
    +                       // be escaped and in quotes.
    +
    +    // "line" and "column" specify the position of the first character of
    +    // the token within the input stream.  They are zero-based.
    +    int line;
    +    int column;
    +    int end_column;
    +  };
    +
    +  // Get the current token.  This is updated when Next() is called.  Before
    +  // the first call to Next(), current() has type TYPE_START and no contents.
    +  const Token& current();
    +
    +  // Return the previous token -- i.e. what current() returned before the
    +  // previous call to Next().
    +  const Token& previous();
    +
    +  // Advance to the next token.  Returns false if the end of the input is
    +  // reached.
    +  bool Next();
    +
    +  // Like Next(), but also collects comments which appear between the previous
    +  // and next tokens.
    +  //
    +  // Comments which appear to be attached to the previous token are stored
    +  // in *prev_tailing_comments.  Comments which appear to be attached to the
    +  // next token are stored in *next_leading_comments.  Comments appearing in
    +  // between which do not appear to be attached to either will be added to
    +  // detached_comments.  Any of these parameters can be NULL to simply discard
    +  // the comments.
    +  //
    +  // A series of line comments appearing on consecutive lines, with no other
    +  // tokens appearing on those lines, will be treated as a single comment.
    +  //
    +  // Only the comment content is returned; comment markers (e.g. //) are
    +  // stripped out.  For block comments, leading whitespace and an asterisk will
    +  // be stripped from the beginning of each line other than the first.  Newlines
    +  // are included in the output.
    +  //
    +  // Examples:
    +  //
    +  //   optional int32 foo = 1;  // Comment attached to foo.
    +  //   // Comment attached to bar.
    +  //   optional int32 bar = 2;
    +  //
    +  //   optional string baz = 3;
    +  //   // Comment attached to baz.
    +  //   // Another line attached to baz.
    +  //
    +  //   // Comment attached to qux.
    +  //   //
    +  //   // Another line attached to qux.
    +  //   optional double qux = 4;
    +  //
    +  //   // Detached comment.  This is not attached to qux or corge
    +  //   // because there are blank lines separating it from both.
    +  //
    +  //   optional string corge = 5;
    +  //   /* Block comment attached
    +  //    * to corge.  Leading asterisks
    +  //    * will be removed. */
    +  //   /* Block comment attached to
    +  //    * grault. */
    +  //   optional int32 grault = 6;
    +  bool NextWithComments(string* prev_trailing_comments,
    +                        vector* detached_comments,
    +                        string* next_leading_comments);
    +
    +  // Parse helpers ---------------------------------------------------
    +
    +  // Parses a TYPE_FLOAT token.  This never fails, so long as the text actually
    +  // comes from a TYPE_FLOAT token parsed by Tokenizer.  If it doesn't, the
    +  // result is undefined (possibly an assert failure).
    +  static double ParseFloat(const string& text);
    +
    +  // Parses a TYPE_STRING token.  This never fails, so long as the text actually
    +  // comes from a TYPE_STRING token parsed by Tokenizer.  If it doesn't, the
    +  // result is undefined (possibly an assert failure).
    +  static void ParseString(const string& text, string* output);
    +
    +  // Identical to ParseString, but appends to output.
    +  static void ParseStringAppend(const string& text, string* output);
    +
    +  // Parses a TYPE_INTEGER token.  Returns false if the result would be
    +  // greater than max_value.  Otherwise, returns true and sets *output to the
    +  // result.  If the text is not from a Token of type TYPE_INTEGER originally
    +  // parsed by a Tokenizer, the result is undefined (possibly an assert
    +  // failure).
    +  static bool ParseInteger(const string& text, uint64 max_value,
    +                           uint64* output);
    +
    +  // Options ---------------------------------------------------------
    +
    +  // Set true to allow floats to be suffixed with the letter 'f'.  Tokens
    +  // which would otherwise be integers but which have the 'f' suffix will be
    +  // forced to be interpreted as floats.  For all other purposes, the 'f' is
    +  // ignored.
    +  void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; }
    +
    +  // Valid values for set_comment_style().
    +  enum CommentStyle {
    +    // Line comments begin with "//", block comments are delimited by "/*" and
    +    // "*/".
    +    CPP_COMMENT_STYLE,
    +    // Line comments begin with "#".  No way to write block comments.
    +    SH_COMMENT_STYLE
    +  };
    +
    +  // Sets the comment style.
    +  void set_comment_style(CommentStyle style) { comment_style_ = style; }
    +
    +  // Whether to require whitespace between a number and a field name.
    +  // Default is true. Do not use this; for Google-internal cleanup only.
    +  void set_require_space_after_number(bool require) {
    +    require_space_after_number_ = require;
    +  }
    +
    +  // Whether to allow string literals to span multiple lines. Default is false.
    +  // Do not use this; for Google-internal cleanup only.
    +  void set_allow_multiline_strings(bool allow) {
    +    allow_multiline_strings_ = allow;
    +  }
    +
    +  // External helper: validate an identifier.
    +  static bool IsIdentifier(const string& text);
    +
    +  // -----------------------------------------------------------------
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
    +
    +  Token current_;           // Returned by current().
    +  Token previous_;          // Returned by previous().
    +
    +  ZeroCopyInputStream* input_;
    +  ErrorCollector* error_collector_;
    +
    +  char current_char_;       // == buffer_[buffer_pos_], updated by NextChar().
    +  const char* buffer_;      // Current buffer returned from input_.
    +  int buffer_size_;         // Size of buffer_.
    +  int buffer_pos_;          // Current position within the buffer.
    +  bool read_error_;         // Did we previously encounter a read error?
    +
    +  // Line and column number of current_char_ within the whole input stream.
    +  int line_;
    +  int column_;
    +
    +  // String to which text should be appended as we advance through it.
    +  // Call RecordTo(&str) to start recording and StopRecording() to stop.
    +  // E.g. StartToken() calls RecordTo(¤t_.text).  record_start_ is the
    +  // position within the current buffer where recording started.
    +  string* record_target_;
    +  int record_start_;
    +
    +  // Options.
    +  bool allow_f_after_float_;
    +  CommentStyle comment_style_;
    +  bool require_space_after_number_;
    +  bool allow_multiline_strings_;
    +
    +  // Since we count columns we need to interpret tabs somehow.  We'll take
    +  // the standard 8-character definition for lack of any way to do better.
    +  static const int kTabWidth = 8;
    +
    +  // -----------------------------------------------------------------
    +  // Helper methods.
    +
    +  // Consume this character and advance to the next one.
    +  void NextChar();
    +
    +  // Read a new buffer from the input.
    +  void Refresh();
    +
    +  inline void RecordTo(string* target);
    +  inline void StopRecording();
    +
    +  // Called when the current character is the first character of a new
    +  // token (not including whitespace or comments).
    +  inline void StartToken();
    +  // Called when the current character is the first character after the
    +  // end of the last token.  After this returns, current_.text will
    +  // contain all text consumed since StartToken() was called.
    +  inline void EndToken();
    +
    +  // Convenience method to add an error at the current line and column.
    +  void AddError(const string& message) {
    +    error_collector_->AddError(line_, column_, message);
    +  }
    +
    +  // -----------------------------------------------------------------
    +  // The following four methods are used to consume tokens of specific
    +  // types.  They are actually used to consume all characters *after*
    +  // the first, since the calling function consumes the first character
    +  // in order to decide what kind of token is being read.
    +
    +  // Read and consume a string, ending when the given delimiter is
    +  // consumed.
    +  void ConsumeString(char delimiter);
    +
    +  // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER
    +  // depending on what was read.  This needs to know if the first
    +  // character was a zero in order to correctly recognize hex and octal
    +  // numbers.
    +  // It also needs to know if the first characted was a . to parse floating
    +  // point correctly.
    +  TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
    +
    +  // Consume the rest of a line.
    +  void ConsumeLineComment(string* content);
    +  // Consume until "*/".
    +  void ConsumeBlockComment(string* content);
    +
    +  enum NextCommentStatus {
    +    // Started a line comment.
    +    LINE_COMMENT,
    +
    +    // Started a block comment.
    +    BLOCK_COMMENT,
    +
    +    // Consumed a slash, then realized it wasn't a comment.  current_ has
    +    // been filled in with a slash token.  The caller should return it.
    +    SLASH_NOT_COMMENT,
    +
    +    // We do not appear to be starting a comment here.
    +    NO_COMMENT
    +  };
    +
    +  // If we're at the start of a new comment, consume it and return what kind
    +  // of comment it is.
    +  NextCommentStatus TryConsumeCommentStart();
    +
    +  // -----------------------------------------------------------------
    +  // These helper methods make the parsing code more readable.  The
    +  // "character classes" refered to are defined at the top of the .cc file.
    +  // Basically it is a C++ class with one method:
    +  //   static bool InClass(char c);
    +  // The method returns true if c is a member of this "class", like "Letter"
    +  // or "Digit".
    +
    +  // Returns true if the current character is of the given character
    +  // class, but does not consume anything.
    +  template
    +  inline bool LookingAt();
    +
    +  // If the current character is in the given class, consume it and return
    +  // true.  Otherwise return false.
    +  // e.g. TryConsumeOne()
    +  template
    +  inline bool TryConsumeOne();
    +
    +  // Like above, but try to consume the specific character indicated.
    +  inline bool TryConsume(char c);
    +
    +  // Consume zero or more of the given character class.
    +  template
    +  inline void ConsumeZeroOrMore();
    +
    +  // Consume one or more of the given character class or log the given
    +  // error message.
    +  // e.g. ConsumeOneOrMore("Expected digits.");
    +  template
    +  inline void ConsumeOneOrMore(const char* error);
    +};
    +
    +// inline methods ====================================================
    +inline const Tokenizer::Token& Tokenizer::current() {
    +  return current_;
    +}
    +
    +inline const Tokenizer::Token& Tokenizer::previous() {
    +  return previous_;
    +}
    +
    +inline void Tokenizer::ParseString(const string& text, string* output) {
    +  output->clear();
    +  ParseStringAppend(text, output);
    +}
    +
    +}  // namespace io
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.cc b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc
    similarity index 82%
    rename from toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.cc
    rename to toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc
    index dad6ff14468d..f77c768fc990 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -34,6 +34,7 @@
     
     #include 
     
    +#include 
     
     namespace google {
     namespace protobuf {
    @@ -43,6 +44,14 @@ ZeroCopyInputStream::~ZeroCopyInputStream() {}
     ZeroCopyOutputStream::~ZeroCopyOutputStream() {}
     
     
    +bool ZeroCopyOutputStream::WriteAliasedRaw(const void* /* data */,
    +                                           int /* size */) {
    +  GOOGLE_LOG(FATAL) << "This ZeroCopyOutputStream doesn't support aliasing. "
    +                "Reaching here usually means a ZeroCopyOutputStream "
    +                "implementation bug.";
    +  return false;
    +}
    +
     }  // namespace io
     }  // namespace protobuf
     }  // namespace google
    diff --git a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.h b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h
    similarity index 93%
    rename from toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.h
    rename to toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h
    index db5326f703db..52650fc6686d 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -226,6 +226,16 @@ class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
       // Returns the total number of bytes written since this object was created.
       virtual int64 ByteCount() const = 0;
     
    +  // Write a given chunk of data to the output.  Some output streams may
    +  // implement this in a way that avoids copying. Check AllowsAliasing() before
    +  // calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is
    +  // called on a stream that does not allow aliasing.
    +  //
    +  // NOTE: It is caller's responsibility to ensure that the chunk of memory
    +  // remains live until all of the data has been consumed from the stream.
    +  virtual bool WriteAliasedRaw(const void* data, int size);
    +  virtual bool AllowsAliasing() const { return false; }
    +
     
      private:
       GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
    diff --git a/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
    new file mode 100644
    index 000000000000..f7901b2797eb
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
    @@ -0,0 +1,473 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#ifdef _MSC_VER
    +#include 
    +#else
    +#include 
    +#include 
    +#include 
    +#include 
    +#endif
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +
    +namespace google {
    +namespace protobuf {
    +namespace io {
    +
    +#ifdef _WIN32
    +// Win32 lseek is broken:  If invoked on a non-seekable file descriptor, its
    +// return value is undefined.  We re-define it to always produce an error.
    +#define lseek(fd, offset, origin) ((off_t)-1)
    +#endif
    +
    +namespace {
    +
    +// EINTR sucks.
    +int close_no_eintr(int fd) {
    +  int result;
    +  do {
    +    result = close(fd);
    +  } while (result < 0 && errno == EINTR);
    +  return result;
    +}
    +
    +}  // namespace
    +
    +
    +// ===================================================================
    +
    +FileInputStream::FileInputStream(int file_descriptor, int block_size)
    +  : copying_input_(file_descriptor),
    +    impl_(©ing_input_, block_size) {
    +}
    +
    +FileInputStream::~FileInputStream() {}
    +
    +bool FileInputStream::Close() {
    +  return copying_input_.Close();
    +}
    +
    +bool FileInputStream::Next(const void** data, int* size) {
    +  return impl_.Next(data, size);
    +}
    +
    +void FileInputStream::BackUp(int count) {
    +  impl_.BackUp(count);
    +}
    +
    +bool FileInputStream::Skip(int count) {
    +  return impl_.Skip(count);
    +}
    +
    +int64 FileInputStream::ByteCount() const {
    +  return impl_.ByteCount();
    +}
    +
    +FileInputStream::CopyingFileInputStream::CopyingFileInputStream(
    +    int file_descriptor)
    +  : file_(file_descriptor),
    +    close_on_delete_(false),
    +    is_closed_(false),
    +    errno_(0),
    +    previous_seek_failed_(false) {
    +}
    +
    +FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() {
    +  if (close_on_delete_) {
    +    if (!Close()) {
    +      GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_);
    +    }
    +  }
    +}
    +
    +bool FileInputStream::CopyingFileInputStream::Close() {
    +  GOOGLE_CHECK(!is_closed_);
    +
    +  is_closed_ = true;
    +  if (close_no_eintr(file_) != 0) {
    +    // The docs on close() do not specify whether a file descriptor is still
    +    // open after close() fails with EIO.  However, the glibc source code
    +    // seems to indicate that it is not.
    +    errno_ = errno;
    +    return false;
    +  }
    +
    +  return true;
    +}
    +
    +int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) {
    +  GOOGLE_CHECK(!is_closed_);
    +
    +  int result;
    +  do {
    +    result = read(file_, buffer, size);
    +  } while (result < 0 && errno == EINTR);
    +
    +  if (result < 0) {
    +    // Read error (not EOF).
    +    errno_ = errno;
    +  }
    +
    +  return result;
    +}
    +
    +int FileInputStream::CopyingFileInputStream::Skip(int count) {
    +  GOOGLE_CHECK(!is_closed_);
    +
    +  if (!previous_seek_failed_ &&
    +      lseek(file_, count, SEEK_CUR) != (off_t)-1) {
    +    // Seek succeeded.
    +    return count;
    +  } else {
    +    // Failed to seek.
    +
    +    // Note to self:  Don't seek again.  This file descriptor doesn't
    +    // support it.
    +    previous_seek_failed_ = true;
    +
    +    // Use the default implementation.
    +    return CopyingInputStream::Skip(count);
    +  }
    +}
    +
    +// ===================================================================
    +
    +FileOutputStream::FileOutputStream(int file_descriptor, int block_size)
    +  : copying_output_(file_descriptor),
    +    impl_(©ing_output_, block_size) {
    +}
    +
    +FileOutputStream::~FileOutputStream() {
    +  impl_.Flush();
    +}
    +
    +bool FileOutputStream::Close() {
    +  bool flush_succeeded = impl_.Flush();
    +  return copying_output_.Close() && flush_succeeded;
    +}
    +
    +bool FileOutputStream::Flush() {
    +  return impl_.Flush();
    +}
    +
    +bool FileOutputStream::Next(void** data, int* size) {
    +  return impl_.Next(data, size);
    +}
    +
    +void FileOutputStream::BackUp(int count) {
    +  impl_.BackUp(count);
    +}
    +
    +int64 FileOutputStream::ByteCount() const {
    +  return impl_.ByteCount();
    +}
    +
    +FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream(
    +    int file_descriptor)
    +  : file_(file_descriptor),
    +    close_on_delete_(false),
    +    is_closed_(false),
    +    errno_(0) {
    +}
    +
    +FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() {
    +  if (close_on_delete_) {
    +    if (!Close()) {
    +      GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_);
    +    }
    +  }
    +}
    +
    +bool FileOutputStream::CopyingFileOutputStream::Close() {
    +  GOOGLE_CHECK(!is_closed_);
    +
    +  is_closed_ = true;
    +  if (close_no_eintr(file_) != 0) {
    +    // The docs on close() do not specify whether a file descriptor is still
    +    // open after close() fails with EIO.  However, the glibc source code
    +    // seems to indicate that it is not.
    +    errno_ = errno;
    +    return false;
    +  }
    +
    +  return true;
    +}
    +
    +bool FileOutputStream::CopyingFileOutputStream::Write(
    +    const void* buffer, int size) {
    +  GOOGLE_CHECK(!is_closed_);
    +  int total_written = 0;
    +
    +  const uint8* buffer_base = reinterpret_cast(buffer);
    +
    +  while (total_written < size) {
    +    int bytes;
    +    do {
    +      bytes = write(file_, buffer_base + total_written, size - total_written);
    +    } while (bytes < 0 && errno == EINTR);
    +
    +    if (bytes <= 0) {
    +      // Write error.
    +
    +      // FIXME(kenton):  According to the man page, if write() returns zero,
    +      //   there was no error; write() simply did not write anything.  It's
    +      //   unclear under what circumstances this might happen, but presumably
    +      //   errno won't be set in this case.  I am confused as to how such an
    +      //   event should be handled.  For now I'm treating it as an error, since
    +      //   retrying seems like it could lead to an infinite loop.  I suspect
    +      //   this never actually happens anyway.
    +
    +      if (bytes < 0) {
    +        errno_ = errno;
    +      }
    +      return false;
    +    }
    +    total_written += bytes;
    +  }
    +
    +  return true;
    +}
    +
    +// ===================================================================
    +
    +IstreamInputStream::IstreamInputStream(istream* input, int block_size)
    +  : copying_input_(input),
    +    impl_(©ing_input_, block_size) {
    +}
    +
    +IstreamInputStream::~IstreamInputStream() {}
    +
    +bool IstreamInputStream::Next(const void** data, int* size) {
    +  return impl_.Next(data, size);
    +}
    +
    +void IstreamInputStream::BackUp(int count) {
    +  impl_.BackUp(count);
    +}
    +
    +bool IstreamInputStream::Skip(int count) {
    +  return impl_.Skip(count);
    +}
    +
    +int64 IstreamInputStream::ByteCount() const {
    +  return impl_.ByteCount();
    +}
    +
    +IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream(
    +    istream* input)
    +  : input_(input) {
    +}
    +
    +IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {}
    +
    +int IstreamInputStream::CopyingIstreamInputStream::Read(
    +    void* buffer, int size) {
    +  input_->read(reinterpret_cast(buffer), size);
    +  int result = input_->gcount();
    +  if (result == 0 && input_->fail() && !input_->eof()) {
    +    return -1;
    +  }
    +  return result;
    +}
    +
    +// ===================================================================
    +
    +OstreamOutputStream::OstreamOutputStream(ostream* output, int block_size)
    +  : copying_output_(output),
    +    impl_(©ing_output_, block_size) {
    +}
    +
    +OstreamOutputStream::~OstreamOutputStream() {
    +  impl_.Flush();
    +}
    +
    +bool OstreamOutputStream::Next(void** data, int* size) {
    +  return impl_.Next(data, size);
    +}
    +
    +void OstreamOutputStream::BackUp(int count) {
    +  impl_.BackUp(count);
    +}
    +
    +int64 OstreamOutputStream::ByteCount() const {
    +  return impl_.ByteCount();
    +}
    +
    +OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream(
    +    ostream* output)
    +  : output_(output) {
    +}
    +
    +OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() {
    +}
    +
    +bool OstreamOutputStream::CopyingOstreamOutputStream::Write(
    +    const void* buffer, int size) {
    +  output_->write(reinterpret_cast(buffer), size);
    +  return output_->good();
    +}
    +
    +// ===================================================================
    +
    +ConcatenatingInputStream::ConcatenatingInputStream(
    +    ZeroCopyInputStream* const streams[], int count)
    +  : streams_(streams), stream_count_(count), bytes_retired_(0) {
    +}
    +
    +ConcatenatingInputStream::~ConcatenatingInputStream() {
    +}
    +
    +bool ConcatenatingInputStream::Next(const void** data, int* size) {
    +  while (stream_count_ > 0) {
    +    if (streams_[0]->Next(data, size)) return true;
    +
    +    // That stream is done.  Advance to the next one.
    +    bytes_retired_ += streams_[0]->ByteCount();
    +    ++streams_;
    +    --stream_count_;
    +  }
    +
    +  // No more streams.
    +  return false;
    +}
    +
    +void ConcatenatingInputStream::BackUp(int count) {
    +  if (stream_count_ > 0) {
    +    streams_[0]->BackUp(count);
    +  } else {
    +    GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next().";
    +  }
    +}
    +
    +bool ConcatenatingInputStream::Skip(int count) {
    +  while (stream_count_ > 0) {
    +    // Assume that ByteCount() can be used to find out how much we actually
    +    // skipped when Skip() fails.
    +    int64 target_byte_count = streams_[0]->ByteCount() + count;
    +    if (streams_[0]->Skip(count)) return true;
    +
    +    // Hit the end of the stream.  Figure out how many more bytes we still have
    +    // to skip.
    +    int64 final_byte_count = streams_[0]->ByteCount();
    +    GOOGLE_DCHECK_LT(final_byte_count, target_byte_count);
    +    count = target_byte_count - final_byte_count;
    +
    +    // That stream is done.  Advance to the next one.
    +    bytes_retired_ += final_byte_count;
    +    ++streams_;
    +    --stream_count_;
    +  }
    +
    +  return false;
    +}
    +
    +int64 ConcatenatingInputStream::ByteCount() const {
    +  if (stream_count_ == 0) {
    +    return bytes_retired_;
    +  } else {
    +    return bytes_retired_ + streams_[0]->ByteCount();
    +  }
    +}
    +
    +
    +// ===================================================================
    +
    +LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input,
    +                                         int64 limit)
    +  : input_(input), limit_(limit) {
    +  prior_bytes_read_ = input_->ByteCount();
    +}
    +
    +LimitingInputStream::~LimitingInputStream() {
    +  // If we overshot the limit, back up.
    +  if (limit_ < 0) input_->BackUp(-limit_);
    +}
    +
    +bool LimitingInputStream::Next(const void** data, int* size) {
    +  if (limit_ <= 0) return false;
    +  if (!input_->Next(data, size)) return false;
    +
    +  limit_ -= *size;
    +  if (limit_ < 0) {
    +    // We overshot the limit.  Reduce *size to hide the rest of the buffer.
    +    *size += limit_;
    +  }
    +  return true;
    +}
    +
    +void LimitingInputStream::BackUp(int count) {
    +  if (limit_ < 0) {
    +    input_->BackUp(count - limit_);
    +    limit_ = count;
    +  } else {
    +    input_->BackUp(count);
    +    limit_ += count;
    +  }
    +}
    +
    +bool LimitingInputStream::Skip(int count) {
    +  if (count > limit_) {
    +    if (limit_ < 0) return false;
    +    input_->Skip(limit_);
    +    limit_ = 0;
    +    return false;
    +  } else {
    +    if (!input_->Skip(count)) return false;
    +    limit_ -= count;
    +    return true;
    +  }
    +}
    +
    +int64 LimitingInputStream::ByteCount() const {
    +  if (limit_ < 0) {
    +    return input_->ByteCount() + limit_ - prior_bytes_read_;
    +  } else {
    +    return input_->ByteCount() - prior_bytes_read_;
    +  }
    +}
    +
    +
    +// ===================================================================
    +
    +}  // namespace io
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl.h b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
    similarity index 99%
    rename from toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl.h
    rename to toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
    index 9fedb00576b6..0746fa6afe69 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -344,6 +344,7 @@ class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
      private:
       ZeroCopyInputStream* input_;
       int64 limit_;  // Decreases as we go, becomes negative if we overshoot.
    +  int64 prior_bytes_read_;  // Bytes read on underlying stream at construction
     
       GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
     };
    diff --git a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.cc b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
    similarity index 93%
    rename from toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.cc
    rename to toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
    index a7de4a6d94a4..58aff0e256ad 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -32,11 +32,13 @@
     //  Based on original Protocol Buffers design by
     //  Sanjay Ghemawat, Jeff Dean, and others.
     
    -#include 
    -#include 
    -#include 
    +#include 
     
     #include 
    +#include 
    +
    +#include 
    +#include 
     
     namespace google {
     namespace protobuf {
    @@ -161,15 +163,23 @@ bool StringOutputStream::Next(void** data, int* size) {
         // without a memory allocation this way.
         STLStringResizeUninitialized(target_, target_->capacity());
       } else {
    -    // Size has reached capacity, so double the size.  Also make sure
    -    // that the new size is at least kMinimumSize.
    +    // Size has reached capacity, try to double the size.
    +    if (old_size > std::numeric_limits::max() / 2) {
    +      // Can not double the size otherwise it is going to cause integer
    +      // overflow in the expression below: old_size * 2 ";
    +      GOOGLE_LOG(ERROR) << "Cannot allocate buffer larger than kint32max for "
    +                 << "StringOutputStream.";
    +      return false;
    +    }
    +    // Double the size, also make sure that the new size is at least
    +    // kMinimumSize.
         STLStringResizeUninitialized(
           target_,
           max(old_size * 2,
               kMinimumSize + 0));  // "+ 0" works around GCC4 weirdness.
       }
     
    -  *data = string_as_array(target_) + old_size;
    +  *data = mutable_string_data(target_) + old_size;
       *size = target_->size() - old_size;
       return true;
     }
    diff --git a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.h b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
    similarity index 95%
    rename from toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.h
    rename to toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
    index 153f543ee4b0..e18da72ca12f 100644
    --- a/toolkit/components/protobuf/google/protobuf/io/zero_copy_stream_impl_lite.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -48,6 +48,7 @@
     #include 
     #include 
     #include 
    +#include 
     
     
     namespace google {
    @@ -333,6 +334,19 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea
     
     // ===================================================================
     
    +// Return a pointer to mutable characters underlying the given string.  The
    +// return value is valid until the next time the string is resized.  We
    +// trust the caller to treat the return value as an array of length s->size().
    +inline char* mutable_string_data(string* s) {
    +#ifdef LANG_CXX11
    +  // This should be simpler & faster than string_as_array() because the latter
    +  // is guaranteed to return NULL when *s is empty, so it has to check for that.
    +  return &(*s)[0];
    +#else
    +  return string_as_array(s);
    +#endif
    +}
    +
     }  // namespace io
     }  // namespace protobuf
     
    diff --git a/toolkit/components/protobuf/src/google/protobuf/message.cc b/toolkit/components/protobuf/src/google/protobuf/message.cc
    new file mode 100644
    index 000000000000..1324ed9b173f
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/message.cc
    @@ -0,0 +1,358 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +using internal::WireFormat;
    +using internal::ReflectionOps;
    +
    +Message::~Message() {}
    +
    +void Message::MergeFrom(const Message& from) {
    +  const Descriptor* descriptor = GetDescriptor();
    +  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
    +    << ": Tried to merge from a message with a different type.  "
    +       "to: " << descriptor->full_name() << ", "
    +       "from:" << from.GetDescriptor()->full_name();
    +  ReflectionOps::Merge(from, this);
    +}
    +
    +void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
    +  MergeFrom(*down_cast(&other));
    +}
    +
    +void Message::CopyFrom(const Message& from) {
    +  const Descriptor* descriptor = GetDescriptor();
    +  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
    +    << ": Tried to copy from a message with a different type. "
    +       "to: " << descriptor->full_name() << ", "
    +       "from:" << from.GetDescriptor()->full_name();
    +  ReflectionOps::Copy(from, this);
    +}
    +
    +string Message::GetTypeName() const {
    +  return GetDescriptor()->full_name();
    +}
    +
    +void Message::Clear() {
    +  ReflectionOps::Clear(this);
    +}
    +
    +bool Message::IsInitialized() const {
    +  return ReflectionOps::IsInitialized(*this);
    +}
    +
    +void Message::FindInitializationErrors(vector* errors) const {
    +  return ReflectionOps::FindInitializationErrors(*this, "", errors);
    +}
    +
    +string Message::InitializationErrorString() const {
    +  vector errors;
    +  FindInitializationErrors(&errors);
    +  return Join(errors, ", ");
    +}
    +
    +void Message::CheckInitialized() const {
    +  GOOGLE_CHECK(IsInitialized())
    +    << "Message of type \"" << GetDescriptor()->full_name()
    +    << "\" is missing required fields: " << InitializationErrorString();
    +}
    +
    +void Message::DiscardUnknownFields() {
    +  return ReflectionOps::DiscardUnknownFields(this);
    +}
    +
    +bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
    +  return WireFormat::ParseAndMergePartial(input, this);
    +}
    +
    +bool Message::ParseFromFileDescriptor(int file_descriptor) {
    +  io::FileInputStream input(file_descriptor);
    +  return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
    +}
    +
    +bool Message::ParsePartialFromFileDescriptor(int file_descriptor) {
    +  io::FileInputStream input(file_descriptor);
    +  return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0;
    +}
    +
    +bool Message::ParseFromIstream(istream* input) {
    +  io::IstreamInputStream zero_copy_input(input);
    +  return ParseFromZeroCopyStream(&zero_copy_input) && input->eof();
    +}
    +
    +bool Message::ParsePartialFromIstream(istream* input) {
    +  io::IstreamInputStream zero_copy_input(input);
    +  return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
    +}
    +
    +
    +void Message::SerializeWithCachedSizes(
    +    io::CodedOutputStream* output) const {
    +  WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
    +}
    +
    +int Message::ByteSize() const {
    +  int size = WireFormat::ByteSize(*this);
    +  SetCachedSize(size);
    +  return size;
    +}
    +
    +void Message::SetCachedSize(int /* size */) const {
    +  GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
    +             << "\" implements neither SetCachedSize() nor ByteSize().  "
    +                "Must implement one or the other.";
    +}
    +
    +int Message::SpaceUsed() const {
    +  return GetReflection()->SpaceUsed(*this);
    +}
    +
    +bool Message::SerializeToFileDescriptor(int file_descriptor) const {
    +  io::FileOutputStream output(file_descriptor);
    +  return SerializeToZeroCopyStream(&output);
    +}
    +
    +bool Message::SerializePartialToFileDescriptor(int file_descriptor) const {
    +  io::FileOutputStream output(file_descriptor);
    +  return SerializePartialToZeroCopyStream(&output);
    +}
    +
    +bool Message::SerializeToOstream(ostream* output) const {
    +  {
    +    io::OstreamOutputStream zero_copy_output(output);
    +    if (!SerializeToZeroCopyStream(&zero_copy_output)) return false;
    +  }
    +  return output->good();
    +}
    +
    +bool Message::SerializePartialToOstream(ostream* output) const {
    +  io::OstreamOutputStream zero_copy_output(output);
    +  return SerializePartialToZeroCopyStream(&zero_copy_output);
    +}
    +
    +
    +// =============================================================================
    +// Reflection and associated Template Specializations
    +
    +Reflection::~Reflection() {}
    +
    +#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                             \
    +template<>                                                            \
    +const RepeatedField& Reflection::GetRepeatedField(        \
    +    const Message& message, const FieldDescriptor* field) const {     \
    +  return *static_cast* >(                         \
    +      MutableRawRepeatedField(const_cast(&message),         \
    +                          field, CPPTYPE, CTYPE, NULL));              \
    +}                                                                     \
    +                                                                      \
    +template<>                                                            \
    +RepeatedField* Reflection::MutableRepeatedField(          \
    +    Message* message, const FieldDescriptor* field) const {           \
    +  return static_cast* >(                          \
    +      MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
    +}
    +
    +HANDLE_TYPE(int32,  FieldDescriptor::CPPTYPE_INT32,  -1);
    +HANDLE_TYPE(int64,  FieldDescriptor::CPPTYPE_INT64,  -1);
    +HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
    +HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
    +HANDLE_TYPE(float,  FieldDescriptor::CPPTYPE_FLOAT,  -1);
    +HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
    +HANDLE_TYPE(bool,   FieldDescriptor::CPPTYPE_BOOL,   -1);
    +
    +
    +#undef HANDLE_TYPE
    +
    +void* Reflection::MutableRawRepeatedString(
    +    Message* message, const FieldDescriptor* field, bool is_string) const {
    +  return MutableRawRepeatedField(message, field,
    +      FieldDescriptor::CPPTYPE_STRING, FieldOptions::STRING, NULL);
    +}
    +
    +
    +// =============================================================================
    +// MessageFactory
    +
    +MessageFactory::~MessageFactory() {}
    +
    +namespace {
    +
    +class GeneratedMessageFactory : public MessageFactory {
    + public:
    +  GeneratedMessageFactory();
    +  ~GeneratedMessageFactory();
    +
    +  static GeneratedMessageFactory* singleton();
    +
    +  typedef void RegistrationFunc(const string&);
    +  void RegisterFile(const char* file, RegistrationFunc* registration_func);
    +  void RegisterType(const Descriptor* descriptor, const Message* prototype);
    +
    +  // implements MessageFactory ---------------------------------------
    +  const Message* GetPrototype(const Descriptor* type);
    +
    + private:
    +  // Only written at static init time, so does not require locking.
    +  hash_map, streq> file_map_;
    +
    +  // Initialized lazily, so requires locking.
    +  Mutex mutex_;
    +  hash_map type_map_;
    +};
    +
    +GeneratedMessageFactory* generated_message_factory_ = NULL;
    +GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_);
    +
    +void ShutdownGeneratedMessageFactory() {
    +  delete generated_message_factory_;
    +}
    +
    +void InitGeneratedMessageFactory() {
    +  generated_message_factory_ = new GeneratedMessageFactory;
    +  internal::OnShutdown(&ShutdownGeneratedMessageFactory);
    +}
    +
    +GeneratedMessageFactory::GeneratedMessageFactory() {}
    +GeneratedMessageFactory::~GeneratedMessageFactory() {}
    +
    +GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
    +  ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_,
    +                 &InitGeneratedMessageFactory);
    +  return generated_message_factory_;
    +}
    +
    +void GeneratedMessageFactory::RegisterFile(
    +    const char* file, RegistrationFunc* registration_func) {
    +  if (!InsertIfNotPresent(&file_map_, file, registration_func)) {
    +    GOOGLE_LOG(FATAL) << "File is already registered: " << file;
    +  }
    +}
    +
    +void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
    +                                           const Message* prototype) {
    +  GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
    +    << "Tried to register a non-generated type with the generated "
    +       "type registry.";
    +
    +  // This should only be called as a result of calling a file registration
    +  // function during GetPrototype(), in which case we already have locked
    +  // the mutex.
    +  mutex_.AssertHeld();
    +  if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
    +    GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
    +  }
    +}
    +
    +
    +const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
    +  {
    +    ReaderMutexLock lock(&mutex_);
    +    const Message* result = FindPtrOrNull(type_map_, type);
    +    if (result != NULL) return result;
    +  }
    +
    +  // If the type is not in the generated pool, then we can't possibly handle
    +  // it.
    +  if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;
    +
    +  // Apparently the file hasn't been registered yet.  Let's do that now.
    +  RegistrationFunc* registration_func =
    +      FindPtrOrNull(file_map_, type->file()->name().c_str());
    +  if (registration_func == NULL) {
    +    GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
    +                   "registered: " << type->file()->name();
    +    return NULL;
    +  }
    +
    +  WriterMutexLock lock(&mutex_);
    +
    +  // Check if another thread preempted us.
    +  const Message* result = FindPtrOrNull(type_map_, type);
    +  if (result == NULL) {
    +    // Nope.  OK, register everything.
    +    registration_func(type->file()->name());
    +    // Should be here now.
    +    result = FindPtrOrNull(type_map_, type);
    +  }
    +
    +  if (result == NULL) {
    +    GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't "
    +                << "registered: " << type->full_name();
    +  }
    +
    +  return result;
    +}
    +
    +}  // namespace
    +
    +MessageFactory* MessageFactory::generated_factory() {
    +  return GeneratedMessageFactory::singleton();
    +}
    +
    +void MessageFactory::InternalRegisterGeneratedFile(
    +    const char* filename, void (*register_messages)(const string&)) {
    +  GeneratedMessageFactory::singleton()->RegisterFile(filename,
    +                                                     register_messages);
    +}
    +
    +void MessageFactory::InternalRegisterGeneratedMessage(
    +    const Descriptor* descriptor, const Message* prototype) {
    +  GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
    +}
    +
    +
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/message.h b/toolkit/components/protobuf/src/google/protobuf/message.h
    new file mode 100644
    index 000000000000..9593560531f8
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/message.h
    @@ -0,0 +1,866 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Defines Message, the abstract interface implemented by non-lite
    +// protocol message objects.  Although it's possible to implement this
    +// interface manually, most users will use the protocol compiler to
    +// generate implementations.
    +//
    +// Example usage:
    +//
    +// Say you have a message defined as:
    +//
    +//   message Foo {
    +//     optional string text = 1;
    +//     repeated int32 numbers = 2;
    +//   }
    +//
    +// Then, if you used the protocol compiler to generate a class from the above
    +// definition, you could use it like so:
    +//
    +//   string data;  // Will store a serialized version of the message.
    +//
    +//   {
    +//     // Create a message and serialize it.
    +//     Foo foo;
    +//     foo.set_text("Hello World!");
    +//     foo.add_numbers(1);
    +//     foo.add_numbers(5);
    +//     foo.add_numbers(42);
    +//
    +//     foo.SerializeToString(&data);
    +//   }
    +//
    +//   {
    +//     // Parse the serialized message and check that it contains the
    +//     // correct data.
    +//     Foo foo;
    +//     foo.ParseFromString(data);
    +//
    +//     assert(foo.text() == "Hello World!");
    +//     assert(foo.numbers_size() == 3);
    +//     assert(foo.numbers(0) == 1);
    +//     assert(foo.numbers(1) == 5);
    +//     assert(foo.numbers(2) == 42);
    +//   }
    +//
    +//   {
    +//     // Same as the last block, but do it dynamically via the Message
    +//     // reflection interface.
    +//     Message* foo = new Foo;
    +//     const Descriptor* descriptor = foo->GetDescriptor();
    +//
    +//     // Get the descriptors for the fields we're interested in and verify
    +//     // their types.
    +//     const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
    +//     assert(text_field != NULL);
    +//     assert(text_field->type() == FieldDescriptor::TYPE_STRING);
    +//     assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
    +//     const FieldDescriptor* numbers_field = descriptor->
    +//                                            FindFieldByName("numbers");
    +//     assert(numbers_field != NULL);
    +//     assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
    +//     assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
    +//
    +//     // Parse the message.
    +//     foo->ParseFromString(data);
    +//
    +//     // Use the reflection interface to examine the contents.
    +//     const Reflection* reflection = foo->GetReflection();
    +//     assert(reflection->GetString(foo, text_field) == "Hello World!");
    +//     assert(reflection->FieldSize(foo, numbers_field) == 3);
    +//     assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1);
    +//     assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5);
    +//     assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42);
    +//
    +//     delete foo;
    +//   }
    +
    +#ifndef GOOGLE_PROTOBUF_MESSAGE_H__
    +#define GOOGLE_PROTOBUF_MESSAGE_H__
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +
    +
    +#define GOOGLE_PROTOBUF_HAS_ONEOF
    +
    +namespace google {
    +namespace protobuf {
    +
    +// Defined in this file.
    +class Message;
    +class Reflection;
    +class MessageFactory;
    +
    +// Defined in other files.
    +class UnknownFieldSet;         // unknown_field_set.h
    +namespace io {
    +  class ZeroCopyInputStream;   // zero_copy_stream.h
    +  class ZeroCopyOutputStream;  // zero_copy_stream.h
    +  class CodedInputStream;      // coded_stream.h
    +  class CodedOutputStream;     // coded_stream.h
    +}
    +
    +
    +template
    +class RepeatedField;     // repeated_field.h
    +
    +template
    +class RepeatedPtrField;  // repeated_field.h
    +
    +// A container to hold message metadata.
    +struct Metadata {
    +  const Descriptor* descriptor;
    +  const Reflection* reflection;
    +};
    +
    +// Abstract interface for protocol messages.
    +//
    +// See also MessageLite, which contains most every-day operations.  Message
    +// adds descriptors and reflection on top of that.
    +//
    +// The methods of this class that are virtual but not pure-virtual have
    +// default implementations based on reflection.  Message classes which are
    +// optimized for speed will want to override these with faster implementations,
    +// but classes optimized for code size may be happy with keeping them.  See
    +// the optimize_for option in descriptor.proto.
    +class LIBPROTOBUF_EXPORT Message : public MessageLite {
    + public:
    +  inline Message() {}
    +  virtual ~Message();
    +
    +  // Basic Operations ------------------------------------------------
    +
    +  // Construct a new instance of the same type.  Ownership is passed to the
    +  // caller.  (This is also defined in MessageLite, but is defined again here
    +  // for return-type covariance.)
    +  virtual Message* New() const = 0;
    +
    +  // Make this message into a copy of the given message.  The given message
    +  // must have the same descriptor, but need not necessarily be the same class.
    +  // By default this is just implemented as "Clear(); MergeFrom(from);".
    +  virtual void CopyFrom(const Message& from);
    +
    +  // Merge the fields from the given message into this message.  Singular
    +  // fields will be overwritten, if specified in from, except for embedded
    +  // messages which will be merged.  Repeated fields will be concatenated.
    +  // The given message must be of the same type as this message (i.e. the
    +  // exact same class).
    +  virtual void MergeFrom(const Message& from);
    +
    +  // Verifies that IsInitialized() returns true.  GOOGLE_CHECK-fails otherwise, with
    +  // a nice error message.
    +  void CheckInitialized() const;
    +
    +  // Slowly build a list of all required fields that are not set.
    +  // This is much, much slower than IsInitialized() as it is implemented
    +  // purely via reflection.  Generally, you should not call this unless you
    +  // have already determined that an error exists by calling IsInitialized().
    +  void FindInitializationErrors(vector* errors) const;
    +
    +  // Like FindInitializationErrors, but joins all the strings, delimited by
    +  // commas, and returns them.
    +  string InitializationErrorString() const;
    +
    +  // Clears all unknown fields from this message and all embedded messages.
    +  // Normally, if unknown tag numbers are encountered when parsing a message,
    +  // the tag and value are stored in the message's UnknownFieldSet and
    +  // then written back out when the message is serialized.  This allows servers
    +  // which simply route messages to other servers to pass through messages
    +  // that have new field definitions which they don't yet know about.  However,
    +  // this behavior can have security implications.  To avoid it, call this
    +  // method after parsing.
    +  //
    +  // See Reflection::GetUnknownFields() for more on unknown fields.
    +  virtual void DiscardUnknownFields();
    +
    +  // Computes (an estimate of) the total number of bytes currently used for
    +  // storing the message in memory.  The default implementation calls the
    +  // Reflection object's SpaceUsed() method.
    +  virtual int SpaceUsed() const;
    +
    +  // Debugging & Testing----------------------------------------------
    +
    +  // Generates a human readable form of this message, useful for debugging
    +  // and other purposes.
    +  string DebugString() const;
    +  // Like DebugString(), but with less whitespace.
    +  string ShortDebugString() const;
    +  // Like DebugString(), but do not escape UTF-8 byte sequences.
    +  string Utf8DebugString() const;
    +  // Convenience function useful in GDB.  Prints DebugString() to stdout.
    +  void PrintDebugString() const;
    +
    +  // Heavy I/O -------------------------------------------------------
    +  // Additional parsing and serialization methods not implemented by
    +  // MessageLite because they are not supported by the lite library.
    +
    +  // Parse a protocol buffer from a file descriptor.  If successful, the entire
    +  // input will be consumed.
    +  bool ParseFromFileDescriptor(int file_descriptor);
    +  // Like ParseFromFileDescriptor(), but accepts messages that are missing
    +  // required fields.
    +  bool ParsePartialFromFileDescriptor(int file_descriptor);
    +  // Parse a protocol buffer from a C++ istream.  If successful, the entire
    +  // input will be consumed.
    +  bool ParseFromIstream(istream* input);
    +  // Like ParseFromIstream(), but accepts messages that are missing
    +  // required fields.
    +  bool ParsePartialFromIstream(istream* input);
    +
    +  // Serialize the message and write it to the given file descriptor.  All
    +  // required fields must be set.
    +  bool SerializeToFileDescriptor(int file_descriptor) const;
    +  // Like SerializeToFileDescriptor(), but allows missing required fields.
    +  bool SerializePartialToFileDescriptor(int file_descriptor) const;
    +  // Serialize the message and write it to the given C++ ostream.  All
    +  // required fields must be set.
    +  bool SerializeToOstream(ostream* output) const;
    +  // Like SerializeToOstream(), but allows missing required fields.
    +  bool SerializePartialToOstream(ostream* output) const;
    +
    +
    +  // Reflection-based methods ----------------------------------------
    +  // These methods are pure-virtual in MessageLite, but Message provides
    +  // reflection-based default implementations.
    +
    +  virtual string GetTypeName() const;
    +  virtual void Clear();
    +  virtual bool IsInitialized() const;
    +  virtual void CheckTypeAndMergeFrom(const MessageLite& other);
    +  virtual bool MergePartialFromCodedStream(io::CodedInputStream* input);
    +  virtual int ByteSize() const;
    +  virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const;
    +
    + private:
    +  // This is called only by the default implementation of ByteSize(), to
    +  // update the cached size.  If you override ByteSize(), you do not need
    +  // to override this.  If you do not override ByteSize(), you MUST override
    +  // this; the default implementation will crash.
    +  //
    +  // The method is private because subclasses should never call it; only
    +  // override it.  Yes, C++ lets you do that.  Crazy, huh?
    +  virtual void SetCachedSize(int size) const;
    +
    + public:
    +
    +  // Introspection ---------------------------------------------------
    +
    +  // Typedef for backwards-compatibility.
    +  typedef google::protobuf::Reflection Reflection;
    +
    +  // Get a Descriptor for this message's type.  This describes what
    +  // fields the message contains, the types of those fields, etc.
    +  const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; }
    +
    +  // Get the Reflection interface for this Message, which can be used to
    +  // read and modify the fields of the Message dynamically (in other words,
    +  // without knowing the message type at compile time).  This object remains
    +  // property of the Message.
    +  //
    +  // This method remains virtual in case a subclass does not implement
    +  // reflection and wants to override the default behavior.
    +  virtual const Reflection* GetReflection() const {
    +    return GetMetadata().reflection;
    +  }
    +
    + protected:
    +  // Get a struct containing the metadata for the Message. Most subclasses only
    +  // need to implement this method, rather than the GetDescriptor() and
    +  // GetReflection() wrappers.
    +  virtual Metadata GetMetadata() const  = 0;
    +
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message);
    +};
    +
    +// This interface contains methods that can be used to dynamically access
    +// and modify the fields of a protocol message.  Their semantics are
    +// similar to the accessors the protocol compiler generates.
    +//
    +// To get the Reflection for a given Message, call Message::GetReflection().
    +//
    +// This interface is separate from Message only for efficiency reasons;
    +// the vast majority of implementations of Message will share the same
    +// implementation of Reflection (GeneratedMessageReflection,
    +// defined in generated_message.h), and all Messages of a particular class
    +// should share the same Reflection object (though you should not rely on
    +// the latter fact).
    +//
    +// There are several ways that these methods can be used incorrectly.  For
    +// example, any of the following conditions will lead to undefined
    +// results (probably assertion failures):
    +// - The FieldDescriptor is not a field of this message type.
    +// - The method called is not appropriate for the field's type.  For
    +//   each field type in FieldDescriptor::TYPE_*, there is only one
    +//   Get*() method, one Set*() method, and one Add*() method that is
    +//   valid for that type.  It should be obvious which (except maybe
    +//   for TYPE_BYTES, which are represented using strings in C++).
    +// - A Get*() or Set*() method for singular fields is called on a repeated
    +//   field.
    +// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated
    +//   field.
    +// - The Message object passed to any method is not of the right type for
    +//   this Reflection object (i.e. message.GetReflection() != reflection).
    +//
    +// You might wonder why there is not any abstract representation for a field
    +// of arbitrary type.  E.g., why isn't there just a "GetField()" method that
    +// returns "const Field&", where "Field" is some class with accessors like
    +// "GetInt32Value()".  The problem is that someone would have to deal with
    +// allocating these Field objects.  For generated message classes, having to
    +// allocate space for an additional object to wrap every field would at least
    +// double the message's memory footprint, probably worse.  Allocating the
    +// objects on-demand, on the other hand, would be expensive and prone to
    +// memory leaks.  So, instead we ended up with this flat interface.
    +//
    +// TODO(kenton):  Create a utility class which callers can use to read and
    +//   write fields from a Reflection without paying attention to the type.
    +class LIBPROTOBUF_EXPORT Reflection {
    + public:
    +  inline Reflection() {}
    +  virtual ~Reflection();
    +
    +  // Get the UnknownFieldSet for the message.  This contains fields which
    +  // were seen when the Message was parsed but were not recognized according
    +  // to the Message's definition.
    +  virtual const UnknownFieldSet& GetUnknownFields(
    +      const Message& message) const = 0;
    +  // Get a mutable pointer to the UnknownFieldSet for the message.  This
    +  // contains fields which were seen when the Message was parsed but were not
    +  // recognized according to the Message's definition.
    +  virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0;
    +
    +  // Estimate the amount of memory used by the message object.
    +  virtual int SpaceUsed(const Message& message) const = 0;
    +
    +  // Check if the given non-repeated field is set.
    +  virtual bool HasField(const Message& message,
    +                        const FieldDescriptor* field) const = 0;
    +
    +  // Get the number of elements of a repeated field.
    +  virtual int FieldSize(const Message& message,
    +                        const FieldDescriptor* field) const = 0;
    +
    +  // Clear the value of a field, so that HasField() returns false or
    +  // FieldSize() returns zero.
    +  virtual void ClearField(Message* message,
    +                          const FieldDescriptor* field) const = 0;
    +
    +  // Check if the oneof is set. Returns ture if any field in oneof
    +  // is set, false otherwise.
    +  // TODO(jieluo) - make it pure virtual after updating all
    +  // the subclasses.
    +  virtual bool HasOneof(const Message& message,
    +                        const OneofDescriptor* oneof_descriptor) const {
    +    return false;
    +  }
    +
    +  virtual void ClearOneof(Message* message,
    +                          const OneofDescriptor* oneof_descriptor) const {}
    +
    +  // Returns the field descriptor if the oneof is set. NULL otherwise.
    +  // TODO(jieluo) - make it pure virtual.
    +  virtual const FieldDescriptor* GetOneofFieldDescriptor(
    +      const Message& message,
    +      const OneofDescriptor* oneof_descriptor) const {
    +    return NULL;
    +  }
    +
    +  // Removes the last element of a repeated field.
    +  // We don't provide a way to remove any element other than the last
    +  // because it invites inefficient use, such as O(n^2) filtering loops
    +  // that should have been O(n).  If you want to remove an element other
    +  // than the last, the best way to do it is to re-arrange the elements
    +  // (using Swap()) so that the one you want removed is at the end, then
    +  // call RemoveLast().
    +  virtual void RemoveLast(Message* message,
    +                          const FieldDescriptor* field) const = 0;
    +  // Removes the last element of a repeated message field, and returns the
    +  // pointer to the caller.  Caller takes ownership of the returned pointer.
    +  virtual Message* ReleaseLast(Message* message,
    +                               const FieldDescriptor* field) const = 0;
    +
    +  // Swap the complete contents of two messages.
    +  virtual void Swap(Message* message1, Message* message2) const = 0;
    +
    +  // Swap fields listed in fields vector of two messages.
    +  virtual void SwapFields(Message* message1,
    +                          Message* message2,
    +                          const vector& fields)
    +      const = 0;
    +
    +  // Swap two elements of a repeated field.
    +  virtual void SwapElements(Message* message,
    +                            const FieldDescriptor* field,
    +                            int index1,
    +                            int index2) const = 0;
    +
    +  // List all fields of the message which are currently set.  This includes
    +  // extensions.  Singular fields will only be listed if HasField(field) would
    +  // return true and repeated fields will only be listed if FieldSize(field)
    +  // would return non-zero.  Fields (both normal fields and extension fields)
    +  // will be listed ordered by field number.
    +  virtual void ListFields(const Message& message,
    +                          vector* output) const = 0;
    +
    +  // Singular field getters ------------------------------------------
    +  // These get the value of a non-repeated field.  They return the default
    +  // value for fields that aren't set.
    +
    +  virtual int32  GetInt32 (const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual int64  GetInt64 (const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual uint32 GetUInt32(const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual uint64 GetUInt64(const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual float  GetFloat (const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual double GetDouble(const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual bool   GetBool  (const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual string GetString(const Message& message,
    +                           const FieldDescriptor* field) const = 0;
    +  virtual const EnumValueDescriptor* GetEnum(
    +      const Message& message, const FieldDescriptor* field) const = 0;
    +  // See MutableMessage() for the meaning of the "factory" parameter.
    +  virtual const Message& GetMessage(const Message& message,
    +                                    const FieldDescriptor* field,
    +                                    MessageFactory* factory = NULL) const = 0;
    +
    +  // Get a string value without copying, if possible.
    +  //
    +  // GetString() necessarily returns a copy of the string.  This can be
    +  // inefficient when the string is already stored in a string object in the
    +  // underlying message.  GetStringReference() will return a reference to the
    +  // underlying string in this case.  Otherwise, it will copy the string into
    +  // *scratch and return that.
    +  //
    +  // Note:  It is perfectly reasonable and useful to write code like:
    +  //     str = reflection->GetStringReference(field, &str);
    +  //   This line would ensure that only one copy of the string is made
    +  //   regardless of the field's underlying representation.  When initializing
    +  //   a newly-constructed string, though, it's just as fast and more readable
    +  //   to use code like:
    +  //     string str = reflection->GetString(field);
    +  virtual const string& GetStringReference(const Message& message,
    +                                           const FieldDescriptor* field,
    +                                           string* scratch) const = 0;
    +
    +
    +  // Singular field mutators -----------------------------------------
    +  // These mutate the value of a non-repeated field.
    +
    +  virtual void SetInt32 (Message* message,
    +                         const FieldDescriptor* field, int32  value) const = 0;
    +  virtual void SetInt64 (Message* message,
    +                         const FieldDescriptor* field, int64  value) const = 0;
    +  virtual void SetUInt32(Message* message,
    +                         const FieldDescriptor* field, uint32 value) const = 0;
    +  virtual void SetUInt64(Message* message,
    +                         const FieldDescriptor* field, uint64 value) const = 0;
    +  virtual void SetFloat (Message* message,
    +                         const FieldDescriptor* field, float  value) const = 0;
    +  virtual void SetDouble(Message* message,
    +                         const FieldDescriptor* field, double value) const = 0;
    +  virtual void SetBool  (Message* message,
    +                         const FieldDescriptor* field, bool   value) const = 0;
    +  virtual void SetString(Message* message,
    +                         const FieldDescriptor* field,
    +                         const string& value) const = 0;
    +  virtual void SetEnum  (Message* message,
    +                         const FieldDescriptor* field,
    +                         const EnumValueDescriptor* value) const = 0;
    +  // Get a mutable pointer to a field with a message type.  If a MessageFactory
    +  // is provided, it will be used to construct instances of the sub-message;
    +  // otherwise, the default factory is used.  If the field is an extension that
    +  // does not live in the same pool as the containing message's descriptor (e.g.
    +  // it lives in an overlay pool), then a MessageFactory must be provided.
    +  // If you have no idea what that meant, then you probably don't need to worry
    +  // about it (don't provide a MessageFactory).  WARNING:  If the
    +  // FieldDescriptor is for a compiled-in extension, then
    +  // factory->GetPrototype(field->message_type() MUST return an instance of the
    +  // compiled-in class for this type, NOT DynamicMessage.
    +  virtual Message* MutableMessage(Message* message,
    +                                  const FieldDescriptor* field,
    +                                  MessageFactory* factory = NULL) const = 0;
    +  // Replaces the message specified by 'field' with the already-allocated object
    +  // sub_message, passing ownership to the message.  If the field contained a
    +  // message, that message is deleted.  If sub_message is NULL, the field is
    +  // cleared.
    +  virtual void SetAllocatedMessage(Message* message,
    +                                   Message* sub_message,
    +                                   const FieldDescriptor* field) const = 0;
    +  // Releases the message specified by 'field' and returns the pointer,
    +  // ReleaseMessage() will return the message the message object if it exists.
    +  // Otherwise, it may or may not return NULL.  In any case, if the return value
    +  // is non-NULL, the caller takes ownership of the pointer.
    +  // If the field existed (HasField() is true), then the returned pointer will
    +  // be the same as the pointer returned by MutableMessage().
    +  // This function has the same effect as ClearField().
    +  virtual Message* ReleaseMessage(Message* message,
    +                                  const FieldDescriptor* field,
    +                                  MessageFactory* factory = NULL) const = 0;
    +
    +
    +  // Repeated field getters ------------------------------------------
    +  // These get the value of one element of a repeated field.
    +
    +  virtual int32  GetRepeatedInt32 (const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual int64  GetRepeatedInt64 (const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual uint32 GetRepeatedUInt32(const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual uint64 GetRepeatedUInt64(const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual float  GetRepeatedFloat (const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual double GetRepeatedDouble(const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual bool   GetRepeatedBool  (const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual string GetRepeatedString(const Message& message,
    +                                   const FieldDescriptor* field,
    +                                   int index) const = 0;
    +  virtual const EnumValueDescriptor* GetRepeatedEnum(
    +      const Message& message,
    +      const FieldDescriptor* field, int index) const = 0;
    +  virtual const Message& GetRepeatedMessage(
    +      const Message& message,
    +      const FieldDescriptor* field, int index) const = 0;
    +
    +  // See GetStringReference(), above.
    +  virtual const string& GetRepeatedStringReference(
    +      const Message& message, const FieldDescriptor* field,
    +      int index, string* scratch) const = 0;
    +
    +
    +  // Repeated field mutators -----------------------------------------
    +  // These mutate the value of one element of a repeated field.
    +
    +  virtual void SetRepeatedInt32 (Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, int32  value) const = 0;
    +  virtual void SetRepeatedInt64 (Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, int64  value) const = 0;
    +  virtual void SetRepeatedUInt32(Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, uint32 value) const = 0;
    +  virtual void SetRepeatedUInt64(Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, uint64 value) const = 0;
    +  virtual void SetRepeatedFloat (Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, float  value) const = 0;
    +  virtual void SetRepeatedDouble(Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, double value) const = 0;
    +  virtual void SetRepeatedBool  (Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, bool   value) const = 0;
    +  virtual void SetRepeatedString(Message* message,
    +                                 const FieldDescriptor* field,
    +                                 int index, const string& value) const = 0;
    +  virtual void SetRepeatedEnum(Message* message,
    +                               const FieldDescriptor* field, int index,
    +                               const EnumValueDescriptor* value) const = 0;
    +  // Get a mutable pointer to an element of a repeated field with a message
    +  // type.
    +  virtual Message* MutableRepeatedMessage(
    +      Message* message, const FieldDescriptor* field, int index) const = 0;
    +
    +
    +  // Repeated field adders -------------------------------------------
    +  // These add an element to a repeated field.
    +
    +  virtual void AddInt32 (Message* message,
    +                         const FieldDescriptor* field, int32  value) const = 0;
    +  virtual void AddInt64 (Message* message,
    +                         const FieldDescriptor* field, int64  value) const = 0;
    +  virtual void AddUInt32(Message* message,
    +                         const FieldDescriptor* field, uint32 value) const = 0;
    +  virtual void AddUInt64(Message* message,
    +                         const FieldDescriptor* field, uint64 value) const = 0;
    +  virtual void AddFloat (Message* message,
    +                         const FieldDescriptor* field, float  value) const = 0;
    +  virtual void AddDouble(Message* message,
    +                         const FieldDescriptor* field, double value) const = 0;
    +  virtual void AddBool  (Message* message,
    +                         const FieldDescriptor* field, bool   value) const = 0;
    +  virtual void AddString(Message* message,
    +                         const FieldDescriptor* field,
    +                         const string& value) const = 0;
    +  virtual void AddEnum  (Message* message,
    +                         const FieldDescriptor* field,
    +                         const EnumValueDescriptor* value) const = 0;
    +  // See MutableMessage() for comments on the "factory" parameter.
    +  virtual Message* AddMessage(Message* message,
    +                              const FieldDescriptor* field,
    +                              MessageFactory* factory = NULL) const = 0;
    +
    +
    +  // Repeated field accessors  -------------------------------------------------
    +  // The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular
    +  // access to the data in a RepeatedField.  The methods below provide aggregate
    +  // access by exposing the RepeatedField object itself with the Message.
    +  // Applying these templates to inappropriate types will lead to an undefined
    +  // reference at link time (e.g. GetRepeatedField<***double>), or possibly a
    +  // template matching error at compile time (e.g. GetRepeatedPtrField).
    +  //
    +  // Usage example: my_doubs = refl->GetRepeatedField(msg, fd);
    +
    +  // for T = Cord and all protobuf scalar types except enums.
    +  template
    +  const RepeatedField& GetRepeatedField(
    +      const Message&, const FieldDescriptor*) const;
    +
    +  // for T = Cord and all protobuf scalar types except enums.
    +  template
    +  RepeatedField* MutableRepeatedField(
    +      Message*, const FieldDescriptor*) const;
    +
    +  // for T = string, google::protobuf::internal::StringPieceField
    +  //         google::protobuf::Message & descendants.
    +  template
    +  const RepeatedPtrField& GetRepeatedPtrField(
    +      const Message&, const FieldDescriptor*) const;
    +
    +  // for T = string, google::protobuf::internal::StringPieceField
    +  //         google::protobuf::Message & descendants.
    +  template
    +  RepeatedPtrField* MutableRepeatedPtrField(
    +      Message*, const FieldDescriptor*) const;
    +
    +  // Extensions ----------------------------------------------------------------
    +
    +  // Try to find an extension of this message type by fully-qualified field
    +  // name.  Returns NULL if no extension is known for this name or number.
    +  virtual const FieldDescriptor* FindKnownExtensionByName(
    +      const string& name) const = 0;
    +
    +  // Try to find an extension of this message type by field number.
    +  // Returns NULL if no extension is known for this name or number.
    +  virtual const FieldDescriptor* FindKnownExtensionByNumber(
    +      int number) const = 0;
    +
    +  // ---------------------------------------------------------------------------
    +
    + protected:
    +  // Obtain a pointer to a Repeated Field Structure and do some type checking:
    +  //   on field->cpp_type(),
    +  //   on field->field_option().ctype() (if ctype >= 0)
    +  //   of field->message_type() (if message_type != NULL).
    +  // We use 1 routine rather than 4 (const vs mutable) x (scalar vs pointer).
    +  virtual void* MutableRawRepeatedField(
    +      Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
    +      int ctype, const Descriptor* message_type) const = 0;
    +
    + private:
    +  // Special version for specialized implementations of string.  We can't call
    +  // MutableRawRepeatedField directly here because we don't have access to
    +  // FieldOptions::* which are defined in descriptor.pb.h.  Including that
    +  // file here is not possible because it would cause a circular include cycle.
    +  void* MutableRawRepeatedString(
    +      Message* message, const FieldDescriptor* field, bool is_string) const;
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
    +};
    +
    +// Abstract interface for a factory for message objects.
    +class LIBPROTOBUF_EXPORT MessageFactory {
    + public:
    +  inline MessageFactory() {}
    +  virtual ~MessageFactory();
    +
    +  // Given a Descriptor, gets or constructs the default (prototype) Message
    +  // of that type.  You can then call that message's New() method to construct
    +  // a mutable message of that type.
    +  //
    +  // Calling this method twice with the same Descriptor returns the same
    +  // object.  The returned object remains property of the factory.  Also, any
    +  // objects created by calling the prototype's New() method share some data
    +  // with the prototype, so these must be destroyed before the MessageFactory
    +  // is destroyed.
    +  //
    +  // The given descriptor must outlive the returned message, and hence must
    +  // outlive the MessageFactory.
    +  //
    +  // Some implementations do not support all types.  GetPrototype() will
    +  // return NULL if the descriptor passed in is not supported.
    +  //
    +  // This method may or may not be thread-safe depending on the implementation.
    +  // Each implementation should document its own degree thread-safety.
    +  virtual const Message* GetPrototype(const Descriptor* type) = 0;
    +
    +  // Gets a MessageFactory which supports all generated, compiled-in messages.
    +  // In other words, for any compiled-in type FooMessage, the following is true:
    +  //   MessageFactory::generated_factory()->GetPrototype(
    +  //     FooMessage::descriptor()) == FooMessage::default_instance()
    +  // This factory supports all types which are found in
    +  // DescriptorPool::generated_pool().  If given a descriptor from any other
    +  // pool, GetPrototype() will return NULL.  (You can also check if a
    +  // descriptor is for a generated message by checking if
    +  // descriptor->file()->pool() == DescriptorPool::generated_pool().)
    +  //
    +  // This factory is 100% thread-safe; calling GetPrototype() does not modify
    +  // any shared data.
    +  //
    +  // This factory is a singleton.  The caller must not delete the object.
    +  static MessageFactory* generated_factory();
    +
    +  // For internal use only:  Registers a .proto file at static initialization
    +  // time, to be placed in generated_factory.  The first time GetPrototype()
    +  // is called with a descriptor from this file, |register_messages| will be
    +  // called, with the file name as the parameter.  It must call
    +  // InternalRegisterGeneratedMessage() (below) to register each message type
    +  // in the file.  This strange mechanism is necessary because descriptors are
    +  // built lazily, so we can't register types by their descriptor until we
    +  // know that the descriptor exists.  |filename| must be a permanent string.
    +  static void InternalRegisterGeneratedFile(
    +      const char* filename, void (*register_messages)(const string&));
    +
    +  // For internal use only:  Registers a message type.  Called only by the
    +  // functions which are registered with InternalRegisterGeneratedFile(),
    +  // above.
    +  static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
    +                                               const Message* prototype);
    +
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
    +};
    +
    +#define DECLARE_GET_REPEATED_FIELD(TYPE)                         \
    +template<>                                                       \
    +LIBPROTOBUF_EXPORT                                               \
    +const RepeatedField& Reflection::GetRepeatedField(   \
    +    const Message& message, const FieldDescriptor* field) const; \
    +                                                                 \
    +template<>                                                       \
    +RepeatedField* Reflection::MutableRepeatedField(     \
    +    Message* message, const FieldDescriptor* field) const;
    +
    +DECLARE_GET_REPEATED_FIELD(int32)
    +DECLARE_GET_REPEATED_FIELD(int64)
    +DECLARE_GET_REPEATED_FIELD(uint32)
    +DECLARE_GET_REPEATED_FIELD(uint64)
    +DECLARE_GET_REPEATED_FIELD(float)
    +DECLARE_GET_REPEATED_FIELD(double)
    +DECLARE_GET_REPEATED_FIELD(bool)
    +
    +#undef DECLARE_GET_REPEATED_FIELD
    +
    +// =============================================================================
    +// Implementation details for {Get,Mutable}RawRepeatedPtrField.  We provide
    +// specializations for ,  and  and handle
    +// everything else with the default template which will match any type having
    +// a method with signature "static const google::protobuf::Descriptor* descriptor()".
    +// Such a type presumably is a descendant of google::protobuf::Message.
    +
    +template<>
    +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField(
    +    const Message& message, const FieldDescriptor* field) const {
    +  return *static_cast* >(
    +      MutableRawRepeatedString(const_cast(&message), field, true));
    +}
    +
    +template<>
    +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField(
    +    Message* message, const FieldDescriptor* field) const {
    +  return static_cast* >(
    +      MutableRawRepeatedString(message, field, true));
    +}
    +
    +
    +// -----
    +
    +template<>
    +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField(
    +    const Message& message, const FieldDescriptor* field) const {
    +  return *static_cast* >(
    +      MutableRawRepeatedField(const_cast(&message), field,
    +          FieldDescriptor::CPPTYPE_MESSAGE, -1,
    +          NULL));
    +}
    +
    +template<>
    +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField(
    +    Message* message, const FieldDescriptor* field) const {
    +  return static_cast* >(
    +      MutableRawRepeatedField(message, field,
    +          FieldDescriptor::CPPTYPE_MESSAGE, -1,
    +          NULL));
    +}
    +
    +template
    +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField(
    +    const Message& message, const FieldDescriptor* field) const {
    +  return *static_cast* >(
    +      MutableRawRepeatedField(const_cast(&message), field,
    +          FieldDescriptor::CPPTYPE_MESSAGE, -1,
    +          PB::default_instance().GetDescriptor()));
    +}
    +
    +template
    +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField(
    +    Message* message, const FieldDescriptor* field) const {
    +  return static_cast* >(
    +      MutableRawRepeatedField(message, field,
    +          FieldDescriptor::CPPTYPE_MESSAGE, -1,
    +          PB::default_instance().GetDescriptor()));
    +}
    +
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_MESSAGE_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/message_lite.cc b/toolkit/components/protobuf/src/google/protobuf/message_lite.cc
    similarity index 98%
    rename from toolkit/components/protobuf/google/protobuf/message_lite.cc
    rename to toolkit/components/protobuf/src/google/protobuf/message_lite.cc
    index e2e7b407afe1..14cdc91fddeb 100644
    --- a/toolkit/components/protobuf/google/protobuf/message_lite.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/message_lite.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -38,7 +38,7 @@
     #include 
     #include 
     #include 
    -#include 
    +#include 
     
     namespace google {
     namespace protobuf {
    @@ -278,7 +278,8 @@ bool MessageLite::AppendPartialToString(string* output) const {
       int old_size = output->size();
       int byte_size = ByteSize();
       STLStringResizeUninitialized(output, old_size + byte_size);
    -  uint8* start = reinterpret_cast(string_as_array(output) + old_size);
    +  uint8* start =
    +      reinterpret_cast(io::mutable_string_data(output) + old_size);
       uint8* end = SerializeWithCachedSizesToArray(start);
       if (end - start != byte_size) {
         ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
    diff --git a/toolkit/components/protobuf/google/protobuf/message_lite.h b/toolkit/components/protobuf/src/google/protobuf/message_lite.h
    similarity index 97%
    rename from toolkit/components/protobuf/google/protobuf/message_lite.h
    rename to toolkit/components/protobuf/src/google/protobuf/message_lite.h
    index ebf4ba3c88af..027cabf91987 100644
    --- a/toolkit/components/protobuf/google/protobuf/message_lite.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/message_lite.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -40,11 +40,17 @@
     #define GOOGLE_PROTOBUF_MESSAGE_LITE_H__
     
     #include 
    -#include 
     
     namespace google {
     namespace protobuf {
     
    +namespace io {
    +  class CodedInputStream;
    +  class CodedOutputStream;
    +  class ZeroCopyInputStream;
    +  class ZeroCopyOutputStream;
    +}
    +
     // Interface to light weight protocol messages.
     //
     // This interface is implemented by all protocol message objects.  Non-lite
    @@ -103,7 +109,8 @@ class LIBPROTOBUF_EXPORT MessageLite {
     
       // Parsing ---------------------------------------------------------
       // Methods for parsing in protocol buffer format.  Most of these are
    -  // just simple wrappers around MergeFromCodedStream().
    +  // just simple wrappers around MergeFromCodedStream().  Clear() will be called
    +  // before merging the input.
     
       // Fill the message with a protocol buffer parsed from the given input
       // stream.  Returns false on a read error or if the input is in the
    @@ -158,6 +165,7 @@ class LIBPROTOBUF_EXPORT MessageLite {
       // followed by IsInitialized().
       virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0;
     
    +
       // Serialization ---------------------------------------------------
       // Methods for serializing in protocol buffer format.  Most of these
       // are just simple wrappers around ByteSize() and SerializeWithCachedSizes().
    diff --git a/toolkit/components/protobuf/google/protobuf/package_info.h b/toolkit/components/protobuf/src/google/protobuf/package_info.h
    similarity index 98%
    rename from toolkit/components/protobuf/google/protobuf/package_info.h
    rename to toolkit/components/protobuf/src/google/protobuf/package_info.h
    index 60cd3994cbb0..935e96396dc3 100644
    --- a/toolkit/components/protobuf/google/protobuf/package_info.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/package_info.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    diff --git a/toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc
    new file mode 100644
    index 000000000000..4629dec2510b
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc
    @@ -0,0 +1,269 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +void ReflectionOps::Copy(const Message& from, Message* to) {
    +  if (&from == to) return;
    +  Clear(to);
    +  Merge(from, to);
    +}
    +
    +void ReflectionOps::Merge(const Message& from, Message* to) {
    +  GOOGLE_CHECK_NE(&from, to);
    +
    +  const Descriptor* descriptor = from.GetDescriptor();
    +  GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
    +    << "Tried to merge messages of different types "
    +    << "(merge " << descriptor->full_name()
    +    << " to " << to->GetDescriptor()->full_name() << ")";
    +
    +  const Reflection* from_reflection = from.GetReflection();
    +  const Reflection* to_reflection = to->GetReflection();
    +
    +  vector fields;
    +  from_reflection->ListFields(from, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    const FieldDescriptor* field = fields[i];
    +
    +    if (field->is_repeated()) {
    +      int count = from_reflection->FieldSize(from, field);
    +      for (int j = 0; j < count; j++) {
    +        switch (field->cpp_type()) {
    +#define HANDLE_TYPE(CPPTYPE, METHOD)                                     \
    +          case FieldDescriptor::CPPTYPE_##CPPTYPE:                       \
    +            to_reflection->Add##METHOD(to, field,                        \
    +              from_reflection->GetRepeated##METHOD(from, field, j));     \
    +            break;
    +
    +          HANDLE_TYPE(INT32 , Int32 );
    +          HANDLE_TYPE(INT64 , Int64 );
    +          HANDLE_TYPE(UINT32, UInt32);
    +          HANDLE_TYPE(UINT64, UInt64);
    +          HANDLE_TYPE(FLOAT , Float );
    +          HANDLE_TYPE(DOUBLE, Double);
    +          HANDLE_TYPE(BOOL  , Bool  );
    +          HANDLE_TYPE(STRING, String);
    +          HANDLE_TYPE(ENUM  , Enum  );
    +#undef HANDLE_TYPE
    +
    +          case FieldDescriptor::CPPTYPE_MESSAGE:
    +            to_reflection->AddMessage(to, field)->MergeFrom(
    +              from_reflection->GetRepeatedMessage(from, field, j));
    +            break;
    +        }
    +      }
    +    } else {
    +      switch (field->cpp_type()) {
    +#define HANDLE_TYPE(CPPTYPE, METHOD)                                        \
    +        case FieldDescriptor::CPPTYPE_##CPPTYPE:                            \
    +          to_reflection->Set##METHOD(to, field,                             \
    +            from_reflection->Get##METHOD(from, field));                     \
    +          break;
    +
    +        HANDLE_TYPE(INT32 , Int32 );
    +        HANDLE_TYPE(INT64 , Int64 );
    +        HANDLE_TYPE(UINT32, UInt32);
    +        HANDLE_TYPE(UINT64, UInt64);
    +        HANDLE_TYPE(FLOAT , Float );
    +        HANDLE_TYPE(DOUBLE, Double);
    +        HANDLE_TYPE(BOOL  , Bool  );
    +        HANDLE_TYPE(STRING, String);
    +        HANDLE_TYPE(ENUM  , Enum  );
    +#undef HANDLE_TYPE
    +
    +        case FieldDescriptor::CPPTYPE_MESSAGE:
    +          to_reflection->MutableMessage(to, field)->MergeFrom(
    +            from_reflection->GetMessage(from, field));
    +          break;
    +      }
    +    }
    +  }
    +
    +  to_reflection->MutableUnknownFields(to)->MergeFrom(
    +    from_reflection->GetUnknownFields(from));
    +}
    +
    +void ReflectionOps::Clear(Message* message) {
    +  const Reflection* reflection = message->GetReflection();
    +
    +  vector fields;
    +  reflection->ListFields(*message, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    reflection->ClearField(message, fields[i]);
    +  }
    +
    +  reflection->MutableUnknownFields(message)->Clear();
    +}
    +
    +bool ReflectionOps::IsInitialized(const Message& message) {
    +  const Descriptor* descriptor = message.GetDescriptor();
    +  const Reflection* reflection = message.GetReflection();
    +
    +  // Check required fields of this message.
    +  for (int i = 0; i < descriptor->field_count(); i++) {
    +    if (descriptor->field(i)->is_required()) {
    +      if (!reflection->HasField(message, descriptor->field(i))) {
    +        return false;
    +      }
    +    }
    +  }
    +
    +  // Check that sub-messages are initialized.
    +  vector fields;
    +  reflection->ListFields(message, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    const FieldDescriptor* field = fields[i];
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +
    +      if (field->is_repeated()) {
    +        int size = reflection->FieldSize(message, field);
    +
    +        for (int j = 0; j < size; j++) {
    +          if (!reflection->GetRepeatedMessage(message, field, j)
    +                          .IsInitialized()) {
    +            return false;
    +          }
    +        }
    +      } else {
    +        if (!reflection->GetMessage(message, field).IsInitialized()) {
    +          return false;
    +        }
    +      }
    +    }
    +  }
    +
    +  return true;
    +}
    +
    +void ReflectionOps::DiscardUnknownFields(Message* message) {
    +  const Reflection* reflection = message->GetReflection();
    +
    +  reflection->MutableUnknownFields(message)->Clear();
    +
    +  vector fields;
    +  reflection->ListFields(*message, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    const FieldDescriptor* field = fields[i];
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      if (field->is_repeated()) {
    +        int size = reflection->FieldSize(*message, field);
    +        for (int j = 0; j < size; j++) {
    +          reflection->MutableRepeatedMessage(message, field, j)
    +                    ->DiscardUnknownFields();
    +        }
    +      } else {
    +        reflection->MutableMessage(message, field)->DiscardUnknownFields();
    +      }
    +    }
    +  }
    +}
    +
    +static string SubMessagePrefix(const string& prefix,
    +                               const FieldDescriptor* field,
    +                               int index) {
    +  string result(prefix);
    +  if (field->is_extension()) {
    +    result.append("(");
    +    result.append(field->full_name());
    +    result.append(")");
    +  } else {
    +    result.append(field->name());
    +  }
    +  if (index != -1) {
    +    result.append("[");
    +    result.append(SimpleItoa(index));
    +    result.append("]");
    +  }
    +  result.append(".");
    +  return result;
    +}
    +
    +void ReflectionOps::FindInitializationErrors(
    +    const Message& message,
    +    const string& prefix,
    +    vector* errors) {
    +  const Descriptor* descriptor = message.GetDescriptor();
    +  const Reflection* reflection = message.GetReflection();
    +
    +  // Check required fields of this message.
    +  for (int i = 0; i < descriptor->field_count(); i++) {
    +    if (descriptor->field(i)->is_required()) {
    +      if (!reflection->HasField(message, descriptor->field(i))) {
    +        errors->push_back(prefix + descriptor->field(i)->name());
    +      }
    +    }
    +  }
    +
    +  // Check sub-messages.
    +  vector fields;
    +  reflection->ListFields(message, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    const FieldDescriptor* field = fields[i];
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +
    +      if (field->is_repeated()) {
    +        int size = reflection->FieldSize(message, field);
    +
    +        for (int j = 0; j < size; j++) {
    +          const Message& sub_message =
    +            reflection->GetRepeatedMessage(message, field, j);
    +          FindInitializationErrors(sub_message,
    +                                   SubMessagePrefix(prefix, field, j),
    +                                   errors);
    +        }
    +      } else {
    +        const Message& sub_message = reflection->GetMessage(message, field);
    +        FindInitializationErrors(sub_message,
    +                                 SubMessagePrefix(prefix, field, -1),
    +                                 errors);
    +      }
    +    }
    +  }
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/reflection_ops.h b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.h
    new file mode 100644
    index 000000000000..4775911e84a2
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/reflection_ops.h
    @@ -0,0 +1,81 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// This header is logically internal, but is made public because it is used
    +// from protocol-compiler-generated code, which may reside in other components.
    +
    +#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__
    +#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__
    +
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// Basic operations that can be performed using reflection.
    +// These can be used as a cheap way to implement the corresponding
    +// methods of the Message interface, though they are likely to be
    +// slower than implementations tailored for the specific message type.
    +//
    +// This class should stay limited to operations needed to implement
    +// the Message interface.
    +//
    +// This class is really a namespace that contains only static methods.
    +class LIBPROTOBUF_EXPORT ReflectionOps {
    + public:
    +  static void Copy(const Message& from, Message* to);
    +  static void Merge(const Message& from, Message* to);
    +  static void Clear(Message* message);
    +  static bool IsInitialized(const Message& message);
    +  static void DiscardUnknownFields(Message* message);
    +
    +  // Finds all unset required fields in the message and adds their full
    +  // paths (e.g. "foo.bar[5].baz") to *names.  "prefix" will be attached to
    +  // the front of each name.
    +  static void FindInitializationErrors(const Message& message,
    +                                       const string& prefix,
    +                                       vector* errors);
    +
    + private:
    +  // All methods are static.  No need to construct.
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps);
    +};
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_REFLECTION_OPS_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/repeated_field.cc b/toolkit/components/protobuf/src/google/protobuf/repeated_field.cc
    similarity index 79%
    rename from toolkit/components/protobuf/google/protobuf/repeated_field.cc
    rename to toolkit/components/protobuf/src/google/protobuf/repeated_field.cc
    index 09377742af59..b400732fe029 100644
    --- a/toolkit/components/protobuf/google/protobuf/repeated_field.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/repeated_field.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -46,42 +46,31 @@ void RepeatedPtrFieldBase::Reserve(int new_size) {
       if (total_size_ >= new_size) return;
     
       void** old_elements = elements_;
    -  total_size_ = max(total_size_ * 2, new_size);
    +  total_size_ = max(kMinRepeatedFieldAllocationSize,
    +                    max(total_size_ * 2, new_size));
       elements_ = new void*[total_size_];
    -  memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
    -  if (old_elements != initial_space_) {
    +  if (old_elements != NULL) {
    +    memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
         delete [] old_elements;
       }
     }
     
     void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
    +  if (this == other) return;
       void** swap_elements       = elements_;
       int    swap_current_size   = current_size_;
       int    swap_allocated_size = allocated_size_;
       int    swap_total_size     = total_size_;
    -  // We may not be using initial_space_ but it's not worth checking.  Just
    -  // copy it anyway.
    -  void* swap_initial_space[kInitialSize];
    -  memcpy(swap_initial_space, initial_space_, sizeof(initial_space_));
     
       elements_       = other->elements_;
       current_size_   = other->current_size_;
       allocated_size_ = other->allocated_size_;
       total_size_     = other->total_size_;
    -  memcpy(initial_space_, other->initial_space_, sizeof(initial_space_));
     
       other->elements_       = swap_elements;
       other->current_size_   = swap_current_size;
       other->allocated_size_ = swap_allocated_size;
       other->total_size_     = swap_total_size;
    -  memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space));
    -
    -  if (elements_ == other->initial_space_) {
    -    elements_ = initial_space_;
    -  }
    -  if (other->elements_ == initial_space_) {
    -    other->elements_ = other->initial_space_;
    -  }
     }
     
     string* StringTypeHandlerBase::New() {
    diff --git a/toolkit/components/protobuf/google/protobuf/repeated_field.h b/toolkit/components/protobuf/src/google/protobuf/repeated_field.h
    similarity index 74%
    rename from toolkit/components/protobuf/google/protobuf/repeated_field.h
    rename to toolkit/components/protobuf/src/google/protobuf/repeated_field.h
    index 6080ddccce32..50051831d69f 100644
    --- a/toolkit/components/protobuf/google/protobuf/repeated_field.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/repeated_field.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -46,24 +46,55 @@
     #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
     #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
     
    +#ifdef _MSC_VER
    +// This is required for min/max on VS2013 only.
    +#include 
    +#endif
    +
     #include 
     #include 
     #include 
    +#include 
    +#include 
     #include 
     
     namespace google {
     
    +namespace upb {
    +namespace google_opensource {
    +class GMR_Handlers;
    +}  // namespace google_opensource
    +}  // namespace upb
    +
     namespace protobuf {
     
     class Message;
     
     namespace internal {
     
    -// We need this (from generated_message_reflection.cc).
    -LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
    +static const int kMinRepeatedFieldAllocationSize = 4;
     
    +// A utility function for logging that doesn't need any template types.
    +void LogIndexOutOfBounds(int index, int size);
    +
    +template 
    +inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
    +  return std::distance(begin, end);
    +}
    +
    +template 
    +inline int CalculateReserve(Iter begin, Iter end, std::input_iterator_tag) {
    +  return -1;
    +}
    +
    +template 
    +inline int CalculateReserve(Iter begin, Iter end) {
    +  typedef typename std::iterator_traits::iterator_category Category;
    +  return CalculateReserve(begin, end, Category());
    +}
     }  // namespace internal
     
    +
     // RepeatedField is used to represent repeated fields of a primitive type (in
     // other words, everything except strings and nested Messages).  Most users will
     // not ever use a RepeatedField directly; they will use the get-by-index,
    @@ -73,10 +104,13 @@ class RepeatedField {
      public:
       RepeatedField();
       RepeatedField(const RepeatedField& other);
    +  template 
    +  RepeatedField(Iter begin, const Iter& end);
       ~RepeatedField();
     
       RepeatedField& operator=(const RepeatedField& other);
     
    +  bool empty() const;
       int size() const;
     
       const Element& Get(int index) const;
    @@ -85,12 +119,14 @@ class RepeatedField {
       void Add(const Element& value);
       Element* Add();
       // Remove the last element in the array.
    -  // We don't provide a way to remove any element other than the last
    -  // because it invites inefficient use, such as O(n^2) filtering loops
    -  // that should have been O(n).  If you want to remove an element other
    -  // than the last, the best way to do it is to re-arrange the elements
    -  // so that the one you want removed is at the end, then call RemoveLast().
       void RemoveLast();
    +
    +  // Extract elements with indices in "[start .. start+num-1]".
    +  // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
    +  // Caution: implementation also moves elements with indices [start+num ..].
    +  // Calling this routine inside a loop can cause quadratic behavior.
    +  void ExtractSubrange(int start, int num, Element* elements);
    +
       void Clear();
       void MergeFrom(const RepeatedField& other);
       void CopyFrom(const RepeatedField& other);
    @@ -106,6 +142,11 @@ class RepeatedField {
       Element* AddAlreadyReserved();
       int Capacity() const;
     
    +  // Like STL resize.  Uses value to fill appended elements.
    +  // Like Truncate() if new_size <= size(), otherwise this is
    +  // O(new_size - size()).
    +  void Resize(int new_size, const Element& value);
    +
       // Gets the underlying array.  This pointer is possibly invalidated by
       // any add or remove operation.
       Element* mutable_data();
    @@ -121,25 +162,45 @@ class RepeatedField {
       typedef Element* iterator;
       typedef const Element* const_iterator;
       typedef Element value_type;
    +  typedef value_type& reference;
    +  typedef const value_type& const_reference;
    +  typedef value_type* pointer;
    +  typedef const value_type* const_pointer;
    +  typedef int size_type;
    +  typedef ptrdiff_t difference_type;
     
       iterator begin();
       const_iterator begin() const;
       iterator end();
       const_iterator end() const;
     
    +  // Reverse iterator support
    +  typedef std::reverse_iterator const_reverse_iterator;
    +  typedef std::reverse_iterator reverse_iterator;
    +  reverse_iterator rbegin() {
    +    return reverse_iterator(end());
    +  }
    +  const_reverse_iterator rbegin() const {
    +    return const_reverse_iterator(end());
    +  }
    +  reverse_iterator rend() {
    +    return reverse_iterator(begin());
    +  }
    +  const_reverse_iterator rend() const {
    +    return const_reverse_iterator(begin());
    +  }
    +
       // Returns the number of bytes used by the repeated field, excluding
       // sizeof(*this)
       int SpaceUsedExcludingSelf() const;
     
      private:
    -  static const int kInitialSize = 4;
    +  static const int kInitialSize = 0;
     
       Element* elements_;
       int      current_size_;
       int      total_size_;
     
    -  Element  initial_space_[kInitialSize];
    -
       // Move the contents of |from| into |to|, possibly clobbering |from| in the
       // process.  For primitive types this is just a memcpy(), but it could be
       // specialized for non-primitive types to, say, swap each element instead.
    @@ -151,7 +212,21 @@ class RepeatedField {
     
     namespace internal {
     template  class RepeatedPtrIterator;
    -template  class RepeatedPtrOverPtrsIterator;
    +template  class RepeatedPtrOverPtrsIterator;
    +}  // namespace internal
    +
    +namespace internal {
    +
    +// This is a helper template to copy an array of elements effeciently when they
    +// have a trivial copy constructor, and correctly otherwise. This really
    +// shouldn't be necessary, but our compiler doesn't optimize std::copy very
    +// effectively.
    +template ::value>
    +struct ElementCopier {
    +  void operator()(Element to[], const Element from[], int array_size);
    +};
    +
     }  // namespace internal
     
     namespace internal {
    @@ -186,12 +261,17 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
       // use of AddFromCleared(), which is not part of the public interface.
       friend class ExtensionSet;
     
    +  // To parse directly into a proto2 generated class, the upb class GMR_Handlers
    +  // needs to be able to modify a RepeatedPtrFieldBase directly.
    +  friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
    +
       RepeatedPtrFieldBase();
     
       // Must be called from destructor.
       template 
       void Destroy();
     
    +  bool empty() const;
       int size() const;
     
       template 
    @@ -209,6 +289,14 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
       template 
       void CopyFrom(const RepeatedPtrFieldBase& other);
     
    +  void CloseGap(int start, int num) {
    +    // Close up a gap of "num" elements starting at offset "start".
    +    for (int i = start + num; i < allocated_size_; ++i)
    +      elements_[i - num] = elements_[i];
    +    current_size_ -= num;
    +    allocated_size_ -= num;
    +  }
    +
       void Reserve(int new_size);
     
       int Capacity() const;
    @@ -248,17 +336,13 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
       typename TypeHandler::Type* ReleaseCleared();
     
      private:
    -  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
    -
    -  static const int kInitialSize = 4;
    +  static const int kInitialSize = 0;
     
       void** elements_;
       int    current_size_;
       int    allocated_size_;
       int    total_size_;
     
    -  void*  initial_space_[kInitialSize];
    -
       template 
       static inline typename TypeHandler::Type* cast(void* element) {
         return reinterpret_cast(element);
    @@ -267,6 +351,8 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
       static inline const typename TypeHandler::Type* cast(const void* element) {
         return reinterpret_cast(element);
       }
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
     };
     
     template 
    @@ -280,6 +366,7 @@ class GenericTypeHandler {
         to->MergeFrom(from);
       }
       static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
    +  static const Type& default_instance() { return Type::default_instance(); }
     };
     
     template <>
    @@ -288,6 +375,25 @@ inline void GenericTypeHandler::Merge(
       to->CheckTypeAndMergeFrom(from);
     }
     
    +template <>
    +inline const MessageLite& GenericTypeHandler::default_instance() {
    +  // Yes, the behavior of the code is undefined, but this function is only
    +  // called when we're already deep into the world of undefined, because the
    +  // caller called Get(index) out of bounds.
    +  MessageLite* null = NULL;
    +  return *null;
    +}
    +
    +template <>
    +inline const Message& GenericTypeHandler::default_instance() {
    +  // Yes, the behavior of the code is undefined, but this function is only
    +  // called when we're already deep into the world of undefined, because the
    +  // caller called Get(index) out of bounds.
    +  Message* null = NULL;
    +  return *null;
    +}
    +
    +
     // HACK:  If a class is declared as DLL-exported in MSVC, it insists on
     //   generating copies of all its methods -- even inline ones -- to include
     //   in the DLL.  But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
    @@ -303,9 +409,12 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
       static void Delete(string* value);
       static void Clear(string* value) { value->clear(); }
       static void Merge(const string& from, string* to) { *to = from; }
    +  static const Type& default_instance() {
    +    return ::google::protobuf::internal::GetEmptyString();
    +  }
     };
     
    -class LIBPROTOBUF_EXPORT StringTypeHandler : public StringTypeHandlerBase {
    +class StringTypeHandler : public StringTypeHandlerBase {
      public:
       static int SpaceUsed(const string& value)  {
         return sizeof(value) + StringSpaceUsedExcludingSelf(value);
    @@ -322,16 +431,28 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
      public:
       RepeatedPtrField();
       RepeatedPtrField(const RepeatedPtrField& other);
    +  template 
    +  RepeatedPtrField(Iter begin, const Iter& end);
       ~RepeatedPtrField();
     
       RepeatedPtrField& operator=(const RepeatedPtrField& other);
     
    +  bool empty() const;
       int size() const;
     
       const Element& Get(int index) const;
       Element* Mutable(int index);
       Element* Add();
    -  void RemoveLast();  // Remove the last element in the array.
    +
    +  // Remove the last element in the array.
    +  // Ownership of the element is retained by the array.
    +  void RemoveLast();
    +
    +  // Delete elements with indices in the range [start .. start+num-1].
    +  // Caution: implementation moves all elements with indices [start+num .. ].
    +  // Calling this routine inside a loop can cause quadratic behavior.
    +  void DeleteSubrange(int start, int num);
    +
       void Clear();
       void MergeFrom(const RepeatedPtrField& other);
       void CopyFrom(const RepeatedPtrField& other);
    @@ -358,42 +479,78 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
       typedef internal::RepeatedPtrIterator iterator;
       typedef internal::RepeatedPtrIterator const_iterator;
       typedef Element value_type;
    +  typedef value_type& reference;
    +  typedef const value_type& const_reference;
    +  typedef value_type* pointer;
    +  typedef const value_type* const_pointer;
    +  typedef int size_type;
    +  typedef ptrdiff_t difference_type;
     
       iterator begin();
       const_iterator begin() const;
       iterator end();
       const_iterator end() const;
     
    +  // Reverse iterator support
    +  typedef std::reverse_iterator const_reverse_iterator;
    +  typedef std::reverse_iterator reverse_iterator;
    +  reverse_iterator rbegin() {
    +    return reverse_iterator(end());
    +  }
    +  const_reverse_iterator rbegin() const {
    +    return const_reverse_iterator(end());
    +  }
    +  reverse_iterator rend() {
    +    return reverse_iterator(begin());
    +  }
    +  const_reverse_iterator rend() const {
    +    return const_reverse_iterator(begin());
    +  }
    +
       // Custom STL-like iterator that iterates over and returns the underlying
       // pointers to Element rather than Element itself.
    -  typedef internal::RepeatedPtrOverPtrsIterator pointer_iterator;
    +  typedef internal::RepeatedPtrOverPtrsIterator
    +  pointer_iterator;
    +  typedef internal::RepeatedPtrOverPtrsIterator
    +  const_pointer_iterator;
       pointer_iterator pointer_begin();
    +  const_pointer_iterator pointer_begin() const;
       pointer_iterator pointer_end();
    +  const_pointer_iterator pointer_end() const;
     
       // Returns (an estimate of) the number of bytes used by the repeated field,
       // excluding sizeof(*this).
       int SpaceUsedExcludingSelf() const;
     
       // Advanced memory management --------------------------------------
    -  // When hardcore memory management becomes necessary -- as it often
    +  // When hardcore memory management becomes necessary -- as it sometimes
       // does here at Google -- the following methods may be useful.
     
       // Add an already-allocated object, passing ownership to the
       // RepeatedPtrField.
       void AddAllocated(Element* value);
    -  // Remove the last element and return it, passing ownership to the
    -  // caller.
    +  // Remove the last element and return it, passing ownership to the caller.
       // Requires:  size() > 0
       Element* ReleaseLast();
     
    +  // Extract elements with indices in the range "[start .. start+num-1]".
    +  // The caller assumes ownership of the extracted elements and is responsible
    +  // for deleting them when they are no longer needed.
    +  // If "elements" is non-NULL, then pointers to the extracted elements
    +  // are stored in "elements[0 .. num-1]" for the convenience of the caller.
    +  // If "elements" is NULL, then the caller must use some other mechanism
    +  // to perform any further operations (like deletion) on these elements.
    +  // Caution: implementation also moves elements with indices [start+num ..].
    +  // Calling this routine inside a loop can cause quadratic behavior.
    +  void ExtractSubrange(int start, int num, Element** elements);
    +
       // When elements are removed by calls to RemoveLast() or Clear(), they
       // are not actually freed.  Instead, they are cleared and kept so that
       // they can be reused later.  This can save lots of CPU time when
       // repeatedly reusing a protocol message for similar purposes.
       //
    -  // Really, extremely hardcore programs may actually want to manipulate
    -  // these objects to better-optimize memory management.  These methods
    -  // allow that.
    +  // Hardcore programs may choose to manipulate these cleared objects
    +  // to better optimize memory management using the following routines.
     
       // Get the number of cleared objects that are currently being kept
       // around for reuse.
    @@ -420,33 +577,56 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
     
     template 
     inline RepeatedField::RepeatedField()
    -  : elements_(initial_space_),
    +  : elements_(NULL),
         current_size_(0),
         total_size_(kInitialSize) {
     }
     
     template 
     inline RepeatedField::RepeatedField(const RepeatedField& other)
    -  : elements_(initial_space_),
    +  : elements_(NULL),
         current_size_(0),
         total_size_(kInitialSize) {
       CopyFrom(other);
     }
     
     template 
    -RepeatedField::~RepeatedField() {
    -  if (elements_ != initial_space_) {
    -    delete [] elements_;
    +template 
    +inline RepeatedField::RepeatedField(Iter begin, const Iter& end)
    +  : elements_(NULL),
    +    current_size_(0),
    +    total_size_(kInitialSize) {
    +  int reserve = internal::CalculateReserve(begin, end);
    +  if (reserve != -1) {
    +    Reserve(reserve);
    +    for (; begin != end; ++begin) {
    +      AddAlreadyReserved(*begin);
    +    }
    +  } else {
    +    for (; begin != end; ++begin) {
    +      Add(*begin);
    +    }
       }
     }
     
    +template 
    +RepeatedField::~RepeatedField() {
    +  delete [] elements_;
    +}
    +
     template 
     inline RepeatedField&
     RepeatedField::operator=(const RepeatedField& other) {
    -  CopyFrom(other);
    +  if (this != &other)
    +    CopyFrom(other);
       return *this;
     }
     
    +template 
    +inline bool RepeatedField::empty() const {
    +  return current_size_ == 0;
    +}
    +
     template 
     inline int RepeatedField::size() const {
       return current_size_;
    @@ -469,20 +649,33 @@ inline Element* RepeatedField::AddAlreadyReserved() {
       return &elements_[current_size_++];
     }
     
    +template
    +inline void RepeatedField::Resize(int new_size, const Element& value) {
    +  GOOGLE_DCHECK_GE(new_size, 0);
    +  if (new_size > size()) {
    +    Reserve(new_size);
    +    std::fill(&elements_[current_size_], &elements_[new_size], value);
    +  }
    +  current_size_ = new_size;
    +}
    +
     template 
     inline const Element& RepeatedField::Get(int index) const {
    +  GOOGLE_DCHECK_GE(index, 0);
       GOOGLE_DCHECK_LT(index, size());
       return elements_[index];
     }
     
     template 
     inline Element* RepeatedField::Mutable(int index) {
    +  GOOGLE_DCHECK_GE(index, 0);
       GOOGLE_DCHECK_LT(index, size());
       return elements_ + index;
     }
     
     template 
     inline void RepeatedField::Set(int index, const Element& value) {
    +  GOOGLE_DCHECK_GE(index, 0);
       GOOGLE_DCHECK_LT(index, size());
       elements_[index] = value;
     }
    @@ -505,6 +698,27 @@ inline void RepeatedField::RemoveLast() {
       --current_size_;
     }
     
    +template 
    +void RepeatedField::ExtractSubrange(
    +    int start, int num, Element* elements) {
    +  GOOGLE_DCHECK_GE(start, 0);
    +  GOOGLE_DCHECK_GE(num, 0);
    +  GOOGLE_DCHECK_LE(start + num, this->size());
    +
    +  // Save the values of the removed elements if requested.
    +  if (elements != NULL) {
    +    for (int i = 0; i < num; ++i)
    +      elements[i] = this->Get(i + start);
    +  }
    +
    +  // Slide remaining elements down to fill the gap.
    +  if (num > 0) {
    +    for (int i = start + num; i < this->size(); ++i)
    +      this->Set(i - num, this->Get(i));
    +    this->Truncate(this->size() - num);
    +  }
    +}
    +
     template 
     inline void RepeatedField::Clear() {
       current_size_ = 0;
    @@ -512,13 +726,17 @@ inline void RepeatedField::Clear() {
     
     template 
     inline void RepeatedField::MergeFrom(const RepeatedField& other) {
    -  Reserve(current_size_ + other.current_size_);
    -  CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
    -  current_size_ += other.current_size_;
    +  GOOGLE_CHECK_NE(&other, this);
    +  if (other.current_size_ != 0) {
    +    Reserve(current_size_ + other.current_size_);
    +    CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
    +    current_size_ += other.current_size_;
    +  }
     }
     
     template 
     inline void RepeatedField::CopyFrom(const RepeatedField& other) {
    +  if (&other == this) return;
       Clear();
       MergeFrom(other);
     }
    @@ -536,35 +754,24 @@ inline const Element* RepeatedField::data() const {
     
     template 
     void RepeatedField::Swap(RepeatedField* other) {
    +  if (this == other) return;
       Element* swap_elements     = elements_;
       int      swap_current_size = current_size_;
       int      swap_total_size   = total_size_;
    -  // We may not be using initial_space_ but it's not worth checking.  Just
    -  // copy it anyway.
    -  Element swap_initial_space[kInitialSize];
    -  MoveArray(swap_initial_space, initial_space_, kInitialSize);
     
       elements_     = other->elements_;
       current_size_ = other->current_size_;
       total_size_   = other->total_size_;
    -  MoveArray(initial_space_, other->initial_space_, kInitialSize);
     
       other->elements_     = swap_elements;
       other->current_size_ = swap_current_size;
       other->total_size_   = swap_total_size;
    -  MoveArray(other->initial_space_, swap_initial_space, kInitialSize);
    -
    -  if (elements_ == other->initial_space_) {
    -    elements_ = initial_space_;
    -  }
    -  if (other->elements_ == initial_space_) {
    -    other->elements_ = other->initial_space_;
    -  }
     }
     
     template 
     void RepeatedField::SwapElements(int index1, int index2) {
    -  std::swap(elements_[index1], elements_[index2]);
    +  using std::swap;  // enable ADL with fallback
    +  swap(elements_[index1], elements_[index2]);
     }
     
     template 
    @@ -590,20 +797,21 @@ RepeatedField::end() const {
     
     template 
     inline int RepeatedField::SpaceUsedExcludingSelf() const {
    -  return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
    +  return (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
     }
     
    -// Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant
    +// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
     // amount of code bloat.
     template 
     void RepeatedField::Reserve(int new_size) {
       if (total_size_ >= new_size) return;
     
       Element* old_elements = elements_;
    -  total_size_ = max(total_size_ * 2, new_size);
    +  total_size_ = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
    +                    max(total_size_ * 2, new_size));
       elements_ = new Element[total_size_];
    -  MoveArray(elements_, old_elements, current_size_);
    -  if (old_elements != initial_space_) {
    +  if (old_elements != NULL) {
    +    MoveArray(elements_, old_elements, current_size_);
         delete [] old_elements;
       }
     }
    @@ -617,22 +825,39 @@ inline void RepeatedField::Truncate(int new_size) {
     template 
     inline void RepeatedField::MoveArray(
         Element to[], Element from[], int array_size) {
    -  memcpy(to, from, array_size * sizeof(Element));
    +  CopyArray(to, from, array_size);
     }
     
     template 
     inline void RepeatedField::CopyArray(
         Element to[], const Element from[], int array_size) {
    -  memcpy(to, from, array_size * sizeof(Element));
    +  internal::ElementCopier()(to, from, array_size);
     }
     
    +namespace internal {
    +
    +template 
    +void ElementCopier::operator()(
    +    Element to[], const Element from[], int array_size) {
    +  std::copy(from, from + array_size, to);
    +}
    +
    +template 
    +struct ElementCopier {
    +  void operator()(Element to[], const Element from[], int array_size) {
    +    memcpy(to, from, array_size * sizeof(Element));
    +  }
    +};
    +
    +}  // namespace internal
    +
     
     // -------------------------------------------------------------------
     
     namespace internal {
     
     inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
    -  : elements_(initial_space_),
    +  : elements_(NULL),
         current_size_(0),
         allocated_size_(0),
         total_size_(kInitialSize) {
    @@ -643,26 +868,30 @@ void RepeatedPtrFieldBase::Destroy() {
       for (int i = 0; i < allocated_size_; i++) {
         TypeHandler::Delete(cast(elements_[i]));
       }
    -  if (elements_ != initial_space_) {
    -    delete [] elements_;
    -  }
    +  delete [] elements_;
    +}
    +
    +inline bool RepeatedPtrFieldBase::empty() const {
    +  return current_size_ == 0;
     }
     
     inline int RepeatedPtrFieldBase::size() const {
       return current_size_;
     }
     
    -
     template 
     inline const typename TypeHandler::Type&
     RepeatedPtrFieldBase::Get(int index) const {
    +  GOOGLE_DCHECK_GE(index, 0);
       GOOGLE_DCHECK_LT(index, size());
       return *cast(elements_[index]);
     }
     
    +
     template 
     inline typename TypeHandler::Type*
     RepeatedPtrFieldBase::Mutable(int index) {
    +  GOOGLE_DCHECK_GE(index, 0);
       GOOGLE_DCHECK_LT(index, size());
       return cast(elements_[index]);
     }
    @@ -673,8 +902,8 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
         return cast(elements_[current_size_++]);
       }
       if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
    -  ++allocated_size_;
       typename TypeHandler::Type* result = TypeHandler::New();
    +  ++allocated_size_;
       elements_[current_size_++] = result;
       return result;
     }
    @@ -695,6 +924,7 @@ void RepeatedPtrFieldBase::Clear() {
     
     template 
     inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
    +  GOOGLE_CHECK_NE(&other, this);
       Reserve(current_size_ + other.current_size_);
       for (int i = 0; i < other.current_size_; i++) {
         TypeHandler::Merge(other.template Get(i), Add());
    @@ -703,6 +933,7 @@ inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
     
     template 
     inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
    +  if (&other == this) return;
       RepeatedPtrFieldBase::Clear();
       RepeatedPtrFieldBase::MergeFrom(other);
     }
    @@ -735,13 +966,14 @@ RepeatedPtrFieldBase::data() const {
     }
     
     inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
    -  std::swap(elements_[index1], elements_[index2]);
    +  using std::swap;  // enable ADL with fallback
    +  swap(elements_[index1], elements_[index2]);
     }
     
     template 
     inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
       int allocated_bytes =
    -      (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
    +      (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
       for (int i = 0; i < allocated_size_; ++i) {
         allocated_bytes += TypeHandler::SpaceUsed(*cast(elements_[i]));
       }
    @@ -798,7 +1030,6 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
       return result;
     }
     
    -
     inline int RepeatedPtrFieldBase::ClearedCount() const {
       return allocated_size_ - current_size_;
     }
    @@ -822,11 +1053,13 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
     
     template 
     class RepeatedPtrField::TypeHandler
    -    : public internal::GenericTypeHandler {};
    +    : public internal::GenericTypeHandler {
    +};
     
     template <>
     class RepeatedPtrField::TypeHandler
    -    : public internal::StringTypeHandler {};
    +    : public internal::StringTypeHandler {
    +};
     
     
     template 
    @@ -834,10 +1067,24 @@ inline RepeatedPtrField::RepeatedPtrField() {}
     
     template 
     inline RepeatedPtrField::RepeatedPtrField(
    -    const RepeatedPtrField& other) {
    +    const RepeatedPtrField& other)
    +    : RepeatedPtrFieldBase() {
       CopyFrom(other);
     }
     
    +template 
    +template 
    +inline RepeatedPtrField::RepeatedPtrField(
    +    Iter begin, const Iter& end) {
    +  int reserve = internal::CalculateReserve(begin, end);
    +  if (reserve != -1) {
    +    Reserve(reserve);
    +  }
    +  for (; begin != end; ++begin) {
    +    *Add() = *begin;
    +  }
    +}
    +
     template 
     RepeatedPtrField::~RepeatedPtrField() {
       Destroy();
    @@ -846,10 +1093,16 @@ RepeatedPtrField::~RepeatedPtrField() {
     template 
     inline RepeatedPtrField& RepeatedPtrField::operator=(
         const RepeatedPtrField& other) {
    -  CopyFrom(other);
    +  if (this != &other)
    +    CopyFrom(other);
       return *this;
     }
     
    +template 
    +inline bool RepeatedPtrField::empty() const {
    +  return RepeatedPtrFieldBase::empty();
    +}
    +
     template 
     inline int RepeatedPtrField::size() const {
       return RepeatedPtrFieldBase::size();
    @@ -860,6 +1113,7 @@ inline const Element& RepeatedPtrField::Get(int index) const {
       return RepeatedPtrFieldBase::Get(index);
     }
     
    +
     template 
     inline Element* RepeatedPtrField::Mutable(int index) {
       return RepeatedPtrFieldBase::Mutable(index);
    @@ -875,6 +1129,33 @@ inline void RepeatedPtrField::RemoveLast() {
       RepeatedPtrFieldBase::RemoveLast();
     }
     
    +template 
    +inline void RepeatedPtrField::DeleteSubrange(int start, int num) {
    +  GOOGLE_DCHECK_GE(start, 0);
    +  GOOGLE_DCHECK_GE(num, 0);
    +  GOOGLE_DCHECK_LE(start + num, size());
    +  for (int i = 0; i < num; ++i)
    +    delete RepeatedPtrFieldBase::Mutable(start + i);
    +  ExtractSubrange(start, num, NULL);
    +}
    +
    +template 
    +inline void RepeatedPtrField::ExtractSubrange(
    +    int start, int num, Element** elements) {
    +  GOOGLE_DCHECK_GE(start, 0);
    +  GOOGLE_DCHECK_GE(num, 0);
    +  GOOGLE_DCHECK_LE(start + num, size());
    +
    +  if (num > 0) {
    +    // Save the values of the removed elements if requested.
    +    if (elements != NULL) {
    +      for (int i = 0; i < num; ++i)
    +        elements[i] = RepeatedPtrFieldBase::Mutable(i + start);
    +    }
    +    CloseGap(start, num);
    +  }
    +}
    +
     template 
     inline void RepeatedPtrField::Clear() {
       RepeatedPtrFieldBase::Clear();
    @@ -961,7 +1242,7 @@ namespace internal {
     // refer to this class directly; use RepeatedPtrField::iterator instead.
     //
     // The iterator for RepeatedPtrField, RepeatedPtrIterator, is
    -// very similar to iterator_ptr in util/gtl/iterator_adaptors-inl.h,
    +// very similar to iterator_ptr in util/gtl/iterator_adaptors.h,
     // but adds random-access operators and is modified to wrap a void** base
     // iterator (since RepeatedPtrField stores its array as a void* array and
     // casting void** to T** would violate C++ aliasing rules).
    @@ -977,6 +1258,10 @@ class RepeatedPtrIterator
       typedef std::iterator<
               std::random_access_iterator_tag, Element> superclass;
     
    +  // Shadow the value_type in std::iterator<> because const_iterator::value_type
    +  // needs to be T, not const T.
    +  typedef typename remove_const::type value_type;
    +
       // Let the compiler know that these are type names, so we don't have to
       // write "typename" in front of them everywhere.
       typedef typename superclass::reference reference;
    @@ -1057,14 +1342,21 @@ class RepeatedPtrIterator
     // rather than the objects themselves as RepeatedPtrIterator does.
     // Consider using this when working with stl algorithms that change
     // the array.
    -template
    +// The VoidPtr template parameter holds the type-agnostic pointer value
    +// referenced by the iterator.  It should either be "void *" for a mutable
    +// iterator, or "const void *" for a constant iterator.
    +template
     class RepeatedPtrOverPtrsIterator
         : public std::iterator {
      public:
    -  typedef RepeatedPtrOverPtrsIterator iterator;
    +  typedef RepeatedPtrOverPtrsIterator iterator;
       typedef std::iterator<
               std::random_access_iterator_tag, Element*> superclass;
     
    +  // Shadow the value_type in std::iterator<> because const_iterator::value_type
    +  // needs to be T, not const T.
    +  typedef typename remove_const::type value_type;
    +
       // Let the compiler know that these are type names, so we don't have to
       // write "typename" in front of them everywhere.
       typedef typename superclass::reference reference;
    @@ -1072,7 +1364,7 @@ class RepeatedPtrOverPtrsIterator
       typedef typename superclass::difference_type difference_type;
     
       RepeatedPtrOverPtrsIterator() : it_(NULL) {}
    -  explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {}
    +  explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
     
       // dereferenceable
       reference operator*() const { return *reinterpret_cast(it_); }
    @@ -1127,10 +1419,9 @@ class RepeatedPtrOverPtrsIterator
       friend class RepeatedPtrIterator;
     
       // The internal iterator.
    -  void** it_;
    +  VoidPtr* it_;
     };
     
    -
     }  // namespace internal
     
     template 
    @@ -1160,10 +1451,21 @@ RepeatedPtrField::pointer_begin() {
       return pointer_iterator(raw_mutable_data());
     }
     template 
    +inline typename RepeatedPtrField::const_pointer_iterator
    +RepeatedPtrField::pointer_begin() const {
    +  return const_pointer_iterator(const_cast(raw_mutable_data()));
    +}
    +template 
     inline typename RepeatedPtrField::pointer_iterator
     RepeatedPtrField::pointer_end() {
       return pointer_iterator(raw_mutable_data() + size());
     }
    +template 
    +inline typename RepeatedPtrField::const_pointer_iterator
    +RepeatedPtrField::pointer_end() const {
    +  return const_pointer_iterator(
    +      const_cast(raw_mutable_data() + size()));
    +}
     
     
     // Iterators and helper functions that follow the spirit of the STL
    @@ -1173,7 +1475,7 @@ RepeatedPtrField::pointer_end() {
     //   std::copy(some_sequence.begin(), some_sequence.end(),
     //             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
     //
    -// Ported by johannes from util/gtl/proto-array-iterators-inl.h
    +// Ported by johannes from util/gtl/proto-array-iterators.h
     
     namespace internal {
     // A back inserter for RepeatedField objects.
    @@ -1194,7 +1496,7 @@ template class RepeatedFieldBackInsertIterator
       RepeatedFieldBackInsertIterator& operator++() {
         return *this;
       }
    -  RepeatedFieldBackInsertIterator& operator++(int ignores_parameter) {
    +  RepeatedFieldBackInsertIterator& operator++(int /* unused */) {
         return *this;
       }
     
    @@ -1225,7 +1527,7 @@ template class RepeatedPtrFieldBackInsertIterator
       RepeatedPtrFieldBackInsertIterator& operator++() {
         return *this;
       }
    -  RepeatedPtrFieldBackInsertIterator& operator++(int ignores_parameter) {
    +  RepeatedPtrFieldBackInsertIterator& operator++(int /* unused */) {
         return *this;
       }
     
    @@ -1254,7 +1556,7 @@ template class AllocatedRepeatedPtrFieldBackInsertIterator
         return *this;
       }
       AllocatedRepeatedPtrFieldBackInsertIterator& operator++(
    -      int ignores_parameter) {
    +      int /* unused */) {
         return *this;
       }
     
    @@ -1264,16 +1566,22 @@ template class AllocatedRepeatedPtrFieldBackInsertIterator
     }  // namespace internal
     
     // Provides a back insert iterator for RepeatedField instances,
    -// similar to std::back_inserter(). Note the identically named
    -// function for RepeatedPtrField instances.
    +// similar to std::back_inserter().
     template internal::RepeatedFieldBackInsertIterator
     RepeatedFieldBackInserter(RepeatedField* const mutable_field) {
       return internal::RepeatedFieldBackInsertIterator(mutable_field);
     }
     
     // Provides a back insert iterator for RepeatedPtrField instances,
    -// similar to std::back_inserter(). Note the identically named
    -// function for RepeatedField instances.
    +// similar to std::back_inserter().
    +template internal::RepeatedPtrFieldBackInsertIterator
    +RepeatedPtrFieldBackInserter(RepeatedPtrField* const mutable_field) {
    +  return internal::RepeatedPtrFieldBackInsertIterator(mutable_field);
    +}
    +
    +// Special back insert iterator for RepeatedPtrField instances, just in
    +// case someone wants to write generic template code that can access both
    +// RepeatedFields and RepeatedPtrFields using a common name.
     template internal::RepeatedPtrFieldBackInsertIterator
     RepeatedFieldBackInserter(RepeatedPtrField* const mutable_field) {
       return internal::RepeatedPtrFieldBackInsertIterator(mutable_field);
    diff --git a/toolkit/components/protobuf/google/protobuf/generated_message_util.h b/toolkit/components/protobuf/src/google/protobuf/service.cc
    similarity index 60%
    rename from toolkit/components/protobuf/google/protobuf/generated_message_util.h
    rename to toolkit/components/protobuf/src/google/protobuf/service.cc
    index 1a2343d44083..ffa919daa7e6 100644
    --- a/toolkit/components/protobuf/google/protobuf/generated_message_util.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/service.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -31,52 +31,16 @@
     // Author: kenton@google.com (Kenton Varda)
     //  Based on original Protocol Buffers design by
     //  Sanjay Ghemawat, Jeff Dean, and others.
    -//
    -// This file contains miscellaneous helper code used by generated code --
    -// including lite types -- but which should not be used directly by users.
    -
    -#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
    -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
    -
    -#include 
    -
    -#include 
     
    +#include 
     
     namespace google {
     namespace protobuf {
    -  namespace io {
    -    class CodedInputStream;      // coded_stream.h
    -  }
    -}
     
    -namespace protobuf {
    -namespace internal {
    +Service::~Service() {}
    +RpcChannel::~RpcChannel() {}
    +RpcController::~RpcController() {}
     
    -// Annotation for the compiler to emit a deprecation message if a field marked
    -// with option 'deprecated=true' is used in the code, or for other things in
    -// generated code which are deprecated.
    -//
    -// For internal use in the pb.cc files, deprecation warnings are suppressed
    -// there.
    -#undef DEPRECATED_PROTOBUF_FIELD
    -#if !defined(INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION)
    -#  define PROTOBUF_DEPRECATED GOOGLE_ATTRIBUTE_DEPRECATED
    -#else
    -#  define PROTOBUF_DEPRECATED
    -#endif
    -
    -
    -// Constants for special floating point values.
    -double Infinity();
    -double NaN();
    -
    -// Constant used for empty default strings.
    -extern const ::std::string kEmptyString;
    -
    -
    -}  // namespace internal
     }  // namespace protobuf
     
     }  // namespace google
    -#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/service.h b/toolkit/components/protobuf/src/google/protobuf/service.h
    new file mode 100644
    index 000000000000..cc0b45d41079
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/service.h
    @@ -0,0 +1,291 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// DEPRECATED:  This module declares the abstract interfaces underlying proto2
    +// RPC services.  These are intented to be independent of any particular RPC
    +// implementation, so that proto2 services can be used on top of a variety
    +// of implementations.  Starting with version 2.3.0, RPC implementations should
    +// not try to build on these, but should instead provide code generator plugins
    +// which generate code specific to the particular RPC implementation.  This way
    +// the generated code can be more appropriate for the implementation in use
    +// and can avoid unnecessary layers of indirection.
    +//
    +//
    +// When you use the protocol compiler to compile a service definition, it
    +// generates two classes:  An abstract interface for the service (with
    +// methods matching the service definition) and a "stub" implementation.
    +// A stub is just a type-safe wrapper around an RpcChannel which emulates a
    +// local implementation of the service.
    +//
    +// For example, the service definition:
    +//   service MyService {
    +//     rpc Foo(MyRequest) returns(MyResponse);
    +//   }
    +// will generate abstract interface "MyService" and class "MyService::Stub".
    +// You could implement a MyService as follows:
    +//   class MyServiceImpl : public MyService {
    +//    public:
    +//     MyServiceImpl() {}
    +//     ~MyServiceImpl() {}
    +//
    +//     // implements MyService ---------------------------------------
    +//
    +//     void Foo(google::protobuf::RpcController* controller,
    +//              const MyRequest* request,
    +//              MyResponse* response,
    +//              Closure* done) {
    +//       // ... read request and fill in response ...
    +//       done->Run();
    +//     }
    +//   };
    +// You would then register an instance of MyServiceImpl with your RPC server
    +// implementation.  (How to do that depends on the implementation.)
    +//
    +// To call a remote MyServiceImpl, first you need an RpcChannel connected to it.
    +// How to construct a channel depends, again, on your RPC implementation.
    +// Here we use a hypothentical "MyRpcChannel" as an example:
    +//   MyRpcChannel channel("rpc:hostname:1234/myservice");
    +//   MyRpcController controller;
    +//   MyServiceImpl::Stub stub(&channel);
    +//   FooRequest request;
    +//   FooRespnose response;
    +//
    +//   // ... fill in request ...
    +//
    +//   stub.Foo(&controller, request, &response, NewCallback(HandleResponse));
    +//
    +// On Thread-Safety:
    +//
    +// Different RPC implementations may make different guarantees about what
    +// threads they may run callbacks on, and what threads the application is
    +// allowed to use to call the RPC system.  Portable software should be ready
    +// for callbacks to be called on any thread, but should not try to call the
    +// RPC system from any thread except for the ones on which it received the
    +// callbacks.  Realistically, though, simple software will probably want to
    +// use a single-threaded RPC system while high-end software will want to
    +// use multiple threads.  RPC implementations should provide multiple
    +// choices.
    +
    +#ifndef GOOGLE_PROTOBUF_SERVICE_H__
    +#define GOOGLE_PROTOBUF_SERVICE_H__
    +
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +// Defined in this file.
    +class Service;
    +class RpcController;
    +class RpcChannel;
    +
    +// Defined in other files.
    +class Descriptor;            // descriptor.h
    +class ServiceDescriptor;     // descriptor.h
    +class MethodDescriptor;      // descriptor.h
    +class Message;               // message.h
    +
    +// Abstract base interface for protocol-buffer-based RPC services.  Services
    +// themselves are abstract interfaces (implemented either by servers or as
    +// stubs), but they subclass this base interface.  The methods of this
    +// interface can be used to call the methods of the Service without knowing
    +// its exact type at compile time (analogous to Reflection).
    +class LIBPROTOBUF_EXPORT Service {
    + public:
    +  inline Service() {}
    +  virtual ~Service();
    +
    +  // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second
    +  // parameter to the constructor to tell it to delete its RpcChannel when
    +  // destroyed.
    +  enum ChannelOwnership {
    +    STUB_OWNS_CHANNEL,
    +    STUB_DOESNT_OWN_CHANNEL
    +  };
    +
    +  // Get the ServiceDescriptor describing this service and its methods.
    +  virtual const ServiceDescriptor* GetDescriptor() = 0;
    +
    +  // Call a method of the service specified by MethodDescriptor.  This is
    +  // normally implemented as a simple switch() that calls the standard
    +  // definitions of the service's methods.
    +  //
    +  // Preconditions:
    +  // * method->service() == GetDescriptor()
    +  // * request and response are of the exact same classes as the objects
    +  //   returned by GetRequestPrototype(method) and
    +  //   GetResponsePrototype(method).
    +  // * After the call has started, the request must not be modified and the
    +  //   response must not be accessed at all until "done" is called.
    +  // * "controller" is of the correct type for the RPC implementation being
    +  //   used by this Service.  For stubs, the "correct type" depends on the
    +  //   RpcChannel which the stub is using.  Server-side Service
    +  //   implementations are expected to accept whatever type of RpcController
    +  //   the server-side RPC implementation uses.
    +  //
    +  // Postconditions:
    +  // * "done" will be called when the method is complete.  This may be
    +  //   before CallMethod() returns or it may be at some point in the future.
    +  // * If the RPC succeeded, "response" contains the response returned by
    +  //   the server.
    +  // * If the RPC failed, "response"'s contents are undefined.  The
    +  //   RpcController can be queried to determine if an error occurred and
    +  //   possibly to get more information about the error.
    +  virtual void CallMethod(const MethodDescriptor* method,
    +                          RpcController* controller,
    +                          const Message* request,
    +                          Message* response,
    +                          Closure* done) = 0;
    +
    +  // CallMethod() requires that the request and response passed in are of a
    +  // particular subclass of Message.  GetRequestPrototype() and
    +  // GetResponsePrototype() get the default instances of these required types.
    +  // You can then call Message::New() on these instances to construct mutable
    +  // objects which you can then pass to CallMethod().
    +  //
    +  // Example:
    +  //   const MethodDescriptor* method =
    +  //     service->GetDescriptor()->FindMethodByName("Foo");
    +  //   Message* request  = stub->GetRequestPrototype (method)->New();
    +  //   Message* response = stub->GetResponsePrototype(method)->New();
    +  //   request->ParseFromString(input);
    +  //   service->CallMethod(method, *request, response, callback);
    +  virtual const Message& GetRequestPrototype(
    +    const MethodDescriptor* method) const = 0;
    +  virtual const Message& GetResponsePrototype(
    +    const MethodDescriptor* method) const = 0;
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service);
    +};
    +
    +// An RpcController mediates a single method call.  The primary purpose of
    +// the controller is to provide a way to manipulate settings specific to the
    +// RPC implementation and to find out about RPC-level errors.
    +//
    +// The methods provided by the RpcController interface are intended to be a
    +// "least common denominator" set of features which we expect all
    +// implementations to support.  Specific implementations may provide more
    +// advanced features (e.g. deadline propagation).
    +class LIBPROTOBUF_EXPORT RpcController {
    + public:
    +  inline RpcController() {}
    +  virtual ~RpcController();
    +
    +  // Client-side methods ---------------------------------------------
    +  // These calls may be made from the client side only.  Their results
    +  // are undefined on the server side (may crash).
    +
    +  // Resets the RpcController to its initial state so that it may be reused in
    +  // a new call.  Must not be called while an RPC is in progress.
    +  virtual void Reset() = 0;
    +
    +  // After a call has finished, returns true if the call failed.  The possible
    +  // reasons for failure depend on the RPC implementation.  Failed() must not
    +  // be called before a call has finished.  If Failed() returns true, the
    +  // contents of the response message are undefined.
    +  virtual bool Failed() const = 0;
    +
    +  // If Failed() is true, returns a human-readable description of the error.
    +  virtual string ErrorText() const = 0;
    +
    +  // Advises the RPC system that the caller desires that the RPC call be
    +  // canceled.  The RPC system may cancel it immediately, may wait awhile and
    +  // then cancel it, or may not even cancel the call at all.  If the call is
    +  // canceled, the "done" callback will still be called and the RpcController
    +  // will indicate that the call failed at that time.
    +  virtual void StartCancel() = 0;
    +
    +  // Server-side methods ---------------------------------------------
    +  // These calls may be made from the server side only.  Their results
    +  // are undefined on the client side (may crash).
    +
    +  // Causes Failed() to return true on the client side.  "reason" will be
    +  // incorporated into the message returned by ErrorText().  If you find
    +  // you need to return machine-readable information about failures, you
    +  // should incorporate it into your response protocol buffer and should
    +  // NOT call SetFailed().
    +  virtual void SetFailed(const string& reason) = 0;
    +
    +  // If true, indicates that the client canceled the RPC, so the server may
    +  // as well give up on replying to it.  The server should still call the
    +  // final "done" callback.
    +  virtual bool IsCanceled() const = 0;
    +
    +  // Asks that the given callback be called when the RPC is canceled.  The
    +  // callback will always be called exactly once.  If the RPC completes without
    +  // being canceled, the callback will be called after completion.  If the RPC
    +  // has already been canceled when NotifyOnCancel() is called, the callback
    +  // will be called immediately.
    +  //
    +  // NotifyOnCancel() must be called no more than once per request.
    +  virtual void NotifyOnCancel(Closure* callback) = 0;
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController);
    +};
    +
    +// Abstract interface for an RPC channel.  An RpcChannel represents a
    +// communication line to a Service which can be used to call that Service's
    +// methods.  The Service may be running on another machine.  Normally, you
    +// should not call an RpcChannel directly, but instead construct a stub Service
    +// wrapping it.  Example:
    +//   RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");
    +//   MyService* service = new MyService::Stub(channel);
    +//   service->MyMethod(request, &response, callback);
    +class LIBPROTOBUF_EXPORT RpcChannel {
    + public:
    +  inline RpcChannel() {}
    +  virtual ~RpcChannel();
    +
    +  // Call the given method of the remote service.  The signature of this
    +  // procedure looks the same as Service::CallMethod(), but the requirements
    +  // are less strict in one important way:  the request and response objects
    +  // need not be of any specific class as long as their descriptors are
    +  // method->input_type() and method->output_type().
    +  virtual void CallMethod(const MethodDescriptor* method,
    +                          RpcController* controller,
    +                          const Message* request,
    +                          Message* response,
    +                          Closure* done) = 0;
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel);
    +};
    +
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_SERVICE_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops.h
    new file mode 100644
    index 000000000000..b1336e36b93d
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops.h
    @@ -0,0 +1,227 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// The routines exported by this module are subtle.  If you use them, even if
    +// you get the code right, it will depend on careful reasoning about atomicity
    +// and memory ordering; it will be less readable, and harder to maintain.  If
    +// you plan to use these routines, you should have a good reason, such as solid
    +// evidence that performance would otherwise suffer, or there being no
    +// alternative.  You should assume only properties explicitly guaranteed by the
    +// specifications in this file.  You are almost certainly _not_ writing code
    +// just for the x86; if you assume x86 semantics, x86 hardware bugs and
    +// implementations on other archtectures will cause your code to break.  If you
    +// do not know what you are doing, avoid these routines, and use a Mutex.
    +//
    +// It is incorrect to make direct assignments to/from an atomic variable.
    +// You should use one of the Load or Store routines.  The NoBarrier
    +// versions are provided when no barriers are needed:
    +//   NoBarrier_Store()
    +//   NoBarrier_Load()
    +// Although there are currently no compiler enforcement, you are encouraged
    +// to use these.
    +
    +// This header and the implementations for each platform (located in
    +// atomicops_internals_*) must be kept in sync with the upstream code (V8).
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_H_
    +
    +// Don't include this file for people not concerned about thread safety.
    +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +typedef int32 Atomic32;
    +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
    +// We need to be able to go between Atomic64 and AtomicWord implicitly.  This
    +// means Atomic64 and AtomicWord should be the same type on 64-bit.
    +#if defined(__ILP32__) || defined(GOOGLE_PROTOBUF_OS_NACL) || defined(GOOGLE_PROTOBUF_ARCH_SPARC)
    +// NaCl's intptr_t is not actually 64-bits on 64-bit!
    +// http://code.google.com/p/nativeclient/issues/detail?id=1162
    +// sparcv9's pointer type is 32bits
    +typedef int64 Atomic64;
    +#else
    +typedef intptr_t Atomic64;
    +#endif
    +#endif
    +
    +// Use AtomicWord for a machine-sized pointer.  It will use the Atomic32 or
    +// Atomic64 routines below, depending on your architecture.
    +typedef intptr_t AtomicWord;
    +
    +// Atomically execute:
    +//      result = *ptr;
    +//      if (*ptr == old_value)
    +//        *ptr = new_value;
    +//      return result;
    +//
    +// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
    +// Always return the old value of "*ptr"
    +//
    +// This routine implies no memory barriers.
    +Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                  Atomic32 old_value,
    +                                  Atomic32 new_value);
    +
    +// Atomically store new_value into *ptr, returning the previous value held in
    +// *ptr.  This routine implies no memory barriers.
    +Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
    +
    +// Atomically increment *ptr by "increment".  Returns the new value of
    +// *ptr with the increment applied.  This routine implies no memory barriers.
    +Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
    +
    +Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                 Atomic32 increment);
    +
    +// These following lower-level operations are typically useful only to people
    +// implementing higher-level synchronization operations like spinlocks,
    +// mutexes, and condition-variables.  They combine CompareAndSwap(), a load, or
    +// a store with appropriate memory-ordering instructions.  "Acquire" operations
    +// ensure that no later memory access can be reordered ahead of the operation.
    +// "Release" operations ensure that no previous memory access can be reordered
    +// after the operation.  "Barrier" operations have both "Acquire" and "Release"
    +// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
    +// access.
    +Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                Atomic32 old_value,
    +                                Atomic32 new_value);
    +Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                Atomic32 old_value,
    +                                Atomic32 new_value);
    +
    +#if defined(__MINGW32__) && defined(MemoryBarrier)
    +#undef MemoryBarrier
    +#endif
    +void MemoryBarrier();
    +void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
    +void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
    +void Release_Store(volatile Atomic32* ptr, Atomic32 value);
    +
    +Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
    +Atomic32 Acquire_Load(volatile const Atomic32* ptr);
    +Atomic32 Release_Load(volatile const Atomic32* ptr);
    +
    +// 64-bit atomic operations (only available on 64-bit processors).
    +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
    +Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                  Atomic64 old_value,
    +                                  Atomic64 new_value);
    +Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
    +Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
    +Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
    +
    +Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                Atomic64 old_value,
    +                                Atomic64 new_value);
    +Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
    +                                Atomic64 old_value,
    +                                Atomic64 new_value);
    +void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
    +void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
    +void Release_Store(volatile Atomic64* ptr, Atomic64 value);
    +Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
    +Atomic64 Acquire_Load(volatile const Atomic64* ptr);
    +Atomic64 Release_Load(volatile const Atomic64* ptr);
    +#endif  // GOOGLE_PROTOBUF_ARCH_64_BIT
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +// Include our platform specific implementation.
    +#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
    +#error "Atomic operations are not supported on your platform"
    +
    +// ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html.
    +#if defined(THREAD_SANITIZER)
    +#include 
    +// MSVC.
    +#elif defined(_MSC_VER)
    +#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
    +#include 
    +#else
    +GOOGLE_PROTOBUF_ATOMICOPS_ERROR
    +#endif
    +
    +// Solaris
    +#elif defined(GOOGLE_PROTOBUF_OS_SOLARIS)
    +#include 
    +
    +// Apple.
    +#elif defined(GOOGLE_PROTOBUF_OS_APPLE)
    +#include 
    +
    +// GCC.
    +#elif defined(__GNUC__)
    +#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
    +#include 
    +#elif defined(GOOGLE_PROTOBUF_ARCH_ARM) && defined(__linux__)
    +#include 
    +#elif defined(GOOGLE_PROTOBUF_ARCH_AARCH64)
    +#include 
    +#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX)
    +#include 
    +#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS) || defined(GOOGLE_PROTOBUF_ARCH_MIPS64)
    +#include 
    +#elif defined(__native_client__)
    +#include 
    +#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
    +#include 
    +#elif defined(__clang__)
    +#if __has_extension(c_atomic)
    +#include 
    +#else
    +GOOGLE_PROTOBUF_ATOMICOPS_ERROR
    +#endif
    +#else
    +GOOGLE_PROTOBUF_ATOMICOPS_ERROR
    +#endif
    +
    +// Unknown.
    +#else
    +GOOGLE_PROTOBUF_ATOMICOPS_ERROR
    +#endif
    +
    +// On some platforms we need additional declarations to make AtomicWord
    +// compatible with our other Atomic* types.
    +#if defined(GOOGLE_PROTOBUF_OS_APPLE)
    +#include 
    +#endif
    +
    +#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR
    +
    +#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
    new file mode 100644
    index 000000000000..0a2d2b894b84
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
    @@ -0,0 +1,325 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline void MemoryBarrier() {
    +  __asm__ __volatile__ ("dmb ish" ::: "memory");  // NOLINT
    +}
    +
    +// NoBarrier versions of the operation include "memory" in the clobber list.
    +// This is not required for direct usage of the NoBarrier versions of the
    +// operations. However this is required for correctness when they are used as
    +// part of the Acquire or Release versions, to ensure that nothing from outside
    +// the call is reordered between the operation and the memory barrier. This does
    +// not change the code generated, so has no or minimal impact on the
    +// NoBarrier operations.
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  Atomic32 prev;
    +  int32_t temp;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "0:                                    \n\t"
    +    "ldxr %w[prev], %[ptr]                 \n\t"  // Load the previous value.
    +    "cmp %w[prev], %w[old_value]           \n\t"
    +    "bne 1f                                \n\t"
    +    "stxr %w[temp], %w[new_value], %[ptr]  \n\t"  // Try to store the new value.
    +    "cbnz %w[temp], 0b                     \n\t"  // Retry if it did not work.
    +    "1:                                    \n\t"
    +    : [prev]"=&r" (prev),
    +      [temp]"=&r" (temp),
    +      [ptr]"+Q" (*ptr)
    +    : [old_value]"IJr" (old_value),
    +      [new_value]"r" (new_value)
    +    : "cc", "memory"
    +  );  // NOLINT
    +
    +  return prev;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  Atomic32 result;
    +  int32_t temp;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "0:                                    \n\t"
    +    "ldxr %w[result], %[ptr]               \n\t"  // Load the previous value.
    +    "stxr %w[temp], %w[new_value], %[ptr]  \n\t"  // Try to store the new value.
    +    "cbnz %w[temp], 0b                     \n\t"  // Retry if it did not work.
    +    : [result]"=&r" (result),
    +      [temp]"=&r" (temp),
    +      [ptr]"+Q" (*ptr)
    +    : [new_value]"r" (new_value)
    +    : "memory"
    +  );  // NOLINT
    +
    +  return result;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  Atomic32 result;
    +  int32_t temp;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "0:                                       \n\t"
    +    "ldxr %w[result], %[ptr]                  \n\t"  // Load the previous value.
    +    "add %w[result], %w[result], %w[increment]\n\t"
    +    "stxr %w[temp], %w[result], %[ptr]        \n\t"  // Try to store the result.
    +    "cbnz %w[temp], 0b                        \n\t"  // Retry on failure.
    +    : [result]"=&r" (result),
    +      [temp]"=&r" (temp),
    +      [ptr]"+Q" (*ptr)
    +    : [increment]"IJr" (increment)
    +    : "memory"
    +  );  // NOLINT
    +
    +  return result;
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                        Atomic32 increment) {
    +  MemoryBarrier();
    +  Atomic32 result = NoBarrier_AtomicIncrement(ptr, increment);
    +  MemoryBarrier();
    +
    +  return result;
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  MemoryBarrier();
    +
    +  return prev;
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  MemoryBarrier();
    +  Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +
    +  return prev;
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  __asm__ __volatile__ (  // NOLINT
    +    "stlr %w[value], %[ptr]  \n\t"
    +    : [ptr]"=Q" (*ptr)
    +    : [value]"r" (value)
    +    : "memory"
    +  );  // NOLINT
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "ldar %w[value], %[ptr]  \n\t"
    +    : [value]"=r" (value)
    +    : [ptr]"Q" (*ptr)
    +    : "memory"
    +  );  // NOLINT
    +
    +  return value;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +// 64-bit versions of the operations.
    +// See the 32-bit versions for comments.
    +
    +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                         Atomic64 old_value,
    +                                         Atomic64 new_value) {
    +  Atomic64 prev;
    +  int32_t temp;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "0:                                    \n\t"
    +    "ldxr %[prev], %[ptr]                  \n\t"
    +    "cmp %[prev], %[old_value]             \n\t"
    +    "bne 1f                                \n\t"
    +    "stxr %w[temp], %[new_value], %[ptr]   \n\t"
    +    "cbnz %w[temp], 0b                     \n\t"
    +    "1:                                    \n\t"
    +    : [prev]"=&r" (prev),
    +      [temp]"=&r" (temp),
    +      [ptr]"+Q" (*ptr)
    +    : [old_value]"IJr" (old_value),
    +      [new_value]"r" (new_value)
    +    : "cc", "memory"
    +  );  // NOLINT
    +
    +  return prev;
    +}
    +
    +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
    +                                         Atomic64 new_value) {
    +  Atomic64 result;
    +  int32_t temp;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "0:                                    \n\t"
    +    "ldxr %[result], %[ptr]                \n\t"
    +    "stxr %w[temp], %[new_value], %[ptr]   \n\t"
    +    "cbnz %w[temp], 0b                     \n\t"
    +    : [result]"=&r" (result),
    +      [temp]"=&r" (temp),
    +      [ptr]"+Q" (*ptr)
    +    : [new_value]"r" (new_value)
    +    : "memory"
    +  );  // NOLINT
    +
    +  return result;
    +}
    +
    +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                          Atomic64 increment) {
    +  Atomic64 result;
    +  int32_t temp;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "0:                                     \n\t"
    +    "ldxr %[result], %[ptr]                 \n\t"
    +    "add %[result], %[result], %[increment] \n\t"
    +    "stxr %w[temp], %[result], %[ptr]       \n\t"
    +    "cbnz %w[temp], 0b                      \n\t"
    +    : [result]"=&r" (result),
    +      [temp]"=&r" (temp),
    +      [ptr]"+Q" (*ptr)
    +    : [increment]"IJr" (increment)
    +    : "memory"
    +  );  // NOLINT
    +
    +  return result;
    +}
    +
    +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                        Atomic64 increment) {
    +  MemoryBarrier();
    +  Atomic64 result = NoBarrier_AtomicIncrement(ptr, increment);
    +  MemoryBarrier();
    +
    +  return result;
    +}
    +
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  MemoryBarrier();
    +
    +  return prev;
    +}
    +
    +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  MemoryBarrier();
    +  Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +
    +  return prev;
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  __asm__ __volatile__ (  // NOLINT
    +    "stlr %x[value], %[ptr]  \n\t"
    +    : [ptr]"=Q" (*ptr)
    +    : [value]"r" (value)
    +    : "memory"
    +  );  // NOLINT
    +}
    +
    +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
    +  Atomic64 value;
    +
    +  __asm__ __volatile__ (  // NOLINT
    +    "ldar %x[value], %[ptr]  \n\t"
    +    : [value]"=r" (value)
    +    : [ptr]"Q" (*ptr)
    +    : "memory"
    +  );  // NOLINT
    +
    +  return value;
    +}
    +
    +inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
    new file mode 100644
    index 000000000000..90e727b0bc56
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
    @@ -0,0 +1,151 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +//
    +// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// 0xffff0fc0 is the hard coded address of a function provided by
    +// the kernel which implements an atomic compare-exchange. On older
    +// ARM architecture revisions (pre-v6) this may be implemented using
    +// a syscall. This address is stable, and in active use (hard coded)
    +// by at least glibc-2.7 and the Android C library.
    +typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
    +                                           Atomic32 new_value,
    +                                           volatile Atomic32* ptr);
    +LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =
    +    (LinuxKernelCmpxchgFunc) 0xffff0fc0;
    +
    +typedef void (*LinuxKernelMemoryBarrierFunc)(void);
    +LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
    +    (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
    +
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  Atomic32 prev_value = *ptr;
    +  do {
    +    if (!pLinuxKernelCmpxchg(old_value, new_value,
    +                             const_cast(ptr))) {
    +      return old_value;
    +    }
    +    prev_value = *ptr;
    +  } while (prev_value == old_value);
    +  return prev_value;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  Atomic32 old_value;
    +  do {
    +    old_value = *ptr;
    +  } while (pLinuxKernelCmpxchg(old_value, new_value,
    +                               const_cast(ptr)));
    +  return old_value;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  return Barrier_AtomicIncrement(ptr, increment);
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                        Atomic32 increment) {
    +  for (;;) {
    +    // Atomic exchange the old value with an incremented one.
    +    Atomic32 old_value = *ptr;
    +    Atomic32 new_value = old_value + increment;
    +    if (pLinuxKernelCmpxchg(old_value, new_value,
    +                            const_cast(ptr)) == 0) {
    +      // The exchange took place as expected.
    +      return new_value;
    +    }
    +    // Otherwise, *ptr changed mid-loop and we need to retry.
    +  }
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +inline void MemoryBarrier() {
    +  pLinuxKernelMemoryBarrier();
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  MemoryBarrier();
    +  *ptr = value;
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value = *ptr;
    +  MemoryBarrier();
    +  return value;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
    new file mode 100644
    index 000000000000..17dfaa518239
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
    @@ -0,0 +1,146 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
    +
    +// For _smp_cmpxchg()
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline Atomic32 QNXCmpxchg(Atomic32 old_value,
    +                           Atomic32 new_value,
    +                           volatile Atomic32* ptr) {
    +  return static_cast(
    +      _smp_cmpxchg((volatile unsigned *)ptr,
    +                   (unsigned)old_value,
    +                   (unsigned)new_value));
    +}
    +
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  Atomic32 prev_value = *ptr;
    +  do {
    +    if (!QNXCmpxchg(old_value, new_value,
    +                    const_cast(ptr))) {
    +      return old_value;
    +    }
    +    prev_value = *ptr;
    +  } while (prev_value == old_value);
    +  return prev_value;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  Atomic32 old_value;
    +  do {
    +    old_value = *ptr;
    +  } while (QNXCmpxchg(old_value, new_value,
    +                      const_cast(ptr)));
    +  return old_value;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  return Barrier_AtomicIncrement(ptr, increment);
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                        Atomic32 increment) {
    +  for (;;) {
    +    // Atomic exchange the old value with an incremented one.
    +    Atomic32 old_value = *ptr;
    +    Atomic32 new_value = old_value + increment;
    +    if (QNXCmpxchg(old_value, new_value,
    +                   const_cast(ptr)) == 0) {
    +      // The exchange took place as expected.
    +      return new_value;
    +    }
    +    // Otherwise, *ptr changed mid-loop and we need to retry.
    +  }
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +inline void MemoryBarrier() {
    +  __sync_synchronize();
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  MemoryBarrier();
    +  *ptr = value;
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value = *ptr;
    +  MemoryBarrier();
    +  return value;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
    new file mode 100644
    index 000000000000..eb198ff5cc23
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
    @@ -0,0 +1,122 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
    +
    +// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32,
    +// which in turn means int. On some LP32 platforms, intptr_t is an int, but
    +// on others, it's a long. When AtomicWord and Atomic32 are based on different
    +// fundamental types, their pointers are incompatible.
    +//
    +// This file defines function overloads to allow both AtomicWord and Atomic32
    +// data to be used with this interface.
    +//
    +// On LP64 platforms, AtomicWord and Atomic64 are both always long,
    +// so this problem doesn't occur.
    +
    +#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
    +                                           AtomicWord old_value,
    +                                           AtomicWord new_value) {
    +  return NoBarrier_CompareAndSwap(
    +      reinterpret_cast(ptr), old_value, new_value);
    +}
    +
    +inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
    +                                           AtomicWord new_value) {
    +  return NoBarrier_AtomicExchange(
    +      reinterpret_cast(ptr), new_value);
    +}
    +
    +inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
    +                                            AtomicWord increment) {
    +  return NoBarrier_AtomicIncrement(
    +      reinterpret_cast(ptr), increment);
    +}
    +
    +inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
    +                                          AtomicWord increment) {
    +  return Barrier_AtomicIncrement(
    +      reinterpret_cast(ptr), increment);
    +}
    +
    +inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
    +                                         AtomicWord old_value,
    +                                         AtomicWord new_value) {
    +  return Acquire_CompareAndSwap(
    +      reinterpret_cast(ptr), old_value, new_value);
    +}
    +
    +inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
    +                                         AtomicWord old_value,
    +                                         AtomicWord new_value) {
    +  return Release_CompareAndSwap(
    +      reinterpret_cast(ptr), old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
    +  NoBarrier_Store(reinterpret_cast(ptr), value);
    +}
    +
    +inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
    +  return Acquire_Store(reinterpret_cast(ptr), value);
    +}
    +
    +inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
    +  return Release_Store(reinterpret_cast(ptr), value);
    +}
    +
    +inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
    +  return NoBarrier_Load(reinterpret_cast(ptr));
    +}
    +
    +inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
    +  return Acquire_Load(reinterpret_cast(ptr));
    +}
    +
    +inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
    +  return Release_Load(reinterpret_cast(ptr));
    +}
    +
    +}   // namespace internal
    +}   // namespace protobuf
    +}   // namespace google
    +
    +#endif  // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
    new file mode 100644
    index 000000000000..dd7abf6f1754
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
    @@ -0,0 +1,137 @@
    +// Copyright 2013 Red Hat Inc.  All rights reserved.
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Red Hat Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
    +                              __ATOMIC_RELAXED, __ATOMIC_RELAXED);
    +  return old_value;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                        Atomic32 increment) {
    +  return __atomic_add_fetch(ptr, increment, __ATOMIC_SEQ_CST);
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  __atomic_compare_exchange(ptr, &old_value, &new_value, true,
    +                            __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
    +  return old_value;
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
    +                              __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
    +  return old_value;
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  __atomic_store_n(ptr, value, __ATOMIC_RELAXED);
    +}
    +
    +inline void MemoryBarrier() {
    +  __sync_synchronize();
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST);
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return __atomic_load_n(ptr, __ATOMIC_RELAXED);
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
    +}
    +
    +#ifdef __LP64__
    +
    +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
    +  return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
    +}
    +
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
    +                              __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
    +  return old_value;
    +}
    +
    +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                         Atomic64 old_value,
    +                                         Atomic64 new_value) {
    +  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
    +                              __ATOMIC_RELAXED, __ATOMIC_RELAXED);
    +  return old_value;
    +}
    +
    +#endif // defined(__LP64__)
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h
    new file mode 100644
    index 000000000000..796332417feb
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h
    @@ -0,0 +1,225 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  Atomic32 prev_value;
    +  do {
    +    if (OSAtomicCompareAndSwap32(old_value, new_value,
    +                                 const_cast(ptr))) {
    +      return old_value;
    +    }
    +    prev_value = *ptr;
    +  } while (prev_value == old_value);
    +  return prev_value;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  Atomic32 old_value;
    +  do {
    +    old_value = *ptr;
    +  } while (!OSAtomicCompareAndSwap32(old_value, new_value,
    +                                     const_cast(ptr)));
    +  return old_value;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  return OSAtomicAdd32(increment, const_cast(ptr));
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  return OSAtomicAdd32Barrier(increment, const_cast(ptr));
    +}
    +
    +inline void MemoryBarrier() {
    +  OSMemoryBarrier();
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  Atomic32 prev_value;
    +  do {
    +    if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
    +                                        const_cast(ptr))) {
    +      return old_value;
    +    }
    +    prev_value = *ptr;
    +  } while (prev_value == old_value);
    +  return prev_value;
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return Acquire_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  MemoryBarrier();
    +  *ptr = value;
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value = *ptr;
    +  MemoryBarrier();
    +  return value;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +#ifdef __LP64__
    +
    +// 64-bit implementation on 64-bit platform
    +
    +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                         Atomic64 old_value,
    +                                         Atomic64 new_value) {
    +  Atomic64 prev_value;
    +  do {
    +    if (OSAtomicCompareAndSwap64(old_value, new_value,
    +                                 reinterpret_cast(ptr))) {
    +      return old_value;
    +    }
    +    prev_value = *ptr;
    +  } while (prev_value == old_value);
    +  return prev_value;
    +}
    +
    +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
    +                                         Atomic64 new_value) {
    +  Atomic64 old_value;
    +  do {
    +    old_value = *ptr;
    +  } while (!OSAtomicCompareAndSwap64(old_value, new_value,
    +                                     reinterpret_cast(ptr)));
    +  return old_value;
    +}
    +
    +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                          Atomic64 increment) {
    +  return OSAtomicAdd64(increment, reinterpret_cast(ptr));
    +}
    +
    +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                        Atomic64 increment) {
    +  return OSAtomicAdd64Barrier(increment,
    +                              reinterpret_cast(ptr));
    +}
    +
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  Atomic64 prev_value;
    +  do {
    +    if (OSAtomicCompareAndSwap64Barrier(
    +        old_value, new_value, reinterpret_cast(ptr))) {
    +      return old_value;
    +    }
    +    prev_value = *ptr;
    +  } while (prev_value == old_value);
    +  return prev_value;
    +}
    +
    +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  // The lib kern interface does not distinguish between
    +  // Acquire and Release memory barriers; they are equivalent.
    +  return Acquire_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  MemoryBarrier();
    +  *ptr = value;
    +}
    +
    +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
    +  Atomic64 value = *ptr;
    +  MemoryBarrier();
    +  return value;
    +}
    +
    +inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +#endif  // defined(__LP64__)
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
    new file mode 100644
    index 000000000000..e3cd14cf8019
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
    @@ -0,0 +1,313 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
    +
    +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// Atomically execute:
    +//      result = *ptr;
    +//      if (*ptr == old_value)
    +//        *ptr = new_value;
    +//      return result;
    +//
    +// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
    +// Always return the old value of "*ptr"
    +//
    +// This routine implies no memory barriers.
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  Atomic32 prev, tmp;
    +  __asm__ __volatile__(".set push\n"
    +                       ".set noreorder\n"
    +                       "1:\n"
    +                       "ll %0, %5\n"  // prev = *ptr
    +                       "bne %0, %3, 2f\n"  // if (prev != old_value) goto 2
    +                       "move %2, %4\n"  // tmp = new_value
    +                       "sc %2, %1\n"  // *ptr = tmp (with atomic check)
    +                       "beqz %2, 1b\n"  // start again on atomic error
    +                       "nop\n"  // delay slot nop
    +                       "2:\n"
    +                       ".set pop\n"
    +                       : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
    +                       : "Ir" (old_value), "r" (new_value), "m" (*ptr)
    +                       : "memory");
    +  return prev;
    +}
    +
    +// Atomically store new_value into *ptr, returning the previous value held in
    +// *ptr.  This routine implies no memory barriers.
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  Atomic32 temp, old;
    +  __asm__ __volatile__(".set push\n"
    +                       ".set noreorder\n"
    +                       "1:\n"
    +                       "ll %1, %4\n"  // old = *ptr
    +                       "move %0, %3\n"  // temp = new_value
    +                       "sc %0, %2\n"  // *ptr = temp (with atomic check)
    +                       "beqz %0, 1b\n"  // start again on atomic error
    +                       "nop\n"  // delay slot nop
    +                       ".set pop\n"
    +                       : "=&r" (temp), "=&r" (old), "=m" (*ptr)
    +                       : "r" (new_value), "m" (*ptr)
    +                       : "memory");
    +
    +  return old;
    +}
    +
    +// Atomically increment *ptr by "increment".  Returns the new value of
    +// *ptr with the increment applied.  This routine implies no memory barriers.
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  Atomic32 temp, temp2;
    +
    +  __asm__ __volatile__(".set push\n"
    +                       ".set noreorder\n"
    +                       "1:\n"
    +                       "ll %0, %4\n"  // temp = *ptr
    +                       "addu %1, %0, %3\n"  // temp2 = temp + increment
    +                       "sc %1, %2\n"  // *ptr = temp2 (with atomic check)
    +                       "beqz %1, 1b\n"  // start again on atomic error
    +                       "addu %1, %0, %3\n"  // temp2 = temp + increment
    +                       ".set pop\n"
    +                       : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
    +                       : "Ir" (increment), "m" (*ptr)
    +                       : "memory");
    +  // temp2 now holds the final value.
    +  return temp2;
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                        Atomic32 increment) {
    +  ATOMICOPS_COMPILER_BARRIER();
    +  Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
    +  ATOMICOPS_COMPILER_BARRIER();
    +  return res;
    +}
    +
    +// "Acquire" operations
    +// ensure that no later memory access can be reordered ahead of the operation.
    +// "Release" operations ensure that no previous memory access can be reordered
    +// after the operation.  "Barrier" operations have both "Acquire" and "Release"
    +// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
    +// access.
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  ATOMICOPS_COMPILER_BARRIER();
    +  Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  ATOMICOPS_COMPILER_BARRIER();
    +  return res;
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  ATOMICOPS_COMPILER_BARRIER();
    +  Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  ATOMICOPS_COMPILER_BARRIER();
    +  return res;
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +inline void MemoryBarrier() {
    +  __asm__ __volatile__("sync" : : : "memory");
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  MemoryBarrier();
    +  *ptr = value;
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value = *ptr;
    +  MemoryBarrier();
    +  return value;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +#if defined(__LP64__)
    +// 64-bit versions of the atomic ops.
    +
    +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                         Atomic64 old_value,
    +                                         Atomic64 new_value) {
    +  Atomic64 prev, tmp;
    +  __asm__ __volatile__(".set push\n"
    +                       ".set noreorder\n"
    +                       "1:\n"
    +                       "lld %0, %5\n"  // prev = *ptr
    +                       "bne %0, %3, 2f\n"  // if (prev != old_value) goto 2
    +                       "move %2, %4\n"  // tmp = new_value
    +                       "scd %2, %1\n"  // *ptr = tmp (with atomic check)
    +                       "beqz %2, 1b\n"  // start again on atomic error
    +                       "nop\n"  // delay slot nop
    +                       "2:\n"
    +                       ".set pop\n"
    +                       : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
    +                       : "Ir" (old_value), "r" (new_value), "m" (*ptr)
    +                       : "memory");
    +  return prev;
    +}
    +
    +// Atomically store new_value into *ptr, returning the previous value held in
    +// *ptr.  This routine implies no memory barriers.
    +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
    +                                         Atomic64 new_value) {
    +  Atomic64 temp, old;
    +  __asm__ __volatile__(".set push\n"
    +                       ".set noreorder\n"
    +                       "1:\n"
    +                       "lld %1, %4\n"  // old = *ptr
    +                       "move %0, %3\n"  // temp = new_value
    +                       "scd %0, %2\n"  // *ptr = temp (with atomic check)
    +                       "beqz %0, 1b\n"  // start again on atomic error
    +                       "nop\n"  // delay slot nop
    +                       ".set pop\n"
    +                       : "=&r" (temp), "=&r" (old), "=m" (*ptr)
    +                       : "r" (new_value), "m" (*ptr)
    +                       : "memory");
    +
    +  return old;
    +}
    +
    +// Atomically increment *ptr by "increment".  Returns the new value of
    +// *ptr with the increment applied.  This routine implies no memory barriers.
    +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                          Atomic64 increment) {
    +  Atomic64 temp, temp2;
    +
    +  __asm__ __volatile__(".set push\n"
    +                       ".set noreorder\n"
    +                       "1:\n"
    +                       "lld %0, %4\n"  // temp = *ptr
    +                       "daddu %1, %0, %3\n"  // temp2 = temp + increment
    +                       "scd %1, %2\n"  // *ptr = temp2 (with atomic check)
    +                       "beqz %1, 1b\n"  // start again on atomic error
    +                       "daddu %1, %0, %3\n"  // temp2 = temp + increment
    +                       ".set pop\n"
    +                       : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
    +                       : "Ir" (increment), "m" (*ptr)
    +                       : "memory");
    +  // temp2 now holds the final value.
    +  return temp2;
    +}
    +
    +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                        Atomic64 increment) {
    +  MemoryBarrier();
    +  Atomic64 res = NoBarrier_AtomicIncrement(ptr, increment);
    +  MemoryBarrier();
    +  return res;
    +}
    +
    +// "Acquire" operations
    +// ensure that no later memory access can be reordered ahead of the operation.
    +// "Release" operations ensure that no previous memory access can be reordered
    +// after the operation.  "Barrier" operations have both "Acquire" and "Release"
    +// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
    +// access.
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  MemoryBarrier();
    +  return res;
    +}
    +
    +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  MemoryBarrier();
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  MemoryBarrier();
    +  *ptr = value;
    +}
    +
    +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
    +  Atomic64 value = *ptr;
    +  MemoryBarrier();
    +  return value;
    +}
    +
    +inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +#endif
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#undef ATOMICOPS_COMPILER_BARRIER
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h
    new file mode 100644
    index 000000000000..b10ac02c4077
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h
    @@ -0,0 +1,73 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  return __sync_val_compare_and_swap(ptr, old_value, new_value);
    +}
    +
    +inline void MemoryBarrier() {
    +  __sync_synchronize();
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  MemoryBarrier();
    +  return ret;
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  MemoryBarrier();
    +  *ptr = value;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value = *ptr;
    +  MemoryBarrier();
    +  return value;
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h
    new file mode 100644
    index 000000000000..d8057ecdeabf
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h
    @@ -0,0 +1,188 @@
    +// Copyright 2014 Google Inc. All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  return (Atomic32)atomic_cas_32((volatile uint32_t*)ptr, (uint32_t)old_value, (uint32_t)new_value);
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  return (Atomic32)atomic_swap_32((volatile uint32_t*)ptr, (uint32_t)new_value);
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  return (Atomic32)atomic_add_32_nv((volatile uint32_t*)ptr, (uint32_t)increment);
    +}
    +
    +inline void MemoryBarrier(void) {
    +	membar_producer();
    +	membar_consumer();
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                        Atomic32 increment) {
    +  MemoryBarrier();
    +  Atomic32 ret = NoBarrier_AtomicIncrement(ptr, increment);
    +  MemoryBarrier();
    +
    +  return ret;
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  MemoryBarrier();
    +
    +  return ret;
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  MemoryBarrier();
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +  membar_producer();
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  membar_consumer();
    +  *ptr = value;
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 val = *ptr;
    +  membar_consumer();
    +  return val;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  membar_producer();
    +  return *ptr;
    +}
    +
    +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
    +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                         Atomic64 old_value,
    +                                         Atomic64 new_value) {
    +  return atomic_cas_64((volatile uint64_t*)ptr, (uint64_t)old_value, (uint64_t)new_value);
    +}
    +
    +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value) {
    +  return atomic_swap_64((volatile uint64_t*)ptr, (uint64_t)new_value);
    +}
    +
    +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
    +  return atomic_add_64_nv((volatile uint64_t*)ptr, increment);
    +}
    +
    +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
    +  MemoryBarrier();
    +  Atomic64 ret = atomic_add_64_nv((volatile uint64_t*)ptr, increment);
    +  MemoryBarrier();
    +  return ret;
    +}
    +
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  Atomic64 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  MemoryBarrier();
    +  return ret;
    +}
    +
    +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  MemoryBarrier();
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +  membar_producer();
    +}
    +
    +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  membar_consumer();
    +  *ptr = value;
    +}
    +
    +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
    +  Atomic64 ret = *ptr;
    +  membar_consumer();
    +  return ret;
    +}
    +
    +inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
    +  membar_producer();
    +  return *ptr;
    +}
    +#endif
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
    +
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h
    new file mode 100644
    index 000000000000..0c903545cd34
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h
    @@ -0,0 +1,219 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2013 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation for compiler-based
    +// ThreadSanitizer (http://clang.llvm.org/docs/ThreadSanitizer.html).
    +// Use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
    +
    +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  Atomic32 cmp = old_value;
    +  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
    +      __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
    +  return cmp;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
    +                                         Atomic32 new_value) {
    +  return __tsan_atomic32_exchange(ptr, new_value,
    +      __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
    +                                       Atomic32 new_value) {
    +  return __tsan_atomic32_exchange(ptr, new_value,
    +      __tsan_memory_order_acquire);
    +}
    +
    +inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
    +                                       Atomic32 new_value) {
    +  return __tsan_atomic32_exchange(ptr, new_value,
    +      __tsan_memory_order_release);
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
    +                                          Atomic32 increment) {
    +  return increment + __tsan_atomic32_fetch_add(ptr, increment,
    +      __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
    +                                        Atomic32 increment) {
    +  return increment + __tsan_atomic32_fetch_add(ptr, increment,
    +      __tsan_memory_order_acq_rel);
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  Atomic32 cmp = old_value;
    +  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
    +      __tsan_memory_order_acquire, __tsan_memory_order_acquire);
    +  return cmp;
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  Atomic32 cmp = old_value;
    +  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
    +      __tsan_memory_order_release, __tsan_memory_order_relaxed);
    +  return cmp;
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
    +  __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
    +}
    +
    +inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
    +  __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
    +  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
    +}
    +
    +inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
    +  __tsan_atomic32_store(ptr, value, __tsan_memory_order_release);
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {
    +  return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
    +  return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire);
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
    +  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
    +  return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
    +                                         Atomic64 old_value,
    +                                         Atomic64 new_value) {
    +  Atomic64 cmp = old_value;
    +  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
    +      __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
    +  return cmp;
    +}
    +
    +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
    +                                         Atomic64 new_value) {
    +  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
    +                                       Atomic64 new_value) {
    +  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_acquire);
    +}
    +
    +inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
    +                                       Atomic64 new_value) {
    +  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_release);
    +}
    +
    +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
    +                                          Atomic64 increment) {
    +  return increment + __tsan_atomic64_fetch_add(ptr, increment,
    +      __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
    +                                        Atomic64 increment) {
    +  return increment + __tsan_atomic64_fetch_add(ptr, increment,
    +      __tsan_memory_order_acq_rel);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {
    +  __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
    +}
    +
    +inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
    +  __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
    +  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
    +}
    +
    +inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
    +  __tsan_atomic64_store(ptr, value, __tsan_memory_order_release);
    +}
    +
    +inline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {
    +  return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
    +  return __tsan_atomic64_load(ptr, __tsan_memory_order_acquire);
    +}
    +
    +inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
    +  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
    +  return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
    +}
    +
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  Atomic64 cmp = old_value;
    +  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
    +      __tsan_memory_order_acquire, __tsan_memory_order_acquire);
    +  return cmp;
    +}
    +
    +inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  Atomic64 cmp = old_value;
    +  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
    +      __tsan_memory_order_release, __tsan_memory_order_relaxed);
    +  return cmp;
    +}
    +
    +inline void MemoryBarrier() {
    +  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#undef ATOMICOPS_COMPILER_BARRIER
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
    new file mode 100644
    index 000000000000..53c9eae0fa73
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
    @@ -0,0 +1,137 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This module gets enough CPU information to optimize the
    +// atomicops module on x86.
    +
    +#include 
    +
    +#include 
    +
    +// This file only makes sense with atomicops_internals_x86_gcc.h -- it
    +// depends on structs that are defined in that file.  If atomicops.h
    +// doesn't sub-include that file, then we aren't needed, and shouldn't
    +// try to do anything.
    +#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
    +
    +// Inline cpuid instruction.  In PIC compilations, %ebx contains the address
    +// of the global offset table.  To avoid breaking such executables, this code
    +// must preserve that register's value across cpuid instructions.
    +#if defined(__i386__)
    +#define cpuid(a, b, c, d, inp) \
    +  asm("mov %%ebx, %%edi\n"     \
    +      "cpuid\n"                \
    +      "xchg %%edi, %%ebx\n"    \
    +      : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
    +#elif defined(__x86_64__)
    +#define cpuid(a, b, c, d, inp) \
    +  asm("mov %%rbx, %%rdi\n"     \
    +      "cpuid\n"                \
    +      "xchg %%rdi, %%rbx\n"    \
    +      : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
    +#endif
    +
    +#if defined(cpuid)        // initialize the struct only on x86
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// Set the flags so that code will run correctly and conservatively, so even
    +// if we haven't been initialized yet, we're probably single threaded, and our
    +// default values should hopefully be pretty safe.
    +struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
    +  false,          // bug can't exist before process spawns multiple threads
    +  false,          // no SSE2
    +};
    +
    +namespace {
    +
    +// Initialize the AtomicOps_Internalx86CPUFeatures struct.
    +void AtomicOps_Internalx86CPUFeaturesInit() {
    +  uint32_t eax;
    +  uint32_t ebx;
    +  uint32_t ecx;
    +  uint32_t edx;
    +
    +  // Get vendor string (issue CPUID with eax = 0)
    +  cpuid(eax, ebx, ecx, edx, 0);
    +  char vendor[13];
    +  memcpy(vendor, &ebx, 4);
    +  memcpy(vendor + 4, &edx, 4);
    +  memcpy(vendor + 8, &ecx, 4);
    +  vendor[12] = 0;
    +
    +  // get feature flags in ecx/edx, and family/model in eax
    +  cpuid(eax, ebx, ecx, edx, 1);
    +
    +  int family = (eax >> 8) & 0xf;        // family and model fields
    +  int model = (eax >> 4) & 0xf;
    +  if (family == 0xf) {                  // use extended family and model fields
    +    family += (eax >> 20) & 0xff;
    +    model += ((eax >> 16) & 0xf) << 4;
    +  }
    +
    +  // Opteron Rev E has a bug in which on very rare occasions a locked
    +  // instruction doesn't act as a read-acquire barrier if followed by a
    +  // non-locked read-modify-write instruction.  Rev F has this bug in
    +  // pre-release versions, but not in versions released to customers,
    +  // so we test only for Rev E, which is family 15, model 32..63 inclusive.
    +  if (strcmp(vendor, "AuthenticAMD") == 0 &&       // AMD
    +      family == 15 &&
    +      32 <= model && model <= 63) {
    +    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
    +  } else {
    +    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
    +  }
    +
    +  // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
    +  AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
    +}
    +
    +class AtomicOpsx86Initializer {
    + public:
    +  AtomicOpsx86Initializer() {
    +    AtomicOps_Internalx86CPUFeaturesInit();
    +  }
    +};
    +
    +// A global to get use initialized on startup via static initialization :/
    +AtomicOpsx86Initializer g_initer;
    +
    +}  // namespace
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // __i386__
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
    new file mode 100644
    index 000000000000..edccc59dee61
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
    @@ -0,0 +1,293 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// This struct is not part of the public API of this module; clients may not
    +// use it.
    +// Features of this x86.  Values may not be correct before main() is run,
    +// but are set conservatively.
    +struct AtomicOps_x86CPUFeatureStruct {
    +  bool has_amd_lock_mb_bug;  // Processor has AMD memory-barrier bug; do lfence
    +                             // after acquire compare-and-swap.
    +  bool has_sse2;             // Processor has SSE2.
    +};
    +extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
    +
    +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
    +
    +// 32-bit low-level operations on any platform.
    +
    +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                         Atomic32 old_value,
    +                                         Atomic32 new_value) {
    +  Atomic32 prev;
    +  __asm__ __volatile__("lock; cmpxchgl %1,%2"
    +                       : "=a" (prev)
    +                       : "q" (new_value), "m" (*ptr), "0" (old_value)
    +                       : "memory");
    +  return prev;
    +}
    +
    +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                         Atomic32 new_value) {
    +  __asm__ __volatile__("xchgl %1,%0"  // The lock prefix is implicit for xchg.
    +                       : "=r" (new_value)
    +                       : "m" (*ptr), "0" (new_value)
    +                       : "memory");
    +  return new_value;  // Now it's the previous value.
    +}
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  Atomic32 temp = increment;
    +  __asm__ __volatile__("lock; xaddl %0,%1"
    +                       : "+r" (temp), "+m" (*ptr)
    +                       : : "memory");
    +  // temp now holds the old value of *ptr
    +  return temp + increment;
    +}
    +
    +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                        Atomic32 increment) {
    +  Atomic32 temp = increment;
    +  __asm__ __volatile__("lock; xaddl %0,%1"
    +                       : "+r" (temp), "+m" (*ptr)
    +                       : : "memory");
    +  // temp now holds the old value of *ptr
    +  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
    +    __asm__ __volatile__("lfence" : : : "memory");
    +  }
    +  return temp + increment;
    +}
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
    +    __asm__ __volatile__("lfence" : : : "memory");
    +  }
    +  return x;
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +#if defined(__x86_64__)
    +
    +// 64-bit implementations of memory barrier can be simpler, because it
    +// "mfence" is guaranteed to exist.
    +inline void MemoryBarrier() {
    +  __asm__ __volatile__("mfence" : : : "memory");
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +#else
    +
    +inline void MemoryBarrier() {
    +  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
    +    __asm__ __volatile__("mfence" : : : "memory");
    +  } else {  // mfence is faster but not present on PIII
    +    Atomic32 x = 0;
    +    NoBarrier_AtomicExchange(&x, 0);  // acts as a barrier on PIII
    +  }
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
    +    *ptr = value;
    +    __asm__ __volatile__("mfence" : : : "memory");
    +  } else {
    +    NoBarrier_AtomicExchange(ptr, value);
    +                          // acts as a barrier on PIII
    +  }
    +}
    +#endif
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  ATOMICOPS_COMPILER_BARRIER();
    +  *ptr = value;  // An x86 store acts as a release barrier.
    +  // See comments in Atomic64 version of Release_Store(), below.
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value = *ptr;  // An x86 load acts as a acquire barrier.
    +  // See comments in Atomic64 version of Release_Store(), below.
    +  ATOMICOPS_COMPILER_BARRIER();
    +  return value;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +#if defined(__x86_64__)
    +
    +// 64-bit low-level operations on 64-bit platform.
    +
    +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                         Atomic64 old_value,
    +                                         Atomic64 new_value) {
    +  Atomic64 prev;
    +  __asm__ __volatile__("lock; cmpxchgq %1,%2"
    +                       : "=a" (prev)
    +                       : "q" (new_value), "m" (*ptr), "0" (old_value)
    +                       : "memory");
    +  return prev;
    +}
    +
    +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
    +                                         Atomic64 new_value) {
    +  __asm__ __volatile__("xchgq %1,%0"  // The lock prefix is implicit for xchg.
    +                       : "=r" (new_value)
    +                       : "m" (*ptr), "0" (new_value)
    +                       : "memory");
    +  return new_value;  // Now it's the previous value.
    +}
    +
    +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                          Atomic64 increment) {
    +  Atomic64 temp = increment;
    +  __asm__ __volatile__("lock; xaddq %0,%1"
    +                       : "+r" (temp), "+m" (*ptr)
    +                       : : "memory");
    +  // temp now contains the previous value of *ptr
    +  return temp + increment;
    +}
    +
    +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                        Atomic64 increment) {
    +  Atomic64 temp = increment;
    +  __asm__ __volatile__("lock; xaddq %0,%1"
    +                       : "+r" (temp), "+m" (*ptr)
    +                       : : "memory");
    +  // temp now contains the previous value of *ptr
    +  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
    +    __asm__ __volatile__("lfence" : : : "memory");
    +  }
    +  return temp + increment;
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +  MemoryBarrier();
    +}
    +
    +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  ATOMICOPS_COMPILER_BARRIER();
    +
    +  *ptr = value;  // An x86 store acts as a release barrier
    +                 // for current AMD/Intel chips as of Jan 2008.
    +                 // See also Acquire_Load(), below.
    +
    +  // When new chips come out, check:
    +  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
    +  //  System Programming Guide, Chatper 7: Multiple-processor management,
    +  //  Section 7.2, Memory Ordering.
    +  // Last seen at:
    +  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
    +  //
    +  // x86 stores/loads fail to act as barriers for a few instructions (clflush
    +  // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
    +  // not generated by the compiler, and are rare.  Users of these instructions
    +  // need to know about cache behaviour in any case since all of these involve
    +  // either flushing cache lines or non-temporal cache hints.
    +}
    +
    +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
    +  Atomic64 value = *ptr;  // An x86 load acts as a acquire barrier,
    +                          // for current AMD/Intel chips as of Jan 2008.
    +                          // See also Release_Store(), above.
    +  ATOMICOPS_COMPILER_BARRIER();
    +  return value;
    +}
    +
    +inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
    +    __asm__ __volatile__("lfence" : : : "memory");
    +  }
    +  return x;
    +}
    +
    +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +#endif  // defined(__x86_64__)
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#undef ATOMICOPS_COMPILER_BARRIER
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
    new file mode 100644
    index 000000000000..741b164f0ff3
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
    @@ -0,0 +1,112 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// The compilation of extension_set.cc fails when windows.h is included.
    +// Therefore we move the code depending on windows.h to this separate cc file.
    +
    +// Don't compile this file for people not concerned about thread safety.
    +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
    +
    +#include 
    +
    +#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline void MemoryBarrier() {
    +  // We use MemoryBarrier from WinNT.h
    +  ::MemoryBarrier();
    +}
    +
    +Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
    +                                  Atomic32 old_value,
    +                                  Atomic32 new_value) {
    +  LONG result = InterlockedCompareExchange(
    +      reinterpret_cast(ptr),
    +      static_cast(new_value),
    +      static_cast(old_value));
    +  return static_cast(result);
    +}
    +
    +Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
    +                                  Atomic32 new_value) {
    +  LONG result = InterlockedExchange(
    +      reinterpret_cast(ptr),
    +      static_cast(new_value));
    +  return static_cast(result);
    +}
    +
    +Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                 Atomic32 increment) {
    +  return InterlockedExchangeAdd(
    +      reinterpret_cast(ptr),
    +      static_cast(increment)) + increment;
    +}
    +
    +#if defined(_WIN64)
    +
    +// 64-bit low-level operations on 64-bit platform.
    +
    +Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
    +                                  Atomic64 old_value,
    +                                  Atomic64 new_value) {
    +  PVOID result = InterlockedCompareExchangePointer(
    +    reinterpret_cast(ptr),
    +    reinterpret_cast(new_value), reinterpret_cast(old_value));
    +  return reinterpret_cast(result);
    +}
    +
    +Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
    +                                  Atomic64 new_value) {
    +  PVOID result = InterlockedExchangePointer(
    +    reinterpret_cast(ptr),
    +    reinterpret_cast(new_value));
    +  return reinterpret_cast(result);
    +}
    +
    +Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                 Atomic64 increment) {
    +  return InterlockedExchangeAdd64(
    +      reinterpret_cast(ptr),
    +      static_cast(increment)) + increment;
    +}
    +
    +#endif  // defined(_WIN64)
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
    +#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
    new file mode 100644
    index 000000000000..e53a641f09f8
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
    @@ -0,0 +1,150 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// This file is an internal atomic implementation, use atomicops.h instead.
    +
    +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
    +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
    +                                          Atomic32 increment) {
    +  return Barrier_AtomicIncrement(ptr, increment);
    +}
    +
    +#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
    +#error "We require at least vs2005 for MemoryBarrier"
    +#endif
    +
    +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
    +                                       Atomic32 old_value,
    +                                       Atomic32 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  NoBarrier_AtomicExchange(ptr, value);
    +              // acts as a barrier in this implementation
    +}
    +
    +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
    +  *ptr = value;  // works w/o barrier for current Intel chips as of June 2005
    +  // See comments in Atomic64 version of Release_Store() below.
    +}
    +
    +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
    +  Atomic32 value = *ptr;
    +  return value;
    +}
    +
    +inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +#if defined(_WIN64)
    +
    +// 64-bit low-level operations on 64-bit platform.
    +
    +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
    +                                          Atomic64 increment) {
    +  return Barrier_AtomicIncrement(ptr, increment);
    +}
    +
    +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;
    +}
    +
    +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  NoBarrier_AtomicExchange(ptr, value);
    +              // acts as a barrier in this implementation
    +}
    +
    +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
    +  *ptr = value;  // works w/o barrier for current Intel chips as of June 2005
    +
    +  // When new chips come out, check:
    +  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
    +  //  System Programming Guide, Chatper 7: Multiple-processor management,
    +  //  Section 7.2, Memory Ordering.
    +  // Last seen at:
    +  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
    +}
    +
    +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
    +  Atomic64 value = *ptr;
    +  return value;
    +}
    +
    +inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
    +  MemoryBarrier();
    +  return *ptr;
    +}
    +
    +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
    +                                       Atomic64 old_value,
    +                                       Atomic64 new_value) {
    +  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
    +}
    +
    +#endif  // defined(_WIN64)
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
    diff --git a/toolkit/components/protobuf/google/protobuf/stubs/common.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/common.cc
    similarity index 90%
    rename from toolkit/components/protobuf/google/protobuf/stubs/common.cc
    rename to toolkit/components/protobuf/src/google/protobuf/stubs/common.cc
    index 9ae7e6101854..899585996392 100644
    --- a/toolkit/components/protobuf/google/protobuf/stubs/common.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/common.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -36,14 +36,15 @@
     #include 
     #include 
     
    -#ifdef WIN32
    +
    +#ifdef _WIN32
     #define WIN32_LEAN_AND_MEAN  // We only need minimal includes
     #include 
    -#if defined(_MSC_VER) && _MSC_VER < 1900
     #define snprintf _snprintf    // see comment in strutil.cc
    -#endif
    -#else
    +#elif defined(HAVE_PTHREAD_H)
     #include 
    +#else
    +#error "No suitable threading library available."
     #endif
     
     namespace google {
    @@ -108,13 +109,13 @@ void DefaultLogHandler(LogLevel level, const char* filename, int line,
     
       // We use fprintf() instead of cerr because we want this to work at static
       // initialization time.
    -  fprintf(stderr, "libprotobuf %s %s:%d] %s\n",
    +  fprintf(stderr, "[libprotobuf %s %s:%d] %s\n",
               level_names[level], filename, line, message.c_str());
       fflush(stderr);  // Needed on MSVC.
     }
     
    -void NullLogHandler(LogLevel level, const char* filename, int line,
    -                    const string& message) {
    +void NullLogHandler(LogLevel /* level */, const char* /* filename */,
    +                    int /* line */, const string& /* message */) {
       // Nothing.
     }
     
    @@ -181,15 +182,15 @@ void LogMessage::Finish() {
       if (level_ != LOGLEVEL_FATAL) {
         InitLogSilencerCountOnce();
         MutexLock lock(log_silencer_count_mutex_);
    -    suppress = internal::log_silencer_count_ > 0;
    +    suppress = log_silencer_count_ > 0;
       }
     
       if (!suppress) {
    -    internal::log_handler_(level_, filename_, line_, message_);
    +    log_handler_(level_, filename_, line_, message_);
       }
     
       if (level_ == LOGLEVEL_FATAL) {
    -#ifdef PROTOBUF_USE_EXCEPTIONS
    +#if PROTOBUF_USE_EXCEPTIONS
         throw FatalException(filename_, line_, message_);
     #else
         abort();
    @@ -240,7 +241,7 @@ void DoNothing() {}
     // ===================================================================
     // emulates google3/base/mutex.cc
     
    -#ifdef WIN32
    +#ifdef _WIN32
     
     struct Mutex::Internal {
       CRITICAL_SECTION mutex;
    @@ -280,7 +281,7 @@ void Mutex::AssertHeld() {
     #endif
     }
     
    -#else
    +#elif defined(HAVE_PTHREAD)
     
     struct Mutex::Internal {
       pthread_mutex_t mutex;
    @@ -317,6 +318,24 @@ void Mutex::AssertHeld() {
     
     #endif
     
    +// ===================================================================
    +// emulates google3/util/endian/endian.h
    +//
    +// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
    +// google/protobuf/io/coded_stream.h and therefore can not be used here.
    +// Maybe move that macro definition here in the furture.
    +uint32 ghtonl(uint32 x) {
    +  union {
    +    uint32 result;
    +    uint8 result_array[4];
    +  };
    +  result_array[0] = static_cast(x >> 24);
    +  result_array[1] = static_cast((x >> 16) & 0xFF);
    +  result_array[2] = static_cast((x >> 8) & 0xFF);
    +  result_array[3] = static_cast(x & 0xFF);
    +  return result;
    +}
    +
     // ===================================================================
     // Shutdown support.
     
    @@ -363,7 +382,7 @@ void ShutdownProtobufLibrary() {
       internal::shutdown_functions_mutex = NULL;
     }
     
    -#ifdef PROTOBUF_USE_EXCEPTIONS
    +#if PROTOBUF_USE_EXCEPTIONS
     FatalException::~FatalException() throw() {}
     
     const char* FatalException::what() const throw() {
    diff --git a/toolkit/components/protobuf/google/protobuf/stubs/common.h b/toolkit/components/protobuf/src/google/protobuf/stubs/common.h
    similarity index 93%
    rename from toolkit/components/protobuf/google/protobuf/stubs/common.h
    rename to toolkit/components/protobuf/src/google/protobuf/stubs/common.h
    index 7173a84d14ad..fa6fe3ce973b 100644
    --- a/toolkit/components/protobuf/google/protobuf/stubs/common.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/common.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -48,12 +48,17 @@
     #include 
     #endif
     
    +#ifndef PROTOBUF_USE_EXCEPTIONS
     #if defined(_MSC_VER) && defined(_CPPUNWIND)
    -  #define PROTOBUF_USE_EXCEPTIONS
    +  #define PROTOBUF_USE_EXCEPTIONS 1
     #elif defined(__EXCEPTIONS)
    -  #define PROTOBUF_USE_EXCEPTIONS
    +  #define PROTOBUF_USE_EXCEPTIONS 1
    +#else
    +  #define PROTOBUF_USE_EXCEPTIONS 0
     #endif
    -#ifdef PROTOBUF_USE_EXCEPTIONS
    +#endif
    +
    +#if PROTOBUF_USE_EXCEPTIONS
     #include 
     #endif
     
    @@ -108,24 +113,24 @@ namespace internal {
     
     // The current version, represented as a single integer to make comparison
     // easier:  major * 10^6 + minor * 10^3 + micro
    -#define GOOGLE_PROTOBUF_VERSION 2004001
    +#define GOOGLE_PROTOBUF_VERSION 2006001
     
     // The minimum library version which works with the current version of the
     // headers.
    -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2004000
    +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2006000
     
     // The minimum header version which works with the current version of
     // the library.  This constant should only be used by protoc's C++ code
     // generator.
    -static const int kMinHeaderVersionForLibrary = 2004000;
    +static const int kMinHeaderVersionForLibrary = 2006000;
     
     // The minimum protoc version which works with the current version of the
     // headers.
    -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2004000
    +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2006000
     
     // The minimum header version which works with the current version of
     // protoc.  This constant should only be used in VerifyVersion().
    -static const int kMinHeaderVersionForProtoc = 2004000;
    +static const int kMinHeaderVersionForProtoc = 2006000;
     
     // Verifies that the headers and libraries are compatible.  Use the macro
     // below to call this.
    @@ -363,60 +368,9 @@ using internal::down_cast;
     // the expression is false, most compilers will issue a warning/error
     // containing the name of the variable.
     
    -namespace internal {
    -
    -template 
    -struct CompileAssert {
    -};
    -
    -}  // namespace internal
    -
    -#undef GOOGLE_COMPILE_ASSERT
    -#define GOOGLE_COMPILE_ASSERT(expr, msg) \
    -  typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \
    -          msg[bool(expr) ? 1 : -1]
    +#define GOOGLE_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
     
     
    -// Implementation details of COMPILE_ASSERT:
    -//
    -// - COMPILE_ASSERT works by defining an array type that has -1
    -//   elements (and thus is invalid) when the expression is false.
    -//
    -// - The simpler definition
    -//
    -//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
    -//
    -//   does not work, as gcc supports variable-length arrays whose sizes
    -//   are determined at run-time (this is gcc's extension and not part
    -//   of the C++ standard).  As a result, gcc fails to reject the
    -//   following code with the simple definition:
    -//
    -//     int foo;
    -//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
    -//                               // not a compile-time constant.
    -//
    -// - By using the type CompileAssert<(bool(expr))>, we ensures that
    -//   expr is a compile-time constant.  (Template arguments must be
    -//   determined at compile-time.)
    -//
    -// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
    -//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
    -//
    -//     CompileAssert
    -//
    -//   instead, these compilers will refuse to compile
    -//
    -//     COMPILE_ASSERT(5 > 0, some_message);
    -//
    -//   (They seem to think the ">" in "5 > 0" marks the end of the
    -//   template argument list.)
    -//
    -// - The array size is (bool(expr) ? 1 : -1), instead of simply
    -//
    -//     ((expr) ? 1 : -1).
    -//
    -//   This is to avoid running into a bug in MS VC 7.1, which
    -//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
     
     // ===================================================================
     // from google3/base/scoped_ptr.h
    @@ -633,6 +587,17 @@ enum LogLevel {
     #else
       LOGLEVEL_DFATAL = LOGLEVEL_FATAL
     #endif
    +
    +#ifdef ERROR
    +  // ERROR is defined as 0 on some windows builds, so `GOOGLE_LOG(ERROR, ...)`
    +  // expands into `GOOGLE_LOG(0, ...)` which then expands into
    +  // `someGoogleLogging(LOGLEVEL_0, ...)`. This is not ideal, because the
    +  // GOOGLE_LOG macro expects to expand itself into
    +  // `someGoogleLogging(LOGLEVEL_ERROR, ...)` instead. The workaround to get
    +  // everything building is to simply define LOGLEVEL_0 as LOGLEVEL_ERROR and
    +  // move on with our lives.
    +  , LOGLEVEL_0 = LOGLEVEL_ERROR
    +#endif
     };
     
     namespace internal {
    @@ -680,12 +645,14 @@ class LIBPROTOBUF_EXPORT LogFinisher {
     #undef GOOGLE_LOG_IF
     
     #undef GOOGLE_CHECK
    +#undef GOOGLE_CHECK_OK
     #undef GOOGLE_CHECK_EQ
     #undef GOOGLE_CHECK_NE
     #undef GOOGLE_CHECK_LT
     #undef GOOGLE_CHECK_LE
     #undef GOOGLE_CHECK_GT
     #undef GOOGLE_CHECK_GE
    +#undef GOOGLE_CHECK_NOTNULL
     
     #undef GOOGLE_DLOG
     #undef GOOGLE_DCHECK
    @@ -705,6 +672,7 @@ class LIBPROTOBUF_EXPORT LogFinisher {
     
     #define GOOGLE_CHECK(EXPRESSION) \
       GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": "
    +#define GOOGLE_CHECK_OK(A) GOOGLE_CHECK(A)
     #define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B))
     #define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B))
     #define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) <  (B))
    @@ -712,6 +680,19 @@ class LIBPROTOBUF_EXPORT LogFinisher {
     #define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) >  (B))
     #define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B))
     
    +namespace internal {
    +template
    +T* CheckNotNull(const char* /* file */, int /* line */,
    +                const char* name, T* val) {
    +  if (val == NULL) {
    +    GOOGLE_LOG(FATAL) << name;
    +  }
    +  return val;
    +}
    +}  // namespace internal
    +#define GOOGLE_CHECK_NOTNULL(A) \
    +  internal::CheckNotNull(__FILE__, __LINE__, "'" #A "' must not be NULL", (A))
    +
     #ifdef NDEBUG
     
     #define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false)
    @@ -1136,26 +1117,20 @@ using internal::WriterMutexLock;
     using internal::MutexLockMaybe;
     
     // ===================================================================
    -// from google3/base/type_traits.h
    +// from google3/util/utf8/public/unilib.h
     
     namespace internal {
     
    -// Specified by TR1 [4.7.4] Pointer modifications.
    -template struct remove_pointer { typedef T type; };
    -template struct remove_pointer { typedef T type; };
    -template struct remove_pointer { typedef T type; };
    -template struct remove_pointer { typedef T type; };
    -template struct remove_pointer {
    -  typedef T type; };
    -
    -// ===================================================================
    -
     // Checks if the buffer contains structurally-valid UTF-8.  Implemented in
     // structurally_valid.cc.
     LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
     
     }  // namespace internal
     
    +// ===================================================================
    +// from google3/util/endian/endian.h
    +LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x);
    +
     // ===================================================================
     // Shutdown support.
     
    @@ -1181,7 +1156,7 @@ LIBPROTOBUF_EXPORT void OnShutdown(void (*func)());
     
     }  // namespace internal
     
    -#ifdef PROTOBUF_USE_EXCEPTIONS
    +#if PROTOBUF_USE_EXCEPTIONS
     class FatalException : public std::exception {
      public:
       FatalException(const char* filename, int line, const std::string& message)
    diff --git a/toolkit/components/protobuf/google/protobuf/stubs/hash.h b/toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
    similarity index 96%
    rename from toolkit/components/protobuf/google/protobuf/stubs/hash.h
    rename to toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
    index 21e34652b576..3640b8982dfb 100644
    --- a/toolkit/components/protobuf/google/protobuf/stubs/hash.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/hash.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -89,12 +89,16 @@ template ,
               typename EqualKey = int >
     class hash_map : public std::map {
    + public:
    +  hash_map(int = 0) {}
     };
     
     template ,
               typename EqualKey = int >
     class hash_set : public std::set {
    + public:
    +  hash_set(int = 0) {}
     };
     
     #elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
    @@ -122,6 +126,8 @@ template 
     class hash_map : public HASH_NAMESPACE::hash_map<
         Key, Data, HashFcn> {
    + public:
    +  hash_map(int = 0) {}
     };
     
     template 
     class hash_set : public HASH_NAMESPACE::hash_set<
         Key, HashFcn> {
    + public:
    +  hash_set(int = 0) {}
     };
     
     #else
    @@ -162,6 +170,8 @@ template  >
     class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS<
         Key, Data, HashFcn, EqualKey> {
    + public:
    +  hash_map(int = 0) {}
     };
     
     template  >
     class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS<
         Key, HashFcn, EqualKey> {
    + public:
    +  hash_set(int = 0) {}
     };
     
     #endif
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h b/toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h
    new file mode 100644
    index 000000000000..7495cb6aec7b
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h
    @@ -0,0 +1,771 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2014 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// from google3/util/gtl/map_util.h
    +// Author: Anton Carver
    +
    +#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
    +#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +// Local implementation of RemoveConst to avoid including base/type_traits.h.
    +template  struct RemoveConst { typedef T type; };
    +template  struct RemoveConst : RemoveConst {};
    +}  // namespace internal
    +
    +//
    +// Find*()
    +//
    +
    +// Returns a const reference to the value associated with the given key if it
    +// exists. Crashes otherwise.
    +//
    +// This is intended as a replacement for operator[] as an rvalue (for reading)
    +// when the key is guaranteed to exist.
    +//
    +// operator[] for lookup is discouraged for several reasons:
    +//  * It has a side-effect of inserting missing keys
    +//  * It is not thread-safe (even when it is not inserting, it can still
    +//      choose to resize the underlying storage)
    +//  * It invalidates iterators (when it chooses to resize)
    +//  * It default constructs a value object even if it doesn't need to
    +//
    +// This version assumes the key is printable, and includes it in the fatal log
    +// message.
    +template 
    +const typename Collection::value_type::second_type&
    +FindOrDie(const Collection& collection,
    +          const typename Collection::value_type::first_type& key) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
    +  return it->second;
    +}
    +
    +// Same as above, but returns a non-const reference.
    +template 
    +typename Collection::value_type::second_type&
    +FindOrDie(Collection& collection,  // NOLINT
    +          const typename Collection::value_type::first_type& key) {
    +  typename Collection::iterator it = collection.find(key);
    +  GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
    +  return it->second;
    +}
    +
    +// Same as FindOrDie above, but doesn't log the key on failure.
    +template 
    +const typename Collection::value_type::second_type&
    +FindOrDieNoPrint(const Collection& collection,
    +                 const typename Collection::value_type::first_type& key) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  GOOGLE_CHECK(it != collection.end()) << "Map key not found";
    +  return it->second;
    +}
    +
    +// Same as above, but returns a non-const reference.
    +template 
    +typename Collection::value_type::second_type&
    +FindOrDieNoPrint(Collection& collection,  // NOLINT
    +                 const typename Collection::value_type::first_type& key) {
    +  typename Collection::iterator it = collection.find(key);
    +  GOOGLE_CHECK(it != collection.end()) << "Map key not found";
    +  return it->second;
    +}
    +
    +// Returns a const reference to the value associated with the given key if it
    +// exists, otherwise returns a const reference to the provided default value.
    +//
    +// WARNING: If a temporary object is passed as the default "value,"
    +// this function will return a reference to that temporary object,
    +// which will be destroyed at the end of the statement. A common
    +// example: if you have a map with string values, and you pass a char*
    +// as the default "value," either use the returned value immediately
    +// or store it in a string (not string&).
    +// Details: http://go/findwithdefault
    +template 
    +const typename Collection::value_type::second_type&
    +FindWithDefault(const Collection& collection,
    +                const typename Collection::value_type::first_type& key,
    +                const typename Collection::value_type::second_type& value) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  if (it == collection.end()) {
    +    return value;
    +  }
    +  return it->second;
    +}
    +
    +// Returns a pointer to the const value associated with the given key if it
    +// exists, or NULL otherwise.
    +template 
    +const typename Collection::value_type::second_type*
    +FindOrNull(const Collection& collection,
    +           const typename Collection::value_type::first_type& key) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  if (it == collection.end()) {
    +    return 0;
    +  }
    +  return &it->second;
    +}
    +
    +// Same as above but returns a pointer to the non-const value.
    +template 
    +typename Collection::value_type::second_type*
    +FindOrNull(Collection& collection,  // NOLINT
    +           const typename Collection::value_type::first_type& key) {
    +  typename Collection::iterator it = collection.find(key);
    +  if (it == collection.end()) {
    +    return 0;
    +  }
    +  return &it->second;
    +}
    +
    +// Returns the pointer value associated with the given key. If none is found,
    +// NULL is returned. The function is designed to be used with a map of keys to
    +// pointers.
    +//
    +// This function does not distinguish between a missing key and a key mapped
    +// to a NULL value.
    +template 
    +typename Collection::value_type::second_type
    +FindPtrOrNull(const Collection& collection,
    +              const typename Collection::value_type::first_type& key) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  if (it == collection.end()) {
    +    return typename Collection::value_type::second_type();
    +  }
    +  return it->second;
    +}
    +
    +// Same as above, except takes non-const reference to collection.
    +//
    +// This function is needed for containers that propagate constness to the
    +// pointee, such as boost::ptr_map.
    +template 
    +typename Collection::value_type::second_type
    +FindPtrOrNull(Collection& collection,  // NOLINT
    +              const typename Collection::value_type::first_type& key) {
    +  typename Collection::iterator it = collection.find(key);
    +  if (it == collection.end()) {
    +    return typename Collection::value_type::second_type();
    +  }
    +  return it->second;
    +}
    +
    +// Finds the pointer value associated with the given key in a map whose values
    +// are linked_ptrs. Returns NULL if key is not found.
    +template 
    +typename Collection::value_type::second_type::element_type*
    +FindLinkedPtrOrNull(const Collection& collection,
    +                    const typename Collection::value_type::first_type& key) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  if (it == collection.end()) {
    +    return 0;
    +  }
    +  // Since linked_ptr::get() is a const member returning a non const,
    +  // we do not need a version of this function taking a non const collection.
    +  return it->second.get();
    +}
    +
    +// Same as above, but dies if the key is not found.
    +template 
    +typename Collection::value_type::second_type::element_type&
    +FindLinkedPtrOrDie(const Collection& collection,
    +                   const typename Collection::value_type::first_type& key) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  CHECK(it != collection.end()) <<  "key not found: " << key;
    +  // Since linked_ptr::operator*() is a const member returning a non const,
    +  // we do not need a version of this function taking a non const collection.
    +  return *it->second;
    +}
    +
    +// Finds the value associated with the given key and copies it to *value (if not
    +// NULL). Returns false if the key was not found, true otherwise.
    +template 
    +bool FindCopy(const Collection& collection,
    +              const Key& key,
    +              Value* const value) {
    +  typename Collection::const_iterator it = collection.find(key);
    +  if (it == collection.end()) {
    +    return false;
    +  }
    +  if (value) {
    +    *value = it->second;
    +  }
    +  return true;
    +}
    +
    +//
    +// Contains*()
    +//
    +
    +// Returns true if and only if the given collection contains the given key.
    +template 
    +bool ContainsKey(const Collection& collection, const Key& key) {
    +  return collection.find(key) != collection.end();
    +}
    +
    +// Returns true if and only if the given collection contains the given key-value
    +// pair.
    +template 
    +bool ContainsKeyValuePair(const Collection& collection,
    +                          const Key& key,
    +                          const Value& value) {
    +  typedef typename Collection::const_iterator const_iterator;
    +  std::pair range = collection.equal_range(key);
    +  for (const_iterator it = range.first; it != range.second; ++it) {
    +    if (it->second == value) {
    +      return true;
    +    }
    +  }
    +  return false;
    +}
    +
    +//
    +// Insert*()
    +//
    +
    +// Inserts the given key-value pair into the collection. Returns true if and
    +// only if the key from the given pair didn't previously exist. Otherwise, the
    +// value in the map is replaced with the value from the given pair.
    +template 
    +bool InsertOrUpdate(Collection* const collection,
    +                    const typename Collection::value_type& vt) {
    +  std::pair ret = collection->insert(vt);
    +  if (!ret.second) {
    +    // update
    +    ret.first->second = vt.second;
    +    return false;
    +  }
    +  return true;
    +}
    +
    +// Same as above, except that the key and value are passed separately.
    +template 
    +bool InsertOrUpdate(Collection* const collection,
    +                    const typename Collection::value_type::first_type& key,
    +                    const typename Collection::value_type::second_type& value) {
    +  return InsertOrUpdate(
    +      collection, typename Collection::value_type(key, value));
    +}
    +
    +// Inserts/updates all the key-value pairs from the range defined by the
    +// iterators "first" and "last" into the given collection.
    +template 
    +void InsertOrUpdateMany(Collection* const collection,
    +                        InputIterator first, InputIterator last) {
    +  for (; first != last; ++first) {
    +    InsertOrUpdate(collection, *first);
    +  }
    +}
    +
    +// Change the value associated with a particular key in a map or hash_map
    +// of the form map which owns the objects pointed to by the
    +// value pointers.  If there was an existing value for the key, it is deleted.
    +// True indicates an insert took place, false indicates an update + delete.
    +template 
    +bool InsertAndDeleteExisting(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key,
    +    const typename Collection::value_type::second_type& value) {
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(key, value));
    +  if (!ret.second) {
    +    delete ret.first->second;
    +    ret.first->second = value;
    +    return false;
    +  }
    +  return true;
    +}
    +
    +// Inserts the given key and value into the given collection if and only if the
    +// given key did NOT already exist in the collection. If the key previously
    +// existed in the collection, the value is not changed. Returns true if the
    +// key-value pair was inserted; returns false if the key was already present.
    +template 
    +bool InsertIfNotPresent(Collection* const collection,
    +                        const typename Collection::value_type& vt) {
    +  return collection->insert(vt).second;
    +}
    +
    +// Same as above except the key and value are passed separately.
    +template 
    +bool InsertIfNotPresent(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key,
    +    const typename Collection::value_type::second_type& value) {
    +  return InsertIfNotPresent(
    +      collection, typename Collection::value_type(key, value));
    +}
    +
    +// Same as above except dies if the key already exists in the collection.
    +template 
    +void InsertOrDie(Collection* const collection,
    +                 const typename Collection::value_type& value) {
    +  CHECK(InsertIfNotPresent(collection, value)) << "duplicate value: " << value;
    +}
    +
    +// Same as above except doesn't log the value on error.
    +template 
    +void InsertOrDieNoPrint(Collection* const collection,
    +                        const typename Collection::value_type& value) {
    +  CHECK(InsertIfNotPresent(collection, value)) << "duplicate value.";
    +}
    +
    +// Inserts the key-value pair into the collection. Dies if key was already
    +// present.
    +template 
    +void InsertOrDie(Collection* const collection,
    +                 const typename Collection::value_type::first_type& key,
    +                 const typename Collection::value_type::second_type& data) {
    +  typedef typename Collection::value_type value_type;
    +  GOOGLE_CHECK(InsertIfNotPresent(collection, key, data))
    +      << "duplicate key: " << key;
    +}
    +
    +// Same as above except doesn't log the key on error.
    +template 
    +void InsertOrDieNoPrint(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key,
    +    const typename Collection::value_type::second_type& data) {
    +  typedef typename Collection::value_type value_type;
    +  GOOGLE_CHECK(InsertIfNotPresent(collection, key, data)) << "duplicate key.";
    +}
    +
    +// Inserts a new key and default-initialized value. Dies if the key was already
    +// present. Returns a reference to the value. Example usage:
    +//
    +// map m;
    +// SomeProto& proto = InsertKeyOrDie(&m, 3);
    +// proto.set_field("foo");
    +template 
    +typename Collection::value_type::second_type& InsertKeyOrDie(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key) {
    +  typedef typename Collection::value_type value_type;
    +  std::pair res =
    +      collection->insert(value_type(key, typename value_type::second_type()));
    +  GOOGLE_CHECK(res.second) << "duplicate key: " << key;
    +  return res.first->second;
    +}
    +
    +//
    +// Lookup*()
    +//
    +
    +// Looks up a given key and value pair in a collection and inserts the key-value
    +// pair if it's not already present. Returns a reference to the value associated
    +// with the key.
    +template 
    +typename Collection::value_type::second_type&
    +LookupOrInsert(Collection* const collection,
    +               const typename Collection::value_type& vt) {
    +  return collection->insert(vt).first->second;
    +}
    +
    +// Same as above except the key-value are passed separately.
    +template 
    +typename Collection::value_type::second_type&
    +LookupOrInsert(Collection* const collection,
    +               const typename Collection::value_type::first_type& key,
    +               const typename Collection::value_type::second_type& value) {
    +  return LookupOrInsert(
    +      collection, typename Collection::value_type(key, value));
    +}
    +
    +// Counts the number of equivalent elements in the given "sequence", and stores
    +// the results in "count_map" with element as the key and count as the value.
    +//
    +// Example:
    +//   vector v = {"a", "b", "c", "a", "b"};
    +//   map m;
    +//   AddTokenCounts(v, 1, &m);
    +//   assert(m["a"] == 2);
    +//   assert(m["b"] == 2);
    +//   assert(m["c"] == 1);
    +template 
    +void AddTokenCounts(
    +    const Sequence& sequence,
    +    const typename Collection::value_type::second_type& increment,
    +    Collection* const count_map) {
    +  for (typename Sequence::const_iterator it = sequence.begin();
    +       it != sequence.end(); ++it) {
    +    typename Collection::value_type::second_type& value =
    +        LookupOrInsert(count_map, *it,
    +                       typename Collection::value_type::second_type());
    +    value += increment;
    +  }
    +}
    +
    +// Returns a reference to the value associated with key. If not found, a value
    +// is default constructed on the heap and added to the map.
    +//
    +// This function is useful for containers of the form map, where
    +// inserting a new key, value pair involves constructing a new heap-allocated
    +// Value, and storing a pointer to that in the collection.
    +template 
    +typename Collection::value_type::second_type&
    +LookupOrInsertNew(Collection* const collection,
    +                  const typename Collection::value_type::first_type& key) {
    +  typedef typename std::iterator_traits<
    +    typename Collection::value_type::second_type>::value_type Element;
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(
    +          key,
    +          static_cast(NULL)));
    +  if (ret.second) {
    +    ret.first->second = new Element();
    +  }
    +  return ret.first->second;
    +}
    +
    +// Same as above but constructs the value using the single-argument constructor
    +// and the given "arg".
    +template 
    +typename Collection::value_type::second_type&
    +LookupOrInsertNew(Collection* const collection,
    +                  const typename Collection::value_type::first_type& key,
    +                  const Arg& arg) {
    +  typedef typename std::iterator_traits<
    +    typename Collection::value_type::second_type>::value_type Element;
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(
    +          key,
    +          static_cast(NULL)));
    +  if (ret.second) {
    +    ret.first->second = new Element(arg);
    +  }
    +  return ret.first->second;
    +}
    +
    +// Lookup of linked/shared pointers is used in two scenarios:
    +//
    +// Use LookupOrInsertNewLinkedPtr if the container owns the elements.
    +// In this case it is fine working with the raw pointer as long as it is
    +// guaranteed that no other thread can delete/update an accessed element.
    +// A mutex will need to lock the container operation as well as the use
    +// of the returned elements. Finding an element may be performed using
    +// FindLinkedPtr*().
    +//
    +// Use LookupOrInsertNewSharedPtr if the container does not own the elements
    +// for their whole lifetime. This is typically the case when a reader allows
    +// parallel updates to the container. In this case a Mutex only needs to lock
    +// container operations, but all element operations must be performed on the
    +// shared pointer. Finding an element must be performed using FindPtr*() and
    +// cannot be done with FindLinkedPtr*() even though it compiles.
    +
    +// Lookup a key in a map or hash_map whose values are linked_ptrs.  If it is
    +// missing, set collection[key].reset(new Value::element_type) and return that.
    +// Value::element_type must be default constructable.
    +template 
    +typename Collection::value_type::second_type::element_type*
    +LookupOrInsertNewLinkedPtr(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key) {
    +  typedef typename Collection::value_type::second_type Value;
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(key, Value()));
    +  if (ret.second) {
    +    ret.first->second.reset(new typename Value::element_type);
    +  }
    +  return ret.first->second.get();
    +}
    +
    +// A variant of LookupOrInsertNewLinkedPtr where the value is constructed using
    +// a single-parameter constructor.  Note: the constructor argument is computed
    +// even if it will not be used, so only values cheap to compute should be passed
    +// here.  On the other hand it does not matter how expensive the construction of
    +// the actual stored value is, as that only occurs if necessary.
    +template 
    +typename Collection::value_type::second_type::element_type*
    +LookupOrInsertNewLinkedPtr(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key,
    +    const Arg& arg) {
    +  typedef typename Collection::value_type::second_type Value;
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(key, Value()));
    +  if (ret.second) {
    +    ret.first->second.reset(new typename Value::element_type(arg));
    +  }
    +  return ret.first->second.get();
    +}
    +
    +// Lookup a key in a map or hash_map whose values are shared_ptrs.  If it is
    +// missing, set collection[key].reset(new Value::element_type). Unlike
    +// LookupOrInsertNewLinkedPtr, this function returns the shared_ptr instead of
    +// the raw pointer. Value::element_type must be default constructable.
    +template 
    +typename Collection::value_type::second_type&
    +LookupOrInsertNewSharedPtr(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key) {
    +  typedef typename Collection::value_type::second_type SharedPtr;
    +  typedef typename Collection::value_type::second_type::element_type Element;
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(key, SharedPtr()));
    +  if (ret.second) {
    +    ret.first->second.reset(new Element());
    +  }
    +  return ret.first->second;
    +}
    +
    +// A variant of LookupOrInsertNewSharedPtr where the value is constructed using
    +// a single-parameter constructor.  Note: the constructor argument is computed
    +// even if it will not be used, so only values cheap to compute should be passed
    +// here.  On the other hand it does not matter how expensive the construction of
    +// the actual stored value is, as that only occurs if necessary.
    +template 
    +typename Collection::value_type::second_type&
    +LookupOrInsertNewSharedPtr(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key,
    +    const Arg& arg) {
    +  typedef typename Collection::value_type::second_type SharedPtr;
    +  typedef typename Collection::value_type::second_type::element_type Element;
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(key, SharedPtr()));
    +  if (ret.second) {
    +    ret.first->second.reset(new Element(arg));
    +  }
    +  return ret.first->second;
    +}
    +
    +//
    +// Misc Utility Functions
    +//
    +
    +// Updates the value associated with the given key. If the key was not already
    +// present, then the key-value pair are inserted and "previous" is unchanged. If
    +// the key was already present, the value is updated and "*previous" will
    +// contain a copy of the old value.
    +//
    +// InsertOrReturnExisting has complementary behavior that returns the
    +// address of an already existing value, rather than updating it.
    +template 
    +bool UpdateReturnCopy(Collection* const collection,
    +                      const typename Collection::value_type::first_type& key,
    +                      const typename Collection::value_type::second_type& value,
    +                      typename Collection::value_type::second_type* previous) {
    +  std::pair ret =
    +      collection->insert(typename Collection::value_type(key, value));
    +  if (!ret.second) {
    +    // update
    +    if (previous) {
    +      *previous = ret.first->second;
    +    }
    +    ret.first->second = value;
    +    return true;
    +  }
    +  return false;
    +}
    +
    +// Same as above except that the key and value are passed as a pair.
    +template 
    +bool UpdateReturnCopy(Collection* const collection,
    +                      const typename Collection::value_type& vt,
    +                      typename Collection::value_type::second_type* previous) {
    +  std::pair ret = collection->insert(vt);
    +  if (!ret.second) {
    +    // update
    +    if (previous) {
    +      *previous = ret.first->second;
    +    }
    +    ret.first->second = vt.second;
    +    return true;
    +  }
    +  return false;
    +}
    +
    +// Tries to insert the given key-value pair into the collection. Returns NULL if
    +// the insert succeeds. Otherwise, returns a pointer to the existing value.
    +//
    +// This complements UpdateReturnCopy in that it allows to update only after
    +// verifying the old value and still insert quickly without having to look up
    +// twice. Unlike UpdateReturnCopy this also does not come with the issue of an
    +// undefined previous* in case new data was inserted.
    +template 
    +typename Collection::value_type::second_type* const
    +InsertOrReturnExisting(Collection* const collection,
    +                       const typename Collection::value_type& vt) {
    +  std::pair ret = collection->insert(vt);
    +  if (ret.second) {
    +    return NULL;  // Inserted, no existing previous value.
    +  } else {
    +    return &ret.first->second;  // Return address of already existing value.
    +  }
    +}
    +
    +// Same as above, except for explicit key and data.
    +template 
    +typename Collection::value_type::second_type* const
    +InsertOrReturnExisting(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key,
    +    const typename Collection::value_type::second_type& data) {
    +  return InsertOrReturnExisting(collection,
    +                                typename Collection::value_type(key, data));
    +}
    +
    +// Erases the collection item identified by the given key, and returns the value
    +// associated with that key. It is assumed that the value (i.e., the
    +// mapped_type) is a pointer. Returns NULL if the key was not found in the
    +// collection.
    +//
    +// Examples:
    +//   map my_map;
    +//
    +// One line cleanup:
    +//     delete EraseKeyReturnValuePtr(&my_map, "abc");
    +//
    +// Use returned value:
    +//     scoped_ptr value_ptr(EraseKeyReturnValuePtr(&my_map, "abc"));
    +//     if (value_ptr.get())
    +//       value_ptr->DoSomething();
    +//
    +template 
    +typename Collection::value_type::second_type EraseKeyReturnValuePtr(
    +    Collection* const collection,
    +    const typename Collection::value_type::first_type& key) {
    +  typename Collection::iterator it = collection->find(key);
    +  if (it == collection->end()) {
    +    return NULL;
    +  }
    +  typename Collection::value_type::second_type v = it->second;
    +  collection->erase(it);
    +  return v;
    +}
    +
    +// Inserts all the keys from map_container into key_container, which must
    +// support insert(MapContainer::key_type).
    +//
    +// Note: any initial contents of the key_container are not cleared.
    +template 
    +void InsertKeysFromMap(const MapContainer& map_container,
    +                       KeyContainer* key_container) {
    +  GOOGLE_CHECK(key_container != NULL);
    +  for (typename MapContainer::const_iterator it = map_container.begin();
    +       it != map_container.end(); ++it) {
    +    key_container->insert(it->first);
    +  }
    +}
    +
    +// Appends all the keys from map_container into key_container, which must
    +// support push_back(MapContainer::key_type).
    +//
    +// Note: any initial contents of the key_container are not cleared.
    +template 
    +void AppendKeysFromMap(const MapContainer& map_container,
    +                       KeyContainer* key_container) {
    +  GOOGLE_CHECK(key_container != NULL);
    +  for (typename MapContainer::const_iterator it = map_container.begin();
    +       it != map_container.end(); ++it) {
    +    key_container->push_back(it->first);
    +  }
    +}
    +
    +// A more specialized overload of AppendKeysFromMap to optimize reallocations
    +// for the common case in which we're appending keys to a vector and hence can
    +// (and sometimes should) call reserve() first.
    +//
    +// (It would be possible to play SFINAE games to call reserve() for any
    +// container that supports it, but this seems to get us 99% of what we need
    +// without the complexity of a SFINAE-based solution.)
    +template 
    +void AppendKeysFromMap(const MapContainer& map_container,
    +                       vector* key_container) {
    +  GOOGLE_CHECK(key_container != NULL);
    +  // We now have the opportunity to call reserve(). Calling reserve() every
    +  // time is a bad idea for some use cases: libstdc++'s implementation of
    +  // vector<>::reserve() resizes the vector's backing store to exactly the
    +  // given size (unless it's already at least that big). Because of this,
    +  // the use case that involves appending a lot of small maps (total size
    +  // N) one by one to a vector would be O(N^2). But never calling reserve()
    +  // loses the opportunity to improve the use case of adding from a large
    +  // map to an empty vector (this improves performance by up to 33%). A
    +  // number of heuristics are possible; see the discussion in
    +  // cl/34081696. Here we use the simplest one.
    +  if (key_container->empty()) {
    +    key_container->reserve(map_container.size());
    +  }
    +  for (typename MapContainer::const_iterator it = map_container.begin();
    +       it != map_container.end(); ++it) {
    +    key_container->push_back(it->first);
    +  }
    +}
    +
    +// Inserts all the values from map_container into value_container, which must
    +// support push_back(MapContainer::mapped_type).
    +//
    +// Note: any initial contents of the value_container are not cleared.
    +template 
    +void AppendValuesFromMap(const MapContainer& map_container,
    +                         ValueContainer* value_container) {
    +  GOOGLE_CHECK(value_container != NULL);
    +  for (typename MapContainer::const_iterator it = map_container.begin();
    +       it != map_container.end(); ++it) {
    +    value_container->push_back(it->second);
    +  }
    +}
    +
    +// A more specialized overload of AppendValuesFromMap to optimize reallocations
    +// for the common case in which we're appending values to a vector and hence
    +// can (and sometimes should) call reserve() first.
    +//
    +// (It would be possible to play SFINAE games to call reserve() for any
    +// container that supports it, but this seems to get us 99% of what we need
    +// without the complexity of a SFINAE-based solution.)
    +template 
    +void AppendValuesFromMap(const MapContainer& map_container,
    +                         vector* value_container) {
    +  GOOGLE_CHECK(value_container != NULL);
    +  // See AppendKeysFromMap for why this is done.
    +  if (value_container->empty()) {
    +    value_container->reserve(map_container.size());
    +  }
    +  for (typename MapContainer::const_iterator it = map_container.begin();
    +       it != map_container.end(); ++it) {
    +    value_container->push_back(it->second);
    +  }
    +}
    +
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/stubs/once.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/once.cc
    similarity index 56%
    rename from toolkit/components/protobuf/google/protobuf/stubs/once.cc
    rename to toolkit/components/protobuf/src/google/protobuf/stubs/once.cc
    index 5b7af9ce990f..889c647660de 100644
    --- a/toolkit/components/protobuf/google/protobuf/stubs/once.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/once.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -35,54 +35,65 @@
     // This header is intended to be included only by internal .cc files and
     // generated .pb.cc files.  Users should not use this directly.
     
    +#include 
    +
    +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
    +
     #ifdef _WIN32
     #include 
    +#else
    +#include 
     #endif
     
    -#include 
    +#include 
     
     namespace google {
     namespace protobuf {
     
    +namespace {
    +
    +void SchedYield() {
     #ifdef _WIN32
    -
    -struct ProtobufOnceInternal {
    -  ProtobufOnceInternal() {
    -    InitializeCriticalSection(&critical_section);
    -  }
    -  ~ProtobufOnceInternal() {
    -    DeleteCriticalSection(&critical_section);
    -  }
    -  CRITICAL_SECTION critical_section;
    -};
    -
    -ProtobufOnceType::~ProtobufOnceType()
    -{
    -  delete internal_;
    -  internal_ = NULL;
    -}
    -
    -ProtobufOnceType::ProtobufOnceType() {
    -  // internal_ may be non-NULL if Init() was already called.
    -  if (internal_ == NULL) internal_ = new ProtobufOnceInternal;
    -}
    -
    -void ProtobufOnceType::Init(void (*init_func)()) {
    -  // internal_ may be NULL if we're still in dynamic initialization and the
    -  // constructor has not been called yet.  As mentioned in once.h, we assume
    -  // that the program is still single-threaded at this time, and therefore it
    -  // should be safe to initialize internal_ like so.
    -  if (internal_ == NULL) internal_ = new ProtobufOnceInternal;
    -
    -  EnterCriticalSection(&internal_->critical_section);
    -  if (!initialized_) {
    -    init_func();
    -    initialized_ = true;
    -  }
    -  LeaveCriticalSection(&internal_->critical_section);
    -}
    -
    +  Sleep(0);
    +#else  // POSIX
    +  sched_yield();
     #endif
    +}
    +
    +}  // namespace
    +
    +void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) {
    +  internal::AtomicWord state = internal::Acquire_Load(once);
    +  // Fast path. The provided closure was already executed.
    +  if (state == ONCE_STATE_DONE) {
    +    return;
    +  }
    +  // The closure execution did not complete yet. The once object can be in one
    +  // of the two following states:
    +  //   - UNINITIALIZED: We are the first thread calling this function.
    +  //   - EXECUTING_CLOSURE: Another thread is already executing the closure.
    +  //
    +  // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE
    +  // atomically.
    +  state = internal::Acquire_CompareAndSwap(
    +      once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE);
    +  if (state == ONCE_STATE_UNINITIALIZED) {
    +    // We are the first thread to call this function, so we have to call the
    +    // closure.
    +    closure->Run();
    +    internal::Release_Store(once, ONCE_STATE_DONE);
    +  } else {
    +    // Another thread has already started executing the closure. We need to
    +    // wait until it completes the initialization.
    +    while (state == ONCE_STATE_EXECUTING_CLOSURE) {
    +      // Note that futex() could be used here on Linux as an improvement.
    +      SchedYield();
    +      state = internal::Acquire_Load(once);
    +    }
    +  }
    +}
     
     }  // namespace protobuf
     }  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
    diff --git a/toolkit/components/protobuf/google/protobuf/stubs/once.h b/toolkit/components/protobuf/src/google/protobuf/stubs/once.h
    similarity index 61%
    rename from toolkit/components/protobuf/google/protobuf/stubs/once.h
    rename to toolkit/components/protobuf/src/google/protobuf/stubs/once.h
    index 0dee407662be..cc62bbaab38b 100644
    --- a/toolkit/components/protobuf/google/protobuf/stubs/once.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/once.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -37,16 +37,22 @@
     //
     // This is basically a portable version of pthread_once().
     //
    -// This header declares three things:
    +// This header declares:
     // * A type called ProtobufOnceType.
     // * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type
     //   ProtobufOnceType.  This is the only legal way to declare such a variable.
    -//   The macro may only be used at the global scope (you cannot create local
    -//   or class member variables of this type).
    -// * A function GogoleOnceInit(ProtobufOnceType* once, void (*init_func)()).
    +//   The macro may only be used at the global scope (you cannot create local or
    +//   class member variables of this type).
    +// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()).
     //   This function, when invoked multiple times given the same ProtobufOnceType
     //   object, will invoke init_func on the first call only, and will make sure
     //   none of the calls return before that first call to init_func has finished.
    +// * The user can provide a parameter which GoogleOnceInit() forwards to the
    +//   user-provided function when it is called. Usage example:
    +//     int a = 10;
    +//     GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a);
    +// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no
    +//   static initializer generated).
     //
     // This implements a way to perform lazy initialization.  It's more efficient
     // than using mutexes as no lock is needed if initialization has already
    @@ -72,50 +78,87 @@
     #ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
     #define GOOGLE_PROTOBUF_STUBS_ONCE_H__
     
    +#include 
     #include 
     
    -#ifndef _WIN32
    -#include 
    -#endif
    -
     namespace google {
     namespace protobuf {
     
    -#ifdef _WIN32
    +#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
     
    -struct ProtobufOnceInternal;
    +typedef bool ProtobufOnceType;
     
    -struct LIBPROTOBUF_EXPORT ProtobufOnceType {
    -  ProtobufOnceType();
    -  ~ProtobufOnceType();
    -  void Init(void (*init_func)());
    -
    -  volatile bool initialized_;
    -  ProtobufOnceInternal* internal_;
    -};
    -
    -#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME)                    \
    -  ::google::protobuf::ProtobufOnceType NAME
    +#define GOOGLE_PROTOBUF_ONCE_INIT false
     
     inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
    -  // Note:  Double-checked locking is safe on x86.
    -  if (!once->initialized_) {
    -    once->Init(init_func);
    +  if (!*once) {
    +    *once = true;
    +    init_func();
    +  }
    +}
    +
    +template 
    +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg),
    +    Arg arg) {
    +  if (!*once) {
    +    *once = true;
    +    init_func(arg);
       }
     }
     
     #else
     
    -typedef pthread_once_t ProtobufOnceType;
    +enum {
    +  ONCE_STATE_UNINITIALIZED = 0,
    +  ONCE_STATE_EXECUTING_CLOSURE = 1,
    +  ONCE_STATE_DONE = 2
    +};
     
    -#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME)                    \
    -  pthread_once_t NAME = PTHREAD_ONCE_INIT
    +typedef internal::AtomicWord ProtobufOnceType;
    +
    +#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED
    +
    +LIBPROTOBUF_EXPORT
    +void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure);
     
     inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
    -  pthread_once(once, init_func);
    +  if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
    +    internal::FunctionClosure0 func(init_func, false);
    +    GoogleOnceInitImpl(once, &func);
    +  }
     }
     
    -#endif
    +template 
    +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*),
    +    Arg* arg) {
    +  if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
    +    internal::FunctionClosure1 func(init_func, false, arg);
    +    GoogleOnceInitImpl(once, &func);
    +  }
    +}
    +
    +#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
    +
    +class GoogleOnceDynamic {
    + public:
    +  GoogleOnceDynamic() : state_(GOOGLE_PROTOBUF_ONCE_INIT) { }
    +
    +  // If this->Init() has not been called before by any thread,
    +  // execute (*func_with_arg)(arg) then return.
    +  // Otherwise, wait until that prior invocation has finished
    +  // executing its function, then return.
    +  template
    +  void Init(void (*func_with_arg)(T*), T* arg) {
    +    GoogleOnceInit(&this->state_,
    +                      func_with_arg,
    +                      arg);
    +  }
    + private:
    +  ProtobufOnceType state_;
    +};
    +
    +#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
    +  ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT
     
     }  // namespace protobuf
     }  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h b/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
    new file mode 100644
    index 000000000000..7956d076dcd5
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
    @@ -0,0 +1,103 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +#ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
    +#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
    +
    +#include 
    +
    +#define GOOGLE_PROTOBUF_PLATFORM_ERROR \
    +#error "Host platform was not detected as supported by protobuf"
    +
    +// Processor architecture detection.  For more info on what's defined, see:
    +//   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
    +//   http://www.agner.org/optimize/calling_conventions.pdf
    +//   or with gcc, run: "echo | gcc -E -dM -"
    +#if defined(_M_X64) || defined(__x86_64__)
    +#define GOOGLE_PROTOBUF_ARCH_X64 1
    +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
    +#elif defined(_M_IX86) || defined(__i386__)
    +#define GOOGLE_PROTOBUF_ARCH_IA32 1
    +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
    +#elif defined(__QNX__)
    +#define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1
    +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
    +#elif defined(__ARMEL__)
    +#define GOOGLE_PROTOBUF_ARCH_ARM 1
    +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
    +#elif defined(__aarch64__)
    +#define GOOGLE_PROTOBUF_ARCH_AARCH64 1
    +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
    +#elif defined(__MIPSEL__)
    +#if defined(__LP64__)
    +#define GOOGLE_PROTOBUF_ARCH_MIPS64 1
    +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
    +#else
    +#define GOOGLE_PROTOBUF_ARCH_MIPS 1
    +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
    +#endif
    +#elif defined(__pnacl__)
    +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
    +#elif defined(sparc)
    +#define GOOGLE_PROTOBUF_ARCH_SPARC 1
    +#ifdef SOLARIS_64BIT_ENABLED
    +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
    +#else
    +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
    +#endif
    +#elif defined(__GNUC__)
    +# if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
    +// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
    +# elif defined(__clang__)
    +#  if !__has_extension(c_atomic)
    +GOOGLE_PROTOBUF_PLATFORM_ERROR
    +#  endif
    +// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
    +# endif
    +# if __LP64__
    +#  define GOOGLE_PROTOBUF_ARCH_64_BIT 1
    +# else
    +#  define GOOGLE_PROTOBUF_ARCH_32_BIT 1
    +# endif
    +#else
    +GOOGLE_PROTOBUF_PLATFORM_ERROR
    +#endif
    +
    +#if defined(__APPLE__)
    +#define GOOGLE_PROTOBUF_OS_APPLE
    +#elif defined(__native_client__)
    +#define GOOGLE_PROTOBUF_OS_NACL
    +#elif defined(sun)
    +#define GOOGLE_PROTOBUF_OS_SOLARIS
    +#endif
    +
    +#undef GOOGLE_PROTOBUF_PLATFORM_ERROR
    +
    +#endif  // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/shared_ptr.h b/toolkit/components/protobuf/src/google/protobuf/stubs/shared_ptr.h
    new file mode 100644
    index 000000000000..d250bf4d3385
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/shared_ptr.h
    @@ -0,0 +1,470 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2014 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// from google3/util/gtl/shared_ptr.h
    +
    +#ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
    +#define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
    +
    +#include 
    +
    +#include   // for swap
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// Alias to std::shared_ptr for any C++11 platform,
    +// and for any supported MSVC compiler.
    +#if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \
    +    (defined(COMPILER_MSVC) || defined(LANG_CXX11))
    +#define UTIL_GTL_USE_STD_SHARED_PTR 1
    +#endif
    +
    +#if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR
    +
    +// These are transitional.  They will be going away soon.
    +// Please just #include  and just type std::shared_ptr yourself, instead
    +// of relying on this file.
    +//
    +// Migration doc: http://go/std-shared-ptr-lsc
    +using std::enable_shared_from_this;
    +using std::shared_ptr;
    +using std::static_pointer_cast;
    +using std::weak_ptr;
    +
    +#else  // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0.
    +
    +// For everything else there is the google3 implementation.
    +inline bool RefCountDec(volatile Atomic32 *ptr) {
    +  return Barrier_AtomicIncrement(ptr, -1) != 0;
    +}
    +
    +inline void RefCountInc(volatile Atomic32 *ptr) {
    +  NoBarrier_AtomicIncrement(ptr, 1);
    +}
    +
    +template  class shared_ptr;
    +template  class weak_ptr;
    +
    +// This class is an internal implementation detail for shared_ptr. If two
    +// shared_ptrs point to the same object, they also share a control block.
    +// An "empty" shared_pointer refers to NULL and also has a NULL control block.
    +// It contains all of the state that's needed for reference counting or any
    +// other kind of resource management. In this implementation the control block
    +// happens to consist of two atomic words, the reference count (the number
    +// of shared_ptrs that share ownership of the object) and the weak count
    +// (the number of weak_ptrs that observe the object, plus 1 if the
    +// refcount is nonzero).
    +//
    +// The "plus 1" is to prevent a race condition in the shared_ptr and
    +// weak_ptr destructors. We need to make sure the control block is
    +// only deleted once, so we need to make sure that at most one
    +// object sees the weak count decremented from 1 to 0.
    +class SharedPtrControlBlock {
    +  template  friend class shared_ptr;
    +  template  friend class weak_ptr;
    + private:
    +  SharedPtrControlBlock() : refcount_(1), weak_count_(1) { }
    +  Atomic32 refcount_;
    +  Atomic32 weak_count_;
    +};
    +
    +// Forward declaration. The class is defined below.
    +template  class enable_shared_from_this;
    +
    +template 
    +class shared_ptr {
    +  template  friend class weak_ptr;
    + public:
    +  typedef T element_type;
    +
    +  shared_ptr() : ptr_(NULL), control_block_(NULL) {}
    +
    +  explicit shared_ptr(T* ptr)
    +      : ptr_(ptr),
    +        control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) {
    +    // If p is non-null and T inherits from enable_shared_from_this, we
    +    // set up the data that shared_from_this needs.
    +    MaybeSetupWeakThis(ptr);
    +  }
    +
    +  // Copy constructor: makes this object a copy of ptr, and increments
    +  // the reference count.
    +  template 
    +  shared_ptr(const shared_ptr& ptr)
    +      : ptr_(NULL),
    +        control_block_(NULL) {
    +    Initialize(ptr);
    +  }
    +  // Need non-templated version to prevent the compiler-generated default
    +  shared_ptr(const shared_ptr& ptr)
    +      : ptr_(NULL),
    +        control_block_(NULL) {
    +    Initialize(ptr);
    +  }
    +
    +  // Assignment operator. Replaces the existing shared_ptr with ptr.
    +  // Increment ptr's reference count and decrement the one being replaced.
    +  template 
    +  shared_ptr& operator=(const shared_ptr& ptr) {
    +    if (ptr_ != ptr.ptr_) {
    +      shared_ptr me(ptr);   // will hold our previous state to be destroyed.
    +      swap(me);
    +    }
    +    return *this;
    +  }
    +
    +  // Need non-templated version to prevent the compiler-generated default
    +  shared_ptr& operator=(const shared_ptr& ptr) {
    +    if (ptr_ != ptr.ptr_) {
    +      shared_ptr me(ptr);   // will hold our previous state to be destroyed.
    +      swap(me);
    +    }
    +    return *this;
    +  }
    +
    +  // TODO(austern): Consider providing this constructor. The draft C++ standard
    +  // (20.8.10.2.1) includes it. However, it says that this constructor throws
    +  // a bad_weak_ptr exception when ptr is expired. Is it better to provide this
    +  // constructor and make it do something else, like fail with a CHECK, or to
    +  // leave this constructor out entirely?
    +  //
    +  // template 
    +  // shared_ptr(const weak_ptr& ptr);
    +
    +  ~shared_ptr() {
    +    if (ptr_ != NULL) {
    +      if (!RefCountDec(&control_block_->refcount_)) {
    +        delete ptr_;
    +
    +        // weak_count_ is defined as the number of weak_ptrs that observe
    +        // ptr_, plus 1 if refcount_ is nonzero.
    +        if (!RefCountDec(&control_block_->weak_count_)) {
    +          delete control_block_;
    +        }
    +      }
    +    }
    +  }
    +
    +  // Replaces underlying raw pointer with the one passed in.  The reference
    +  // count is set to one (or zero if the pointer is NULL) for the pointer
    +  // being passed in and decremented for the one being replaced.
    +  //
    +  // If you have a compilation error with this code, make sure you aren't
    +  // passing NULL, nullptr, or 0 to this function.  Call reset without an
    +  // argument to reset to a null ptr.
    +  template 
    +  void reset(Y* p) {
    +    if (p != ptr_) {
    +      shared_ptr tmp(p);
    +      tmp.swap(*this);
    +    }
    +  }
    +
    +  void reset() {
    +    reset(static_cast(NULL));
    +  }
    +
    +  // Exchanges the contents of this with the contents of r.  This function
    +  // supports more efficient swapping since it eliminates the need for a
    +  // temporary shared_ptr object.
    +  void swap(shared_ptr& r) {
    +    using std::swap;  // http://go/using-std-swap
    +    swap(ptr_, r.ptr_);
    +    swap(control_block_, r.control_block_);
    +  }
    +
    +  // The following function is useful for gaining access to the underlying
    +  // pointer when a shared_ptr remains in scope so the reference-count is
    +  // known to be > 0 (e.g. for parameter passing).
    +  T* get() const {
    +    return ptr_;
    +  }
    +
    +  T& operator*() const {
    +    return *ptr_;
    +  }
    +
    +  T* operator->() const {
    +    return ptr_;
    +  }
    +
    +  long use_count() const {
    +    return control_block_ ? control_block_->refcount_ : 1;
    +  }
    +
    +  bool unique() const {
    +    return use_count() == 1;
    +  }
    +
    + private:
    +  // If r is non-empty, initialize *this to share ownership with r,
    +  // increasing the underlying reference count.
    +  // If r is empty, *this remains empty.
    +  // Requires: this is empty, namely this->ptr_ == NULL.
    +  template 
    +  void Initialize(const shared_ptr& r) {
    +    // This performs a static_cast on r.ptr_ to U*, which is a no-op since it
    +    // is already a U*. So initialization here requires that r.ptr_ is
    +    // implicitly convertible to T*.
    +    InitializeWithStaticCast(r);
    +  }
    +
    +  // Initializes *this as described in Initialize, but additionally performs a
    +  // static_cast from r.ptr_ (V*) to U*.
    +  // NOTE(gfc): We'd need a more general form to support const_pointer_cast and
    +  // dynamic_pointer_cast, but those operations are sufficiently discouraged
    +  // that supporting static_pointer_cast is sufficient.
    +  template 
    +  void InitializeWithStaticCast(const shared_ptr& r) {
    +    if (r.control_block_ != NULL) {
    +      RefCountInc(&r.control_block_->refcount_);
    +
    +      ptr_ = static_cast(r.ptr_);
    +      control_block_ = r.control_block_;
    +    }
    +  }
    +
    +  // Helper function for the constructor that takes a raw pointer. If T
    +  // doesn't inherit from enable_shared_from_this then we have nothing to
    +  // do, so this function is trivial and inline. The other version is declared
    +  // out of line, after the class definition of enable_shared_from_this.
    +  void MaybeSetupWeakThis(enable_shared_from_this* ptr);
    +  void MaybeSetupWeakThis(...) { }
    +
    +  T* ptr_;
    +  SharedPtrControlBlock* control_block_;
    +
    +#ifndef SWIG
    +  template 
    +  friend class shared_ptr;
    +
    +  template 
    +  friend shared_ptr static_pointer_cast(const shared_ptr& rhs);
    +#endif
    +};
    +
    +// Matches the interface of std::swap as an aid to generic programming.
    +template  void swap(shared_ptr& r, shared_ptr& s) {
    +  r.swap(s);
    +}
    +
    +template 
    +shared_ptr static_pointer_cast(const shared_ptr& rhs) {
    +  shared_ptr lhs;
    +  lhs.template InitializeWithStaticCast(rhs);
    +  return lhs;
    +}
    +
    +// See comments at the top of the file for a description of why this
    +// class exists, and the draft C++ standard (as of July 2009 the
    +// latest draft is N2914) for the detailed specification.
    +template 
    +class weak_ptr {
    +  template  friend class weak_ptr;
    + public:
    +  typedef T element_type;
    +
    +  // Create an empty (i.e. already expired) weak_ptr.
    +  weak_ptr() : ptr_(NULL), control_block_(NULL) { }
    +
    +  // Create a weak_ptr that observes the same object that ptr points
    +  // to.  Note that there is no race condition here: we know that the
    +  // control block can't disappear while we're looking at it because
    +  // it is owned by at least one shared_ptr, ptr.
    +  template  weak_ptr(const shared_ptr& ptr) {
    +    CopyFrom(ptr.ptr_, ptr.control_block_);
    +  }
    +
    +  // Copy a weak_ptr. The object it points to might disappear, but we
    +  // don't care: we're only working with the control block, and it can't
    +  // disappear while we're looking at because it's owned by at least one
    +  // weak_ptr, ptr.
    +  template  weak_ptr(const weak_ptr& ptr) {
    +    CopyFrom(ptr.ptr_, ptr.control_block_);
    +  }
    +
    +  // Need non-templated version to prevent default copy constructor
    +  weak_ptr(const weak_ptr& ptr) {
    +    CopyFrom(ptr.ptr_, ptr.control_block_);
    +  }
    +
    +  // Destroy the weak_ptr. If no shared_ptr owns the control block, and if
    +  // we are the last weak_ptr to own it, then it can be deleted. Note that
    +  // weak_count_ is defined as the number of weak_ptrs sharing this control
    +  // block, plus 1 if there are any shared_ptrs. We therefore know that it's
    +  // safe to delete the control block when weak_count_ reaches 0, without
    +  // having to perform any additional tests.
    +  ~weak_ptr() {
    +    if (control_block_ != NULL &&
    +        !RefCountDec(&control_block_->weak_count_)) {
    +      delete control_block_;
    +    }
    +  }
    +
    +  weak_ptr& operator=(const weak_ptr& ptr) {
    +    if (&ptr != this) {
    +      weak_ptr tmp(ptr);
    +      tmp.swap(*this);
    +    }
    +    return *this;
    +  }
    +  template  weak_ptr& operator=(const weak_ptr& ptr) {
    +    weak_ptr tmp(ptr);
    +    tmp.swap(*this);
    +    return *this;
    +  }
    +  template  weak_ptr& operator=(const shared_ptr& ptr) {
    +    weak_ptr tmp(ptr);
    +    tmp.swap(*this);
    +    return *this;
    +  }
    +
    +  void swap(weak_ptr& ptr) {
    +    using std::swap;  // http://go/using-std-swap
    +    swap(ptr_, ptr.ptr_);
    +    swap(control_block_, ptr.control_block_);
    +  }
    +
    +  void reset() {
    +    weak_ptr tmp;
    +    tmp.swap(*this);
    +  }
    +
    +  // Return the number of shared_ptrs that own the object we are observing.
    +  // Note that this number can be 0 (if this pointer has expired).
    +  long use_count() const {
    +    return control_block_ != NULL ? control_block_->refcount_ : 0;
    +  }
    +
    +  bool expired() const { return use_count() == 0; }
    +
    +  // Return a shared_ptr that owns the object we are observing. If we
    +  // have expired, the shared_ptr will be empty. We have to be careful
    +  // about concurrency, though, since some other thread might be
    +  // destroying the last owning shared_ptr while we're in this
    +  // function.  We want to increment the refcount only if it's nonzero
    +  // and get the new value, and we want that whole operation to be
    +  // atomic.
    +  shared_ptr lock() const {
    +    shared_ptr result;
    +    if (control_block_ != NULL) {
    +      Atomic32 old_refcount;
    +      do {
    +        old_refcount = control_block_->refcount_;
    +        if (old_refcount == 0)
    +          break;
    +      } while (old_refcount !=
    +               NoBarrier_CompareAndSwap(
    +                   &control_block_->refcount_, old_refcount,
    +                   old_refcount + 1));
    +      if (old_refcount > 0) {
    +        result.ptr_ = ptr_;
    +        result.control_block_ = control_block_;
    +      }
    +    }
    +
    +    return result;
    +  }
    +
    + private:
    +  void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) {
    +    ptr_ = ptr;
    +    control_block_ = control_block;
    +    if (control_block_ != NULL)
    +      RefCountInc(&control_block_->weak_count_);
    +  }
    +
    + private:
    +  element_type* ptr_;
    +  SharedPtrControlBlock* control_block_;
    +};
    +
    +template  void swap(weak_ptr& r, weak_ptr& s) {
    +  r.swap(s);
    +}
    +
    +// See comments at the top of the file for a description of why this class
    +// exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009
    +// the latest draft is N2914) for the detailed specification.
    +template 
    +class enable_shared_from_this {
    +  friend class shared_ptr;
    + public:
    +  // Precondition: there must be a shared_ptr that owns *this and that was
    +  // created, directly or indirectly, from a raw pointer of type T*. (The
    +  // latter part of the condition is technical but not quite redundant; it
    +  // rules out some complicated uses involving inheritance hierarchies.)
    +  shared_ptr shared_from_this() {
    +    // Behavior is undefined if the precondition isn't satisfied; we choose
    +    // to die with a CHECK failure.
    +    CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
    +    return weak_this_.lock();
    +  }
    +  shared_ptr shared_from_this() const {
    +    CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
    +    return weak_this_.lock();
    +  }
    +
    + protected:
    +  enable_shared_from_this() { }
    +  enable_shared_from_this(const enable_shared_from_this& other) { }
    +  enable_shared_from_this& operator=(const enable_shared_from_this& other) {
    +    return *this;
    +  }
    +  ~enable_shared_from_this() { }
    +
    + private:
    +  weak_ptr weak_this_;
    +};
    +
    +// This is a helper function called by shared_ptr's constructor from a raw
    +// pointer. If T inherits from enable_shared_from_this, it sets up
    +// weak_this_ so that shared_from_this works correctly. If T does not inherit
    +// from weak_this we get a different overload, defined inline, which does
    +// nothing.
    +template
    +void shared_ptr::MaybeSetupWeakThis(enable_shared_from_this* ptr) {
    +  if (ptr) {
    +    CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr";
    +    ptr->weak_this_ = *this;
    +  }
    +}
    +
    +#endif  // UTIL_GTL_USE_STD_SHARED_PTR
    +
    +}  // internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/stubs/stl_util-inl.h b/toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h
    similarity index 95%
    rename from toolkit/components/protobuf/google/protobuf/stubs/stl_util-inl.h
    rename to toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h
    index a2e671bb7461..9e4c82a4c3be 100644
    --- a/toolkit/components/protobuf/google/protobuf/stubs/stl_util-inl.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/stl_util.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -28,10 +28,10 @@
     // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     
    -// from google3/util/gtl/stl_util-inl.h
    +// from google3/util/gtl/stl_util.h
     
    -#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
    -#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
    +#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
    +#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
     
     #include 
     
    @@ -118,4 +118,4 @@ void STLDeleteValues(T *v) {
     }  // namespace protobuf
     }  // namespace google
     
    -#endif  // GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
    +#endif  // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc
    new file mode 100644
    index 000000000000..83fdfe454e90
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc
    @@ -0,0 +1,174 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// from google3/base/stringprintf.cc
    +
    +#include 
    +
    +#include 
    +#include  // For va_list and related operations
    +#include  // MSVC requires this for _vsnprintf
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +#ifdef _MSC_VER
    +enum { IS_COMPILER_MSVC = 1 };
    +#ifndef va_copy
    +// Define va_copy for MSVC. This is a hack, assuming va_list is simply a
    +// pointer into the stack and is safe to copy.
    +#define va_copy(dest, src) ((dest) = (src))
    +#endif
    +#else
    +enum { IS_COMPILER_MSVC = 0 };
    +#endif
    +
    +void StringAppendV(string* dst, const char* format, va_list ap) {
    +  // First try with a small fixed size buffer
    +  static const int kSpaceLength = 1024;
    +  char space[kSpaceLength];
    +
    +  // It's possible for methods that use a va_list to invalidate
    +  // the data in it upon use.  The fix is to make a copy
    +  // of the structure before using it and use that copy instead.
    +  va_list backup_ap;
    +  va_copy(backup_ap, ap);
    +  int result = vsnprintf(space, kSpaceLength, format, backup_ap);
    +  va_end(backup_ap);
    +
    +  if (result < kSpaceLength) {
    +    if (result >= 0) {
    +      // Normal case -- everything fit.
    +      dst->append(space, result);
    +      return;
    +    }
    +
    +    if (IS_COMPILER_MSVC) {
    +      // Error or MSVC running out of space.  MSVC 8.0 and higher
    +      // can be asked about space needed with the special idiom below:
    +      va_copy(backup_ap, ap);
    +      result = vsnprintf(NULL, 0, format, backup_ap);
    +      va_end(backup_ap);
    +    }
    +
    +    if (result < 0) {
    +      // Just an error.
    +      return;
    +    }
    +  }
    +
    +  // Increase the buffer size to the size requested by vsnprintf,
    +  // plus one for the closing \0.
    +  int length = result+1;
    +  char* buf = new char[length];
    +
    +  // Restore the va_list before we use it again
    +  va_copy(backup_ap, ap);
    +  result = vsnprintf(buf, length, format, backup_ap);
    +  va_end(backup_ap);
    +
    +  if (result >= 0 && result < length) {
    +    // It fit
    +    dst->append(buf, result);
    +  }
    +  delete[] buf;
    +}
    +
    +
    +string StringPrintf(const char* format, ...) {
    +  va_list ap;
    +  va_start(ap, format);
    +  string result;
    +  StringAppendV(&result, format, ap);
    +  va_end(ap);
    +  return result;
    +}
    +
    +const string& SStringPrintf(string* dst, const char* format, ...) {
    +  va_list ap;
    +  va_start(ap, format);
    +  dst->clear();
    +  StringAppendV(dst, format, ap);
    +  va_end(ap);
    +  return *dst;
    +}
    +
    +void StringAppendF(string* dst, const char* format, ...) {
    +  va_list ap;
    +  va_start(ap, format);
    +  StringAppendV(dst, format, ap);
    +  va_end(ap);
    +}
    +
    +// Max arguments supported by StringPrintVector
    +const int kStringPrintfVectorMaxArgs = 32;
    +
    +// An empty block of zero for filler arguments.  This is const so that if
    +// printf tries to write to it (via %n) then the program gets a SIGSEGV
    +// and we can fix the problem or protect against an attack.
    +static const char string_printf_empty_block[256] = { '\0' };
    +
    +string StringPrintfVector(const char* format, const vector& v) {
    +  GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs)
    +      << "StringPrintfVector currently only supports up to "
    +      << kStringPrintfVectorMaxArgs << " arguments. "
    +      << "Feel free to add support for more if you need it.";
    +
    +  // Add filler arguments so that bogus format+args have a harder time
    +  // crashing the program, corrupting the program (%n),
    +  // or displaying random chunks of memory to users.
    +
    +  const char* cstr[kStringPrintfVectorMaxArgs];
    +  for (int i = 0; i < v.size(); ++i) {
    +    cstr[i] = v[i].c_str();
    +  }
    +  for (int i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) {
    +    cstr[i] = &string_printf_empty_block[0];
    +  }
    +
    +  // I do not know any way to pass kStringPrintfVectorMaxArgs arguments,
    +  // or any way to build a va_list by hand, or any API for printf
    +  // that accepts an array of arguments.  The best I can do is stick
    +  // this COMPILE_ASSERT right next to the actual statement.
    +
    +  GOOGLE_COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch);
    +  return StringPrintf(format,
    +                      cstr[0], cstr[1], cstr[2], cstr[3], cstr[4],
    +                      cstr[5], cstr[6], cstr[7], cstr[8], cstr[9],
    +                      cstr[10], cstr[11], cstr[12], cstr[13], cstr[14],
    +                      cstr[15], cstr[16], cstr[17], cstr[18], cstr[19],
    +                      cstr[20], cstr[21], cstr[22], cstr[23], cstr[24],
    +                      cstr[25], cstr[26], cstr[27], cstr[28], cstr[29],
    +                      cstr[30], cstr[31]);
    +}
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h b/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h
    new file mode 100644
    index 000000000000..ab1ab558329e
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h
    @@ -0,0 +1,76 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2012 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// from google3/base/stringprintf.h
    +//
    +// Printf variants that place their output in a C++ string.
    +//
    +// Usage:
    +//      string result = StringPrintf("%d %s\n", 10, "hello");
    +//      SStringPrintf(&result, "%d %s\n", 10, "hello");
    +//      StringAppendF(&result, "%d %s\n", 20, "there");
    +
    +#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
    +#define GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +// Return a C++ string
    +LIBPROTOBUF_EXPORT extern string StringPrintf(const char* format, ...);
    +
    +// Store result into a supplied string and return it
    +LIBPROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, const char* format, ...);
    +
    +// Append result to a supplied string
    +LIBPROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...);
    +
    +// Lower-level routine that takes a va_list and appends to a specified
    +// string.  All other routines are just convenience wrappers around it.
    +LIBPROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, va_list ap);
    +
    +// The max arguments supported by StringPrintfVector
    +LIBPROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs;
    +
    +// You can use this version when all your arguments are strings, but
    +// you don't know how many arguments you'll have at compile time.
    +// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs
    +LIBPROTOBUF_EXPORT extern string StringPrintfVector(const char* format, const vector& v);
    +
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc
    new file mode 100644
    index 000000000000..0f6afe6dc8e1
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc
    @@ -0,0 +1,536 @@
    +// Copyright 2005-2008 Google Inc. All Rights Reserved.
    +// Author: jrm@google.com (Jim Meehan)
    +
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// These four-byte entries compactly encode how many bytes 0..255 to delete
    +// in making a string replacement, how many bytes to add 0..255, and the offset
    +// 0..64k-1 of the replacement string in remap_string.
    +struct RemapEntry {
    +  uint8 delete_bytes;
    +  uint8 add_bytes;
    +  uint16 bytes_offset;
    +};
    +
    +// Exit type codes for state tables. All but the first get stuffed into
    +// signed one-byte entries. The first is only generated by executable code.
    +// To distinguish from next-state entries, these must be contiguous and
    +// all <= kExitNone
    +typedef enum {
    +  kExitDstSpaceFull = 239,
    +  kExitIllegalStructure,  // 240
    +  kExitOK,                // 241
    +  kExitReject,            // ...
    +  kExitReplace1,
    +  kExitReplace2,
    +  kExitReplace3,
    +  kExitReplace21,
    +  kExitReplace31,
    +  kExitReplace32,
    +  kExitReplaceOffset1,
    +  kExitReplaceOffset2,
    +  kExitReplace1S0,
    +  kExitSpecial,
    +  kExitDoAgain,
    +  kExitRejectAlt,
    +  kExitNone               // 255
    +} ExitReason;
    +
    +
    +// This struct represents one entire state table. The three initialized byte
    +// areas are state_table, remap_base, and remap_string. state0 and state0_size
    +// give the byte offset and length within state_table of the initial state --
    +// table lookups are expected to start and end in this state, but for
    +// truncated UTF-8 strings, may end in a different state. These allow a quick
    +// test for that condition. entry_shift is 8 for tables subscripted by a full
    +// byte value and 6 for space-optimized tables subscripted by only six
    +// significant bits in UTF-8 continuation bytes.
    +typedef struct {
    +  const uint32 state0;
    +  const uint32 state0_size;
    +  const uint32 total_size;
    +  const int max_expand;
    +  const int entry_shift;
    +  const int bytes_per_entry;
    +  const uint32 losub;
    +  const uint32 hiadd;
    +  const uint8* state_table;
    +  const RemapEntry* remap_base;
    +  const uint8* remap_string;
    +  const uint8* fast_state;
    +} UTF8StateMachineObj;
    +
    +typedef UTF8StateMachineObj UTF8ScanObj;
    +
    +#define X__ (kExitIllegalStructure)
    +#define RJ_ (kExitReject)
    +#define S1_ (kExitReplace1)
    +#define S2_ (kExitReplace2)
    +#define S3_ (kExitReplace3)
    +#define S21 (kExitReplace21)
    +#define S31 (kExitReplace31)
    +#define S32 (kExitReplace32)
    +#define T1_ (kExitReplaceOffset1)
    +#define T2_ (kExitReplaceOffset2)
    +#define S11 (kExitReplace1S0)
    +#define SP_ (kExitSpecial)
    +#define D__ (kExitDoAgain)
    +#define RJA (kExitRejectAlt)
    +
    +//  Entire table has 9 state blocks of 256 entries each
    +static const unsigned int utf8acceptnonsurrogates_STATE0 = 0;     // state[0]
    +static const unsigned int utf8acceptnonsurrogates_STATE0_SIZE = 256;  // =[1]
    +static const unsigned int utf8acceptnonsurrogates_TOTAL_SIZE = 2304;
    +static const unsigned int utf8acceptnonsurrogates_MAX_EXPAND_X4 = 0;
    +static const unsigned int utf8acceptnonsurrogates_SHIFT = 8;
    +static const unsigned int utf8acceptnonsurrogates_BYTES = 1;
    +static const unsigned int utf8acceptnonsurrogates_LOSUB = 0x20202020;
    +static const unsigned int utf8acceptnonsurrogates_HIADD = 0x00000000;
    +
    +static const uint8 utf8acceptnonsurrogates[] = {
    +// state[0] 0x000000 Byte 1
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  2,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   7,   3,   3,
    +  4,   5,   5,   5,   6, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[1] 0x000080 Byte 2 of 2
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[2] 0x000000 Byte 2 of 3
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[3] 0x001000 Byte 2 of 3
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[4] 0x000000 Byte 2 of 4
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[5] 0x040000 Byte 2 of 4
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[6] 0x100000 Byte 2 of 4
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[7] 0x00d000 Byte 2 of 3
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
    +  8,   8,   8,   8,   8,   8,   8,   8,    8,   8,   8,   8,   8,   8,   8,   8,
    +  8,   8,   8,   8,   8,   8,   8,   8,    8,   8,   8,   8,   8,   8,   8,   8,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +// state[8] 0x00d800 Byte 3 of 3
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +
    +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
    +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
    +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
    +RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
    +
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
    +};
    +
    +// Remap base[0] = (del, add, string_offset)
    +static const RemapEntry utf8acceptnonsurrogates_remap_base[] = {
    +{0, 0, 0} };
    +
    +// Remap string[0]
    +static const unsigned char utf8acceptnonsurrogates_remap_string[] = {
    +0 };
    +
    +static const unsigned char utf8acceptnonsurrogates_fast[256] = {
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
    +
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
    +};
    +
    +static const UTF8ScanObj utf8acceptnonsurrogates_obj = {
    +  utf8acceptnonsurrogates_STATE0,
    +  utf8acceptnonsurrogates_STATE0_SIZE,
    +  utf8acceptnonsurrogates_TOTAL_SIZE,
    +  utf8acceptnonsurrogates_MAX_EXPAND_X4,
    +  utf8acceptnonsurrogates_SHIFT,
    +  utf8acceptnonsurrogates_BYTES,
    +  utf8acceptnonsurrogates_LOSUB,
    +  utf8acceptnonsurrogates_HIADD,
    +  utf8acceptnonsurrogates,
    +  utf8acceptnonsurrogates_remap_base,
    +  utf8acceptnonsurrogates_remap_string,
    +  utf8acceptnonsurrogates_fast
    +};
    +
    +
    +#undef X__
    +#undef RJ_
    +#undef S1_
    +#undef S2_
    +#undef S3_
    +#undef S21
    +#undef S31
    +#undef S32
    +#undef T1_
    +#undef T2_
    +#undef S11
    +#undef SP_
    +#undef D__
    +#undef RJA
    +
    +// Return true if current Tbl pointer is within state0 range
    +// Note that unsigned compare checks both ends of range simultaneously
    +static inline bool InStateZero(const UTF8ScanObj* st, const uint8* Tbl) {
    +  const uint8* Tbl0 = &st->state_table[st->state0];
    +  return (static_cast(Tbl - Tbl0) < st->state0_size);
    +}
    +
    +// Scan a UTF-8 string based on state table.
    +// Always scan complete UTF-8 characters
    +// Set number of bytes scanned. Return reason for exiting
    +int UTF8GenericScan(const UTF8ScanObj* st,
    +                    const char * str,
    +                    int str_length,
    +                    int* bytes_consumed) {
    +  *bytes_consumed = 0;
    +  if (str_length == 0) return kExitOK;
    +
    +  int eshift = st->entry_shift;
    +  const uint8* isrc = reinterpret_cast(str);
    +  const uint8* src = isrc;
    +  const uint8* srclimit = isrc + str_length;
    +  const uint8* srclimit8 = srclimit - 7;
    +  const uint8* Tbl_0 = &st->state_table[st->state0];
    +
    + DoAgain:
    +  // Do state-table scan
    +  int e = 0;
    +  uint8 c;
    +  const uint8* Tbl2 = &st->fast_state[0];
    +  const uint32 losub = st->losub;
    +  const uint32 hiadd = st->hiadd;
    +  // Check initial few bytes one at a time until 8-byte aligned
    +  //----------------------------
    +  while ((((uintptr_t)src & 0x07) != 0) &&
    +         (src < srclimit) &&
    +         Tbl2[src[0]] == 0) {
    +    src++;
    +  }
    +  if (((uintptr_t)src & 0x07) == 0) {
    +    // Do fast for groups of 8 identity bytes.
    +    // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop,
    +    // including slowing slightly on cr/lf/ht
    +    //----------------------------
    +    while (src < srclimit8) {
    +      uint32 s0123 = (reinterpret_cast(src))[0];
    +      uint32 s4567 = (reinterpret_cast(src))[1];
    +      src += 8;
    +      // This is a fast range check for all bytes in [lowsub..0x80-hiadd)
    +      uint32 temp = (s0123 - losub) | (s0123 + hiadd) |
    +                    (s4567 - losub) | (s4567 + hiadd);
    +      if ((temp & 0x80808080) != 0) {
    +        // We typically end up here on cr/lf/ht; src was incremented
    +        int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) |
    +                    (Tbl2[src[-6]] | Tbl2[src[-5]]);
    +        if (e0123 != 0) {
    +          src -= 8;
    +          break;
    +        }    // Exit on Non-interchange
    +        e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) |
    +                (Tbl2[src[-2]] | Tbl2[src[-1]]);
    +        if (e0123 != 0) {
    +          src -= 4;
    +          break;
    +        }    // Exit on Non-interchange
    +        // Else OK, go around again
    +      }
    +    }
    +  }
    +  //----------------------------
    +
    +  // Byte-at-a-time scan
    +  //----------------------------
    +  const uint8* Tbl = Tbl_0;
    +  while (src < srclimit) {
    +    c = *src;
    +    e = Tbl[c];
    +    src++;
    +    if (e >= kExitIllegalStructure) {break;}
    +    Tbl = &Tbl_0[e << eshift];
    +  }
    +  //----------------------------
    +
    +
    +  // Exit posibilities:
    +  //  Some exit code, !state0, back up over last char
    +  //  Some exit code, state0, back up one byte exactly
    +  //  source consumed, !state0, back up over partial char
    +  //  source consumed, state0, exit OK
    +  // For illegal byte in state0, avoid backup up over PREVIOUS char
    +  // For truncated last char, back up to beginning of it
    +
    +  if (e >= kExitIllegalStructure) {
    +    // Back up over exactly one byte of rejected/illegal UTF-8 character
    +    src--;
    +    // Back up more if needed
    +    if (!InStateZero(st, Tbl)) {
    +      do {
    +        src--;
    +      } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
    +    }
    +  } else if (!InStateZero(st, Tbl)) {
    +    // Back up over truncated UTF-8 character
    +    e = kExitIllegalStructure;
    +    do {
    +      src--;
    +    } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
    +  } else {
    +    // Normal termination, source fully consumed
    +    e = kExitOK;
    +  }
    +
    +  if (e == kExitDoAgain) {
    +    // Loop back up to the fast scan
    +    goto DoAgain;
    +  }
    +
    +  *bytes_consumed = src - isrc;
    +  return e;
    +}
    +
    +int UTF8GenericScanFastAscii(const UTF8ScanObj* st,
    +                    const char * str,
    +                    int str_length,
    +                    int* bytes_consumed) {
    +  *bytes_consumed = 0;
    +  if (str_length == 0) return kExitOK;
    +
    +  const uint8* isrc =  reinterpret_cast(str);
    +  const uint8* src = isrc;
    +  const uint8* srclimit = isrc + str_length;
    +  const uint8* srclimit8 = srclimit - 7;
    +  int n;
    +  int rest_consumed;
    +  int exit_reason;
    +  do {
    +    // Check initial few bytes one at a time until 8-byte aligned
    +    while ((((uintptr_t)src & 0x07) != 0) &&
    +           (src < srclimit) && (src[0] < 0x80)) {
    +      src++;
    +    }
    +    if (((uintptr_t)src & 0x07) == 0) {
    +      while ((src < srclimit8) &&
    +             (((reinterpret_cast(src)[0] |
    +                reinterpret_cast(src)[1]) & 0x80808080) == 0)) {
    +        src += 8;
    +      }
    +    }
    +    while ((src < srclimit) && (src[0] < 0x80)) {
    +      src++;
    +    }
    +    // Run state table on the rest
    +    n = src - isrc;
    +    exit_reason = UTF8GenericScan(st, str + n, str_length - n, &rest_consumed);
    +    src += rest_consumed;
    +  } while ( exit_reason == kExitDoAgain );
    +
    +  *bytes_consumed = src - isrc;
    +  return exit_reason;
    +}
    +
    +// Hack:  On some compilers the static tables are initialized at startup.
    +//   We can't use them until they are initialized.  However, some Protocol
    +//   Buffer parsing happens at static init time and may try to validate
    +//   UTF-8 strings.  Since UTF-8 validation is only used for debugging
    +//   anyway, we simply always return success if initialization hasn't
    +//   occurred yet.
    +namespace {
    +
    +bool module_initialized_ = false;
    +
    +struct InitDetector {
    +  InitDetector() {
    +    module_initialized_ = true;
    +  }
    +};
    +InitDetector init_detector;
    +
    +}  // namespace
    +
    +bool IsStructurallyValidUTF8(const char* buf, int len) {
    +  if (!module_initialized_) return true;
    +  
    +  int bytes_consumed = 0;
    +  UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
    +                           buf, len, &bytes_consumed);
    +  return (bytes_consumed == len);
    +}
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc
    new file mode 100644
    index 000000000000..d7f673d10ad7
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc
    @@ -0,0 +1,1280 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// from google3/strings/strutil.cc
    +
    +#include 
    +#include 
    +#include     // FLT_DIG and DBL_DIG
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "mozilla/FloatingPoint.h"
    +
    +#ifdef _WIN32
    +// MSVC has only _snprintf, not snprintf.
    +//
    +// MinGW has both snprintf and _snprintf, but they appear to be different
    +// functions.  The former is buggy.  When invoked like so:
    +//   char buffer[32];
    +//   snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f);
    +// it prints "1.23000e+10".  This is plainly wrong:  %g should never print
    +// trailing zeros after the decimal point.  For some reason this bug only
    +// occurs with some input values, not all.  In any case, _snprintf does the
    +// right thing, so we use it.
    +#define snprintf _snprintf
    +#endif
    +
    +namespace google {
    +namespace protobuf {
    +
    +inline bool IsNaN(double value) {
    +  return ::mozilla::IsNaN(value);
    +}
    +
    +// These are defined as macros on some platforms.  #undef them so that we can
    +// redefine them.
    +#undef isxdigit
    +#undef isprint
    +
    +// The definitions of these in ctype.h change based on locale.  Since our
    +// string manipulation is all in relation to the protocol buffer and C++
    +// languages, we always want to use the C locale.  So, we re-define these
    +// exactly as we want them.
    +inline bool isxdigit(char c) {
    +  return ('0' <= c && c <= '9') ||
    +         ('a' <= c && c <= 'f') ||
    +         ('A' <= c && c <= 'F');
    +}
    +
    +inline bool isprint(char c) {
    +  return c >= 0x20 && c <= 0x7E;
    +}
    +
    +// ----------------------------------------------------------------------
    +// StripString
    +//    Replaces any occurrence of the character 'remove' (or the characters
    +//    in 'remove') with the character 'replacewith'.
    +// ----------------------------------------------------------------------
    +void StripString(string* s, const char* remove, char replacewith) {
    +  const char * str_start = s->c_str();
    +  const char * str = str_start;
    +  for (str = strpbrk(str, remove);
    +       str != NULL;
    +       str = strpbrk(str + 1, remove)) {
    +    (*s)[str - str_start] = replacewith;
    +  }
    +}
    +
    +// ----------------------------------------------------------------------
    +// StringReplace()
    +//    Replace the "old" pattern with the "new" pattern in a string,
    +//    and append the result to "res".  If replace_all is false,
    +//    it only replaces the first instance of "old."
    +// ----------------------------------------------------------------------
    +
    +void StringReplace(const string& s, const string& oldsub,
    +                   const string& newsub, bool replace_all,
    +                   string* res) {
    +  if (oldsub.empty()) {
    +    res->append(s);  // if empty, append the given string.
    +    return;
    +  }
    +
    +  string::size_type start_pos = 0;
    +  string::size_type pos;
    +  do {
    +    pos = s.find(oldsub, start_pos);
    +    if (pos == string::npos) {
    +      break;
    +    }
    +    res->append(s, start_pos, pos - start_pos);
    +    res->append(newsub);
    +    start_pos = pos + oldsub.size();  // start searching again after the "old"
    +  } while (replace_all);
    +  res->append(s, start_pos, s.length() - start_pos);
    +}
    +
    +// ----------------------------------------------------------------------
    +// StringReplace()
    +//    Give me a string and two patterns "old" and "new", and I replace
    +//    the first instance of "old" in the string with "new", if it
    +//    exists.  If "global" is true; call this repeatedly until it
    +//    fails.  RETURN a new string, regardless of whether the replacement
    +//    happened or not.
    +// ----------------------------------------------------------------------
    +
    +string StringReplace(const string& s, const string& oldsub,
    +                     const string& newsub, bool replace_all) {
    +  string ret;
    +  StringReplace(s, oldsub, newsub, replace_all, &ret);
    +  return ret;
    +}
    +
    +// ----------------------------------------------------------------------
    +// SplitStringUsing()
    +//    Split a string using a character delimiter. Append the components
    +//    to 'result'.
    +//
    +// Note: For multi-character delimiters, this routine will split on *ANY* of
    +// the characters in the string, not the entire string as a single delimiter.
    +// ----------------------------------------------------------------------
    +template 
    +static inline
    +void SplitStringToIteratorUsing(const string& full,
    +                                const char* delim,
    +                                ITR& result) {
    +  // Optimize the common case where delim is a single character.
    +  if (delim[0] != '\0' && delim[1] == '\0') {
    +    char c = delim[0];
    +    const char* p = full.data();
    +    const char* end = p + full.size();
    +    while (p != end) {
    +      if (*p == c) {
    +        ++p;
    +      } else {
    +        const char* start = p;
    +        while (++p != end && *p != c);
    +        *result++ = string(start, p - start);
    +      }
    +    }
    +    return;
    +  }
    +
    +  string::size_type begin_index, end_index;
    +  begin_index = full.find_first_not_of(delim);
    +  while (begin_index != string::npos) {
    +    end_index = full.find_first_of(delim, begin_index);
    +    if (end_index == string::npos) {
    +      *result++ = full.substr(begin_index);
    +      return;
    +    }
    +    *result++ = full.substr(begin_index, (end_index - begin_index));
    +    begin_index = full.find_first_not_of(delim, end_index);
    +  }
    +}
    +
    +void SplitStringUsing(const string& full,
    +                      const char* delim,
    +                      vector* result) {
    +  back_insert_iterator< vector > it(*result);
    +  SplitStringToIteratorUsing(full, delim, it);
    +}
    +
    +// Split a string using a character delimiter. Append the components
    +// to 'result'.  If there are consecutive delimiters, this function
    +// will return corresponding empty strings. The string is split into
    +// at most the specified number of pieces greedily. This means that the
    +// last piece may possibly be split further. To split into as many pieces
    +// as possible, specify 0 as the number of pieces.
    +//
    +// If "full" is the empty string, yields an empty string as the only value.
    +//
    +// If "pieces" is negative for some reason, it returns the whole string
    +// ----------------------------------------------------------------------
    +template 
    +static inline
    +void SplitStringToIteratorAllowEmpty(const StringType& full,
    +                                     const char* delim,
    +                                     int pieces,
    +                                     ITR& result) {
    +  string::size_type begin_index, end_index;
    +  begin_index = 0;
    +
    +  for (int i = 0; (i < pieces-1) || (pieces == 0); i++) {
    +    end_index = full.find_first_of(delim, begin_index);
    +    if (end_index == string::npos) {
    +      *result++ = full.substr(begin_index);
    +      return;
    +    }
    +    *result++ = full.substr(begin_index, (end_index - begin_index));
    +    begin_index = end_index + 1;
    +  }
    +  *result++ = full.substr(begin_index);
    +}
    +
    +void SplitStringAllowEmpty(const string& full, const char* delim,
    +                           vector* result) {
    +  back_insert_iterator > it(*result);
    +  SplitStringToIteratorAllowEmpty(full, delim, 0, it);
    +}
    +
    +// ----------------------------------------------------------------------
    +// JoinStrings()
    +//    This merges a vector of string components with delim inserted
    +//    as separaters between components.
    +//
    +// ----------------------------------------------------------------------
    +template 
    +static void JoinStringsIterator(const ITERATOR& start,
    +                                const ITERATOR& end,
    +                                const char* delim,
    +                                string* result) {
    +  GOOGLE_CHECK(result != NULL);
    +  result->clear();
    +  int delim_length = strlen(delim);
    +
    +  // Precompute resulting length so we can reserve() memory in one shot.
    +  int length = 0;
    +  for (ITERATOR iter = start; iter != end; ++iter) {
    +    if (iter != start) {
    +      length += delim_length;
    +    }
    +    length += iter->size();
    +  }
    +  result->reserve(length);
    +
    +  // Now combine everything.
    +  for (ITERATOR iter = start; iter != end; ++iter) {
    +    if (iter != start) {
    +      result->append(delim, delim_length);
    +    }
    +    result->append(iter->data(), iter->size());
    +  }
    +}
    +
    +void JoinStrings(const vector& components,
    +                 const char* delim,
    +                 string * result) {
    +  JoinStringsIterator(components.begin(), components.end(), delim, result);
    +}
    +
    +// ----------------------------------------------------------------------
    +// UnescapeCEscapeSequences()
    +//    This does all the unescaping that C does: \ooo, \r, \n, etc
    +//    Returns length of resulting string.
    +//    The implementation of \x parses any positive number of hex digits,
    +//    but it is an error if the value requires more than 8 bits, and the
    +//    result is truncated to 8 bits.
    +//
    +//    The second call stores its errors in a supplied string vector.
    +//    If the string vector pointer is NULL, it reports the errors with LOG().
    +// ----------------------------------------------------------------------
    +
    +#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7'))
    +
    +inline int hex_digit_to_int(char c) {
    +  /* Assume ASCII. */
    +  assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61);
    +  assert(isxdigit(c));
    +  int x = static_cast(c);
    +  if (x > '9') {
    +    x += 9;
    +  }
    +  return x & 0xf;
    +}
    +
    +// Protocol buffers doesn't ever care about errors, but I don't want to remove
    +// the code.
    +#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false)
    +
    +int UnescapeCEscapeSequences(const char* source, char* dest) {
    +  return UnescapeCEscapeSequences(source, dest, NULL);
    +}
    +
    +int UnescapeCEscapeSequences(const char* source, char* dest,
    +                             vector *errors) {
    +  GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented.";
    +
    +  char* d = dest;
    +  const char* p = source;
    +
    +  // Small optimization for case where source = dest and there's no escaping
    +  while ( p == d && *p != '\0' && *p != '\\' )
    +    p++, d++;
    +
    +  while (*p != '\0') {
    +    if (*p != '\\') {
    +      *d++ = *p++;
    +    } else {
    +      switch ( *++p ) {                    // skip past the '\\'
    +        case '\0':
    +          LOG_STRING(ERROR, errors) << "String cannot end with \\";
    +          *d = '\0';
    +          return d - dest;   // we're done with p
    +        case 'a':  *d++ = '\a';  break;
    +        case 'b':  *d++ = '\b';  break;
    +        case 'f':  *d++ = '\f';  break;
    +        case 'n':  *d++ = '\n';  break;
    +        case 'r':  *d++ = '\r';  break;
    +        case 't':  *d++ = '\t';  break;
    +        case 'v':  *d++ = '\v';  break;
    +        case '\\': *d++ = '\\';  break;
    +        case '?':  *d++ = '\?';  break;    // \?  Who knew?
    +        case '\'': *d++ = '\'';  break;
    +        case '"':  *d++ = '\"';  break;
    +        case '0': case '1': case '2': case '3':  // octal digit: 1 to 3 digits
    +        case '4': case '5': case '6': case '7': {
    +          char ch = *p - '0';
    +          if ( IS_OCTAL_DIGIT(p[1]) )
    +            ch = ch * 8 + *++p - '0';
    +          if ( IS_OCTAL_DIGIT(p[1]) )      // safe (and easy) to do this twice
    +            ch = ch * 8 + *++p - '0';      // now points at last digit
    +          *d++ = ch;
    +          break;
    +        }
    +        case 'x': case 'X': {
    +          if (!isxdigit(p[1])) {
    +            if (p[1] == '\0') {
    +              LOG_STRING(ERROR, errors) << "String cannot end with \\x";
    +            } else {
    +              LOG_STRING(ERROR, errors) <<
    +                "\\x cannot be followed by non-hex digit: \\" << *p << p[1];
    +            }
    +            break;
    +          }
    +          unsigned int ch = 0;
    +          const char *hex_start = p;
    +          while (isxdigit(p[1]))  // arbitrarily many hex digits
    +            ch = (ch << 4) + hex_digit_to_int(*++p);
    +          if (ch > 0xFF)
    +            LOG_STRING(ERROR, errors) << "Value of " <<
    +              "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits";
    +          *d++ = ch;
    +          break;
    +        }
    +#if 0  // TODO(kenton):  Support \u and \U?  Requires runetochar().
    +        case 'u': {
    +          // \uhhhh => convert 4 hex digits to UTF-8
    +          char32 rune = 0;
    +          const char *hex_start = p;
    +          for (int i = 0; i < 4; ++i) {
    +            if (isxdigit(p[1])) {  // Look one char ahead.
    +              rune = (rune << 4) + hex_digit_to_int(*++p);  // Advance p.
    +            } else {
    +              LOG_STRING(ERROR, errors)
    +                << "\\u must be followed by 4 hex digits: \\"
    +                <<  string(hex_start, p+1-hex_start);
    +              break;
    +            }
    +          }
    +          d += runetochar(d, &rune);
    +          break;
    +        }
    +        case 'U': {
    +          // \Uhhhhhhhh => convert 8 hex digits to UTF-8
    +          char32 rune = 0;
    +          const char *hex_start = p;
    +          for (int i = 0; i < 8; ++i) {
    +            if (isxdigit(p[1])) {  // Look one char ahead.
    +              // Don't change rune until we're sure this
    +              // is within the Unicode limit, but do advance p.
    +              char32 newrune = (rune << 4) + hex_digit_to_int(*++p);
    +              if (newrune > 0x10FFFF) {
    +                LOG_STRING(ERROR, errors)
    +                  << "Value of \\"
    +                  << string(hex_start, p + 1 - hex_start)
    +                  << " exceeds Unicode limit (0x10FFFF)";
    +                break;
    +              } else {
    +                rune = newrune;
    +              }
    +            } else {
    +              LOG_STRING(ERROR, errors)
    +                << "\\U must be followed by 8 hex digits: \\"
    +                <<  string(hex_start, p+1-hex_start);
    +              break;
    +            }
    +          }
    +          d += runetochar(d, &rune);
    +          break;
    +        }
    +#endif
    +        default:
    +          LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p;
    +      }
    +      p++;                                 // read past letter we escaped
    +    }
    +  }
    +  *d = '\0';
    +  return d - dest;
    +}
    +
    +// ----------------------------------------------------------------------
    +// UnescapeCEscapeString()
    +//    This does the same thing as UnescapeCEscapeSequences, but creates
    +//    a new string. The caller does not need to worry about allocating
    +//    a dest buffer. This should be used for non performance critical
    +//    tasks such as printing debug messages. It is safe for src and dest
    +//    to be the same.
    +//
    +//    The second call stores its errors in a supplied string vector.
    +//    If the string vector pointer is NULL, it reports the errors with LOG().
    +//
    +//    In the first and second calls, the length of dest is returned. In the
    +//    the third call, the new string is returned.
    +// ----------------------------------------------------------------------
    +int UnescapeCEscapeString(const string& src, string* dest) {
    +  return UnescapeCEscapeString(src, dest, NULL);
    +}
    +
    +int UnescapeCEscapeString(const string& src, string* dest,
    +                          vector *errors) {
    +  scoped_array unescaped(new char[src.size() + 1]);
    +  int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors);
    +  GOOGLE_CHECK(dest);
    +  dest->assign(unescaped.get(), len);
    +  return len;
    +}
    +
    +string UnescapeCEscapeString(const string& src) {
    +  scoped_array unescaped(new char[src.size() + 1]);
    +  int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL);
    +  return string(unescaped.get(), len);
    +}
    +
    +// ----------------------------------------------------------------------
    +// CEscapeString()
    +// CHexEscapeString()
    +//    Copies 'src' to 'dest', escaping dangerous characters using
    +//    C-style escape sequences. This is very useful for preparing query
    +//    flags. 'src' and 'dest' should not overlap. The 'Hex' version uses
    +//    hexadecimal rather than octal sequences.
    +//    Returns the number of bytes written to 'dest' (not including the \0)
    +//    or -1 if there was insufficient space.
    +//
    +//    Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
    +// ----------------------------------------------------------------------
    +int CEscapeInternal(const char* src, int src_len, char* dest,
    +                    int dest_len, bool use_hex, bool utf8_safe) {
    +  const char* src_end = src + src_len;
    +  int used = 0;
    +  bool last_hex_escape = false; // true if last output char was \xNN
    +
    +  for (; src < src_end; src++) {
    +    if (dest_len - used < 2)   // Need space for two letter escape
    +      return -1;
    +
    +    bool is_hex_escape = false;
    +    switch (*src) {
    +      case '\n': dest[used++] = '\\'; dest[used++] = 'n';  break;
    +      case '\r': dest[used++] = '\\'; dest[used++] = 'r';  break;
    +      case '\t': dest[used++] = '\\'; dest[used++] = 't';  break;
    +      case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
    +      case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
    +      case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
    +      default:
    +        // Note that if we emit \xNN and the src character after that is a hex
    +        // digit then that digit must be escaped too to prevent it being
    +        // interpreted as part of the character code by C.
    +        if ((!utf8_safe || static_cast(*src) < 0x80) &&
    +            (!isprint(*src) ||
    +             (last_hex_escape && isxdigit(*src)))) {
    +          if (dest_len - used < 4) // need space for 4 letter escape
    +            return -1;
    +          sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"),
    +                  static_cast(*src));
    +          is_hex_escape = use_hex;
    +          used += 4;
    +        } else {
    +          dest[used++] = *src; break;
    +        }
    +    }
    +    last_hex_escape = is_hex_escape;
    +  }
    +
    +  if (dest_len - used < 1)   // make sure that there is room for \0
    +    return -1;
    +
    +  dest[used] = '\0';   // doesn't count towards return value though
    +  return used;
    +}
    +
    +int CEscapeString(const char* src, int src_len, char* dest, int dest_len) {
    +  return CEscapeInternal(src, src_len, dest, dest_len, false, false);
    +}
    +
    +// ----------------------------------------------------------------------
    +// CEscape()
    +// CHexEscape()
    +//    Copies 'src' to result, escaping dangerous characters using
    +//    C-style escape sequences. This is very useful for preparing query
    +//    flags. 'src' and 'dest' should not overlap. The 'Hex' version
    +//    hexadecimal rather than octal sequences.
    +//
    +//    Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
    +// ----------------------------------------------------------------------
    +string CEscape(const string& src) {
    +  const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
    +  scoped_array dest(new char[dest_length]);
    +  const int len = CEscapeInternal(src.data(), src.size(),
    +                                  dest.get(), dest_length, false, false);
    +  GOOGLE_DCHECK_GE(len, 0);
    +  return string(dest.get(), len);
    +}
    +
    +namespace strings {
    +
    +string Utf8SafeCEscape(const string& src) {
    +  const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
    +  scoped_array dest(new char[dest_length]);
    +  const int len = CEscapeInternal(src.data(), src.size(),
    +                                  dest.get(), dest_length, false, true);
    +  GOOGLE_DCHECK_GE(len, 0);
    +  return string(dest.get(), len);
    +}
    +
    +string CHexEscape(const string& src) {
    +  const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
    +  scoped_array dest(new char[dest_length]);
    +  const int len = CEscapeInternal(src.data(), src.size(),
    +                                  dest.get(), dest_length, true, false);
    +  GOOGLE_DCHECK_GE(len, 0);
    +  return string(dest.get(), len);
    +}
    +
    +}  // namespace strings
    +
    +// ----------------------------------------------------------------------
    +// strto32_adaptor()
    +// strtou32_adaptor()
    +//    Implementation of strto[u]l replacements that have identical
    +//    overflow and underflow characteristics for both ILP-32 and LP-64
    +//    platforms, including errno preservation in error-free calls.
    +// ----------------------------------------------------------------------
    +
    +int32 strto32_adaptor(const char *nptr, char **endptr, int base) {
    +  const int saved_errno = errno;
    +  errno = 0;
    +  const long result = strtol(nptr, endptr, base);
    +  if (errno == ERANGE && result == LONG_MIN) {
    +    return kint32min;
    +  } else if (errno == ERANGE && result == LONG_MAX) {
    +    return kint32max;
    +  } else if (errno == 0 && result < kint32min) {
    +    errno = ERANGE;
    +    return kint32min;
    +  } else if (errno == 0 && result > kint32max) {
    +    errno = ERANGE;
    +    return kint32max;
    +  }
    +  if (errno == 0)
    +    errno = saved_errno;
    +  return static_cast(result);
    +}
    +
    +uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) {
    +  const int saved_errno = errno;
    +  errno = 0;
    +  const unsigned long result = strtoul(nptr, endptr, base);
    +  if (errno == ERANGE && result == ULONG_MAX) {
    +    return kuint32max;
    +  } else if (errno == 0 && result > kuint32max) {
    +    errno = ERANGE;
    +    return kuint32max;
    +  }
    +  if (errno == 0)
    +    errno = saved_errno;
    +  return static_cast(result);
    +}
    +
    +inline bool safe_parse_sign(string* text  /*inout*/,
    +                            bool* negative_ptr  /*output*/) {
    +  const char* start = text->data();
    +  const char* end = start + text->size();
    +
    +  // Consume whitespace.
    +  while (start < end && (start[0] == ' ')) {
    +    ++start;
    +  }
    +  while (start < end && (end[-1] == ' ')) {
    +    --end;
    +  }
    +  if (start >= end) {
    +    return false;
    +  }
    +
    +  // Consume sign.
    +  *negative_ptr = (start[0] == '-');
    +  if (*negative_ptr || start[0] == '+') {
    +    ++start;
    +    if (start >= end) {
    +      return false;
    +    }
    +  }
    +  *text = text->substr(start - text->data(), end - start);
    +  return true;
    +}
    +
    +inline bool safe_parse_positive_int(
    +    string text, int32* value_p) {
    +  int base = 10;
    +  int32 value = 0;
    +  const int32 vmax = std::numeric_limits::max();
    +  assert(vmax > 0);
    +  assert(vmax >= base);
    +  const int32 vmax_over_base = vmax / base;
    +  const char* start = text.data();
    +  const char* end = start + text.size();
    +  // loop over digits
    +  for (; start < end; ++start) {
    +    unsigned char c = static_cast(start[0]);
    +    int digit = c - '0';
    +    if (digit >= base || digit < 0) {
    +      *value_p = value;
    +      return false;
    +    }
    +    if (value > vmax_over_base) {
    +      *value_p = vmax;
    +      return false;
    +    }
    +    value *= base;
    +    if (value > vmax - digit) {
    +      *value_p = vmax;
    +      return false;
    +    }
    +    value += digit;
    +  }
    +  *value_p = value;
    +  return true;
    +}
    +
    +inline bool safe_parse_negative_int(
    +    string text, int32* value_p) {
    +  int base = 10;
    +  int32 value = 0;
    +  const int32 vmin = std::numeric_limits::min();
    +  assert(vmin < 0);
    +  assert(vmin <= 0 - base);
    +  int32 vmin_over_base = vmin / base;
    +  // 2003 c++ standard [expr.mul]
    +  // "... the sign of the remainder is implementation-defined."
    +  // Although (vmin/base)*base + vmin%base is always vmin.
    +  // 2011 c++ standard tightens the spec but we cannot rely on it.
    +  if (vmin % base > 0) {
    +    vmin_over_base += 1;
    +  }
    +  const char* start = text.data();
    +  const char* end = start + text.size();
    +  // loop over digits
    +  for (; start < end; ++start) {
    +    unsigned char c = static_cast(start[0]);
    +    int digit = c - '0';
    +    if (digit >= base || digit < 0) {
    +      *value_p = value;
    +      return false;
    +    }
    +    if (value < vmin_over_base) {
    +      *value_p = vmin;
    +      return false;
    +    }
    +    value *= base;
    +    if (value < vmin + digit) {
    +      *value_p = vmin;
    +      return false;
    +    }
    +    value -= digit;
    +  }
    +  *value_p = value;
    +  return true;
    +}
    +
    +bool safe_int(string text, int32* value_p) {
    +  *value_p = 0;
    +  bool negative;
    +  if (!safe_parse_sign(&text, &negative)) {
    +    return false;
    +  }
    +  if (!negative) {
    +    return safe_parse_positive_int(text, value_p);
    +  } else {
    +    return safe_parse_negative_int(text, value_p);
    +  }
    +}
    +
    +// ----------------------------------------------------------------------
    +// FastIntToBuffer()
    +// FastInt64ToBuffer()
    +// FastHexToBuffer()
    +// FastHex64ToBuffer()
    +// FastHex32ToBuffer()
    +// ----------------------------------------------------------------------
    +
    +// Offset into buffer where FastInt64ToBuffer places the end of string
    +// null character.  Also used by FastInt64ToBufferLeft.
    +static const int kFastInt64ToBufferOffset = 21;
    +
    +char *FastInt64ToBuffer(int64 i, char* buffer) {
    +  // We could collapse the positive and negative sections, but that
    +  // would be slightly slower for positive numbers...
    +  // 22 bytes is enough to store -2**64, -18446744073709551616.
    +  char* p = buffer + kFastInt64ToBufferOffset;
    +  *p-- = '\0';
    +  if (i >= 0) {
    +    do {
    +      *p-- = '0' + i % 10;
    +      i /= 10;
    +    } while (i > 0);
    +    return p + 1;
    +  } else {
    +    // On different platforms, % and / have different behaviors for
    +    // negative numbers, so we need to jump through hoops to make sure
    +    // we don't divide negative numbers.
    +    if (i > -10) {
    +      i = -i;
    +      *p-- = '0' + i;
    +      *p = '-';
    +      return p;
    +    } else {
    +      // Make sure we aren't at MIN_INT, in which case we can't say i = -i
    +      i = i + 10;
    +      i = -i;
    +      *p-- = '0' + i % 10;
    +      // Undo what we did a moment ago
    +      i = i / 10 + 1;
    +      do {
    +        *p-- = '0' + i % 10;
    +        i /= 10;
    +      } while (i > 0);
    +      *p = '-';
    +      return p;
    +    }
    +  }
    +}
    +
    +// Offset into buffer where FastInt32ToBuffer places the end of string
    +// null character.  Also used by FastInt32ToBufferLeft
    +static const int kFastInt32ToBufferOffset = 11;
    +
    +// Yes, this is a duplicate of FastInt64ToBuffer.  But, we need this for the
    +// compiler to generate 32 bit arithmetic instructions.  It's much faster, at
    +// least with 32 bit binaries.
    +char *FastInt32ToBuffer(int32 i, char* buffer) {
    +  // We could collapse the positive and negative sections, but that
    +  // would be slightly slower for positive numbers...
    +  // 12 bytes is enough to store -2**32, -4294967296.
    +  char* p = buffer + kFastInt32ToBufferOffset;
    +  *p-- = '\0';
    +  if (i >= 0) {
    +    do {
    +      *p-- = '0' + i % 10;
    +      i /= 10;
    +    } while (i > 0);
    +    return p + 1;
    +  } else {
    +    // On different platforms, % and / have different behaviors for
    +    // negative numbers, so we need to jump through hoops to make sure
    +    // we don't divide negative numbers.
    +    if (i > -10) {
    +      i = -i;
    +      *p-- = '0' + i;
    +      *p = '-';
    +      return p;
    +    } else {
    +      // Make sure we aren't at MIN_INT, in which case we can't say i = -i
    +      i = i + 10;
    +      i = -i;
    +      *p-- = '0' + i % 10;
    +      // Undo what we did a moment ago
    +      i = i / 10 + 1;
    +      do {
    +        *p-- = '0' + i % 10;
    +        i /= 10;
    +      } while (i > 0);
    +      *p = '-';
    +      return p;
    +    }
    +  }
    +}
    +
    +char *FastHexToBuffer(int i, char* buffer) {
    +  GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i;
    +
    +  static const char *hexdigits = "0123456789abcdef";
    +  char *p = buffer + 21;
    +  *p-- = '\0';
    +  do {
    +    *p-- = hexdigits[i & 15];   // mod by 16
    +    i >>= 4;                    // divide by 16
    +  } while (i > 0);
    +  return p + 1;
    +}
    +
    +char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
    +  static const char *hexdigits = "0123456789abcdef";
    +  buffer[num_byte] = '\0';
    +  for (int i = num_byte - 1; i >= 0; i--) {
    +#ifdef _M_X64
    +    // MSVC x64 platform has a bug optimizing the uint32(value) in the #else
    +    // block. Given that the uint32 cast was to improve performance on 32-bit
    +    // platforms, we use 64-bit '&' directly.
    +    buffer[i] = hexdigits[value & 0xf];
    +#else
    +    buffer[i] = hexdigits[uint32(value) & 0xf];
    +#endif
    +    value >>= 4;
    +  }
    +  return buffer;
    +}
    +
    +char *FastHex64ToBuffer(uint64 value, char* buffer) {
    +  return InternalFastHexToBuffer(value, buffer, 16);
    +}
    +
    +char *FastHex32ToBuffer(uint32 value, char* buffer) {
    +  return InternalFastHexToBuffer(value, buffer, 8);
    +}
    +
    +static inline char* PlaceNum(char* p, int num, char prev_sep) {
    +   *p-- = '0' + num % 10;
    +   *p-- = '0' + num / 10;
    +   *p-- = prev_sep;
    +   return p;
    +}
    +
    +// ----------------------------------------------------------------------
    +// FastInt32ToBufferLeft()
    +// FastUInt32ToBufferLeft()
    +// FastInt64ToBufferLeft()
    +// FastUInt64ToBufferLeft()
    +//
    +// Like the Fast*ToBuffer() functions above, these are intended for speed.
    +// Unlike the Fast*ToBuffer() functions, however, these functions write
    +// their output to the beginning of the buffer (hence the name, as the
    +// output is left-aligned).  The caller is responsible for ensuring that
    +// the buffer has enough space to hold the output.
    +//
    +// Returns a pointer to the end of the string (i.e. the null character
    +// terminating the string).
    +// ----------------------------------------------------------------------
    +
    +static const char two_ASCII_digits[100][2] = {
    +  {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'},
    +  {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'},
    +  {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'},
    +  {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'},
    +  {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'},
    +  {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'},
    +  {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'},
    +  {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'},
    +  {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'},
    +  {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'},
    +  {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'},
    +  {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'},
    +  {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'},
    +  {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'},
    +  {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'},
    +  {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'},
    +  {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'},
    +  {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'},
    +  {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'},
    +  {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'}
    +};
    +
    +char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
    +  int digits;
    +  const char *ASCII_digits = NULL;
    +  // The idea of this implementation is to trim the number of divides to as few
    +  // as possible by using multiplication and subtraction rather than mod (%),
    +  // and by outputting two digits at a time rather than one.
    +  // The huge-number case is first, in the hopes that the compiler will output
    +  // that case in one branch-free block of code, and only output conditional
    +  // branches into it from below.
    +  if (u >= 1000000000) {  // >= 1,000,000,000
    +    digits = u / 100000000;  // 100,000,000
    +    ASCII_digits = two_ASCII_digits[digits];
    +    buffer[0] = ASCII_digits[0];
    +    buffer[1] = ASCII_digits[1];
    +    buffer += 2;
    +sublt100_000_000:
    +    u -= digits * 100000000;  // 100,000,000
    +lt100_000_000:
    +    digits = u / 1000000;  // 1,000,000
    +    ASCII_digits = two_ASCII_digits[digits];
    +    buffer[0] = ASCII_digits[0];
    +    buffer[1] = ASCII_digits[1];
    +    buffer += 2;
    +sublt1_000_000:
    +    u -= digits * 1000000;  // 1,000,000
    +lt1_000_000:
    +    digits = u / 10000;  // 10,000
    +    ASCII_digits = two_ASCII_digits[digits];
    +    buffer[0] = ASCII_digits[0];
    +    buffer[1] = ASCII_digits[1];
    +    buffer += 2;
    +sublt10_000:
    +    u -= digits * 10000;  // 10,000
    +lt10_000:
    +    digits = u / 100;
    +    ASCII_digits = two_ASCII_digits[digits];
    +    buffer[0] = ASCII_digits[0];
    +    buffer[1] = ASCII_digits[1];
    +    buffer += 2;
    +sublt100:
    +    u -= digits * 100;
    +lt100:
    +    digits = u;
    +    ASCII_digits = two_ASCII_digits[digits];
    +    buffer[0] = ASCII_digits[0];
    +    buffer[1] = ASCII_digits[1];
    +    buffer += 2;
    +done:
    +    *buffer = 0;
    +    return buffer;
    +  }
    +
    +  if (u < 100) {
    +    digits = u;
    +    if (u >= 10) goto lt100;
    +    *buffer++ = '0' + digits;
    +    goto done;
    +  }
    +  if (u  <  10000) {   // 10,000
    +    if (u >= 1000) goto lt10_000;
    +    digits = u / 100;
    +    *buffer++ = '0' + digits;
    +    goto sublt100;
    +  }
    +  if (u  <  1000000) {   // 1,000,000
    +    if (u >= 100000) goto lt1_000_000;
    +    digits = u / 10000;  //    10,000
    +    *buffer++ = '0' + digits;
    +    goto sublt10_000;
    +  }
    +  if (u  <  100000000) {   // 100,000,000
    +    if (u >= 10000000) goto lt100_000_000;
    +    digits = u / 1000000;  //   1,000,000
    +    *buffer++ = '0' + digits;
    +    goto sublt1_000_000;
    +  }
    +  // we already know that u < 1,000,000,000
    +  digits = u / 100000000;   // 100,000,000
    +  *buffer++ = '0' + digits;
    +  goto sublt100_000_000;
    +}
    +
    +char* FastInt32ToBufferLeft(int32 i, char* buffer) {
    +  uint32 u = i;
    +  if (i < 0) {
    +    *buffer++ = '-';
    +    u = -i;
    +  }
    +  return FastUInt32ToBufferLeft(u, buffer);
    +}
    +
    +char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) {
    +  int digits;
    +  const char *ASCII_digits = NULL;
    +
    +  uint32 u = static_cast(u64);
    +  if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
    +
    +  uint64 top_11_digits = u64 / 1000000000;
    +  buffer = FastUInt64ToBufferLeft(top_11_digits, buffer);
    +  u = u64 - (top_11_digits * 1000000000);
    +
    +  digits = u / 10000000;  // 10,000,000
    +  GOOGLE_DCHECK_LT(digits, 100);
    +  ASCII_digits = two_ASCII_digits[digits];
    +  buffer[0] = ASCII_digits[0];
    +  buffer[1] = ASCII_digits[1];
    +  buffer += 2;
    +  u -= digits * 10000000;  // 10,000,000
    +  digits = u / 100000;  // 100,000
    +  ASCII_digits = two_ASCII_digits[digits];
    +  buffer[0] = ASCII_digits[0];
    +  buffer[1] = ASCII_digits[1];
    +  buffer += 2;
    +  u -= digits * 100000;  // 100,000
    +  digits = u / 1000;  // 1,000
    +  ASCII_digits = two_ASCII_digits[digits];
    +  buffer[0] = ASCII_digits[0];
    +  buffer[1] = ASCII_digits[1];
    +  buffer += 2;
    +  u -= digits * 1000;  // 1,000
    +  digits = u / 10;
    +  ASCII_digits = two_ASCII_digits[digits];
    +  buffer[0] = ASCII_digits[0];
    +  buffer[1] = ASCII_digits[1];
    +  buffer += 2;
    +  u -= digits * 10;
    +  digits = u;
    +  *buffer++ = '0' + digits;
    +  *buffer = 0;
    +  return buffer;
    +}
    +
    +char* FastInt64ToBufferLeft(int64 i, char* buffer) {
    +  uint64 u = i;
    +  if (i < 0) {
    +    *buffer++ = '-';
    +    u = -i;
    +  }
    +  return FastUInt64ToBufferLeft(u, buffer);
    +}
    +
    +// ----------------------------------------------------------------------
    +// SimpleItoa()
    +//    Description: converts an integer to a string.
    +//
    +//    Return value: string
    +// ----------------------------------------------------------------------
    +
    +string SimpleItoa(int i) {
    +  char buffer[kFastToBufferSize];
    +  return (sizeof(i) == 4) ?
    +    FastInt32ToBuffer(i, buffer) :
    +    FastInt64ToBuffer(i, buffer);
    +}
    +
    +string SimpleItoa(unsigned int i) {
    +  char buffer[kFastToBufferSize];
    +  return string(buffer, (sizeof(i) == 4) ?
    +    FastUInt32ToBufferLeft(i, buffer) :
    +    FastUInt64ToBufferLeft(i, buffer));
    +}
    +
    +string SimpleItoa(long i) {
    +  char buffer[kFastToBufferSize];
    +  return (sizeof(i) == 4) ?
    +    FastInt32ToBuffer(i, buffer) :
    +    FastInt64ToBuffer(i, buffer);
    +}
    +
    +string SimpleItoa(unsigned long i) {
    +  char buffer[kFastToBufferSize];
    +  return string(buffer, (sizeof(i) == 4) ?
    +    FastUInt32ToBufferLeft(i, buffer) :
    +    FastUInt64ToBufferLeft(i, buffer));
    +}
    +
    +string SimpleItoa(long long i) {
    +  char buffer[kFastToBufferSize];
    +  return (sizeof(i) == 4) ?
    +    FastInt32ToBuffer(i, buffer) :
    +    FastInt64ToBuffer(i, buffer);
    +}
    +
    +string SimpleItoa(unsigned long long i) {
    +  char buffer[kFastToBufferSize];
    +  return string(buffer, (sizeof(i) == 4) ?
    +    FastUInt32ToBufferLeft(i, buffer) :
    +    FastUInt64ToBufferLeft(i, buffer));
    +}
    +
    +// ----------------------------------------------------------------------
    +// SimpleDtoa()
    +// SimpleFtoa()
    +// DoubleToBuffer()
    +// FloatToBuffer()
    +//    We want to print the value without losing precision, but we also do
    +//    not want to print more digits than necessary.  This turns out to be
    +//    trickier than it sounds.  Numbers like 0.2 cannot be represented
    +//    exactly in binary.  If we print 0.2 with a very large precision,
    +//    e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167".
    +//    On the other hand, if we set the precision too low, we lose
    +//    significant digits when printing numbers that actually need them.
    +//    It turns out there is no precision value that does the right thing
    +//    for all numbers.
    +//
    +//    Our strategy is to first try printing with a precision that is never
    +//    over-precise, then parse the result with strtod() to see if it
    +//    matches.  If not, we print again with a precision that will always
    +//    give a precise result, but may use more digits than necessary.
    +//
    +//    An arguably better strategy would be to use the algorithm described
    +//    in "How to Print Floating-Point Numbers Accurately" by Steele &
    +//    White, e.g. as implemented by David M. Gay's dtoa().  It turns out,
    +//    however, that the following implementation is about as fast as
    +//    DMG's code.  Furthermore, DMG's code locks mutexes, which means it
    +//    will not scale well on multi-core machines.  DMG's code is slightly
    +//    more accurate (in that it will never use more digits than
    +//    necessary), but this is probably irrelevant for most users.
    +//
    +//    Rob Pike and Ken Thompson also have an implementation of dtoa() in
    +//    third_party/fmt/fltfmt.cc.  Their implementation is similar to this
    +//    one in that it makes guesses and then uses strtod() to check them.
    +//    Their implementation is faster because they use their own code to
    +//    generate the digits in the first place rather than use snprintf(),
    +//    thus avoiding format string parsing overhead.  However, this makes
    +//    it considerably more complicated than the following implementation,
    +//    and it is embedded in a larger library.  If speed turns out to be
    +//    an issue, we could re-implement this in terms of their
    +//    implementation.
    +// ----------------------------------------------------------------------
    +
    +string SimpleDtoa(double value) {
    +  char buffer[kDoubleToBufferSize];
    +  return DoubleToBuffer(value, buffer);
    +}
    +
    +string SimpleFtoa(float value) {
    +  char buffer[kFloatToBufferSize];
    +  return FloatToBuffer(value, buffer);
    +}
    +
    +static inline bool IsValidFloatChar(char c) {
    +  return ('0' <= c && c <= '9') ||
    +         c == 'e' || c == 'E' ||
    +         c == '+' || c == '-';
    +}
    +
    +void DelocalizeRadix(char* buffer) {
    +  // Fast check:  if the buffer has a normal decimal point, assume no
    +  // translation is needed.
    +  if (strchr(buffer, '.') != NULL) return;
    +
    +  // Find the first unknown character.
    +  while (IsValidFloatChar(*buffer)) ++buffer;
    +
    +  if (*buffer == '\0') {
    +    // No radix character found.
    +    return;
    +  }
    +
    +  // We are now pointing at the locale-specific radix character.  Replace it
    +  // with '.'.
    +  *buffer = '.';
    +  ++buffer;
    +
    +  if (!IsValidFloatChar(*buffer) && *buffer != '\0') {
    +    // It appears the radix was a multi-byte character.  We need to remove the
    +    // extra bytes.
    +    char* target = buffer;
    +    do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0');
    +    memmove(target, buffer, strlen(buffer) + 1);
    +  }
    +}
    +
    +char* DoubleToBuffer(double value, char* buffer) {
    +  // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
    +  // platforms these days.  Just in case some system exists where DBL_DIG
    +  // is significantly larger -- and risks overflowing our buffer -- we have
    +  // this assert.
    +  GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big);
    +
    +  if (value == numeric_limits::infinity()) {
    +    strcpy(buffer, "inf");
    +    return buffer;
    +  } else if (value == -numeric_limits::infinity()) {
    +    strcpy(buffer, "-inf");
    +    return buffer;
    +  } else if (IsNaN(value)) {
    +    strcpy(buffer, "nan");
    +    return buffer;
    +  }
    +
    +  int snprintf_result =
    +    snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value);
    +
    +  // The snprintf should never overflow because the buffer is significantly
    +  // larger than the precision we asked for.
    +  GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
    +
    +  // We need to make parsed_value volatile in order to force the compiler to
    +  // write it out to the stack.  Otherwise, it may keep the value in a
    +  // register, and if it does that, it may keep it as a long double instead
    +  // of a double.  This long double may have extra bits that make it compare
    +  // unequal to "value" even though it would be exactly equal if it were
    +  // truncated to a double.
    +  volatile double parsed_value = strtod(buffer, NULL);
    +  if (parsed_value != value) {
    +    int snprintf_result =
    +      snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value);
    +
    +    // Should never overflow; see above.
    +    GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
    +  }
    +
    +  DelocalizeRadix(buffer);
    +  return buffer;
    +}
    +
    +bool safe_strtof(const char* str, float* value) {
    +  char* endptr;
    +  errno = 0;  // errno only gets set on errors
    +#if defined(_WIN32) || defined (__hpux)  // has no strtof()
    +  *value = strtod(str, &endptr);
    +#else
    +  *value = strtof(str, &endptr);
    +#endif
    +  return *str != 0 && *endptr == 0 && errno == 0;
    +}
    +
    +char* FloatToBuffer(float value, char* buffer) {
    +  // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
    +  // platforms these days.  Just in case some system exists where FLT_DIG
    +  // is significantly larger -- and risks overflowing our buffer -- we have
    +  // this assert.
    +  GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big);
    +
    +  if (value == numeric_limits::infinity()) {
    +    strcpy(buffer, "inf");
    +    return buffer;
    +  } else if (value == -numeric_limits::infinity()) {
    +    strcpy(buffer, "-inf");
    +    return buffer;
    +  } else if (IsNaN(value)) {
    +    strcpy(buffer, "nan");
    +    return buffer;
    +  }
    +
    +  int snprintf_result =
    +    snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value);
    +
    +  // The snprintf should never overflow because the buffer is significantly
    +  // larger than the precision we asked for.
    +  GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
    +
    +  float parsed_value;
    +  if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
    +    int snprintf_result =
    +      snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value);
    +
    +    // Should never overflow; see above.
    +    GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
    +  }
    +
    +  DelocalizeRadix(buffer);
    +  return buffer;
    +}
    +
    +string ToHex(uint64 num) {
    +  if (num == 0) {
    +    return string("0");
    +  }
    +
    +  // Compute hex bytes in reverse order, writing to the back of the
    +  // buffer.
    +  char buf[16];  // No more than 16 hex digits needed.
    +  char* bufptr = buf + 16;
    +  static const char kHexChars[] = "0123456789abcdef";
    +  while (num != 0) {
    +    *--bufptr = kHexChars[num & 0xf];
    +    num >>= 4;
    +  }
    +
    +  return string(bufptr, buf + 16 - bufptr);
    +}
    +
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h
    new file mode 100644
    index 000000000000..6cf23821e99b
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h
    @@ -0,0 +1,563 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// from google3/strings/strutil.h
    +
    +#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
    +#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
    +
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +#ifdef _MSC_VER
    +#define strtoll  _strtoi64
    +#define strtoull _strtoui64
    +#elif defined(__DECCXX) && defined(__osf__)
    +// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit.
    +#define strtoll strtol
    +#define strtoull strtoul
    +#endif
    +
    +// ----------------------------------------------------------------------
    +// ascii_isalnum()
    +//    Check if an ASCII character is alphanumeric.  We can't use ctype's
    +//    isalnum() because it is affected by locale.  This function is applied
    +//    to identifiers in the protocol buffer language, not to natural-language
    +//    strings, so locale should not be taken into account.
    +// ascii_isdigit()
    +//    Like above, but only accepts digits.
    +// ----------------------------------------------------------------------
    +
    +inline bool ascii_isalnum(char c) {
    +  return ('a' <= c && c <= 'z') ||
    +         ('A' <= c && c <= 'Z') ||
    +         ('0' <= c && c <= '9');
    +}
    +
    +inline bool ascii_isdigit(char c) {
    +  return ('0' <= c && c <= '9');
    +}
    +
    +// ----------------------------------------------------------------------
    +// HasPrefixString()
    +//    Check if a string begins with a given prefix.
    +// StripPrefixString()
    +//    Given a string and a putative prefix, returns the string minus the
    +//    prefix string if the prefix matches, otherwise the original
    +//    string.
    +// ----------------------------------------------------------------------
    +inline bool HasPrefixString(const string& str,
    +                            const string& prefix) {
    +  return str.size() >= prefix.size() &&
    +         str.compare(0, prefix.size(), prefix) == 0;
    +}
    +
    +inline string StripPrefixString(const string& str, const string& prefix) {
    +  if (HasPrefixString(str, prefix)) {
    +    return str.substr(prefix.size());
    +  } else {
    +    return str;
    +  }
    +}
    +
    +// ----------------------------------------------------------------------
    +// HasSuffixString()
    +//    Return true if str ends in suffix.
    +// StripSuffixString()
    +//    Given a string and a putative suffix, returns the string minus the
    +//    suffix string if the suffix matches, otherwise the original
    +//    string.
    +// ----------------------------------------------------------------------
    +inline bool HasSuffixString(const string& str,
    +                            const string& suffix) {
    +  return str.size() >= suffix.size() &&
    +         str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
    +}
    +
    +inline string StripSuffixString(const string& str, const string& suffix) {
    +  if (HasSuffixString(str, suffix)) {
    +    return str.substr(0, str.size() - suffix.size());
    +  } else {
    +    return str;
    +  }
    +}
    +
    +// ----------------------------------------------------------------------
    +// StripString
    +//    Replaces any occurrence of the character 'remove' (or the characters
    +//    in 'remove') with the character 'replacewith'.
    +//    Good for keeping html characters or protocol characters (\t) out
    +//    of places where they might cause a problem.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove,
    +                                    char replacewith);
    +
    +// ----------------------------------------------------------------------
    +// LowerString()
    +// UpperString()
    +// ToUpper()
    +//    Convert the characters in "s" to lowercase or uppercase.  ASCII-only:
    +//    these functions intentionally ignore locale because they are applied to
    +//    identifiers used in the Protocol Buffer language, not to natural-language
    +//    strings.
    +// ----------------------------------------------------------------------
    +
    +inline void LowerString(string * s) {
    +  string::iterator end = s->end();
    +  for (string::iterator i = s->begin(); i != end; ++i) {
    +    // tolower() changes based on locale.  We don't want this!
    +    if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
    +  }
    +}
    +
    +inline void UpperString(string * s) {
    +  string::iterator end = s->end();
    +  for (string::iterator i = s->begin(); i != end; ++i) {
    +    // toupper() changes based on locale.  We don't want this!
    +    if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
    +  }
    +}
    +
    +inline string ToUpper(const string& s) {
    +  string out = s;
    +  UpperString(&out);
    +  return out;
    +}
    +
    +// ----------------------------------------------------------------------
    +// StringReplace()
    +//    Give me a string and two patterns "old" and "new", and I replace
    +//    the first instance of "old" in the string with "new", if it
    +//    exists.  RETURN a new string, regardless of whether the replacement
    +//    happened or not.
    +// ----------------------------------------------------------------------
    +
    +LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
    +                                        const string& newsub, bool replace_all);
    +
    +// ----------------------------------------------------------------------
    +// SplitStringUsing()
    +//    Split a string using a character delimiter. Append the components
    +//    to 'result'.  If there are consecutive delimiters, this function skips
    +//    over all of them.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
    +                                         vector* res);
    +
    +// Split a string using one or more byte delimiters, presented
    +// as a nul-terminated c string. Append the components to 'result'.
    +// If there are consecutive delimiters, this function will return
    +// corresponding empty strings.  If you want to drop the empty
    +// strings, try SplitStringUsing().
    +//
    +// If "full" is the empty string, yields an empty string as the only value.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT void SplitStringAllowEmpty(const string& full,
    +                                              const char* delim,
    +                                              vector* result);
    +
    +// ----------------------------------------------------------------------
    +// Split()
    +//    Split a string using a character delimiter.
    +// ----------------------------------------------------------------------
    +inline vector Split(
    +    const string& full, const char* delim, bool skip_empty = true) {
    +  vector result;
    +  if (skip_empty) {
    +    SplitStringUsing(full, delim, &result);
    +  } else {
    +    SplitStringAllowEmpty(full, delim, &result);
    +  }
    +  return result;
    +}
    +
    +// ----------------------------------------------------------------------
    +// JoinStrings()
    +//    These methods concatenate a vector of strings into a C++ string, using
    +//    the C-string "delim" as a separator between components. There are two
    +//    flavors of the function, one flavor returns the concatenated string,
    +//    another takes a pointer to the target string. In the latter case the
    +//    target string is cleared and overwritten.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT void JoinStrings(const vector& components,
    +                                    const char* delim, string* result);
    +
    +inline string JoinStrings(const vector& components,
    +                          const char* delim) {
    +  string result;
    +  JoinStrings(components, delim, &result);
    +  return result;
    +}
    +
    +// ----------------------------------------------------------------------
    +// UnescapeCEscapeSequences()
    +//    Copies "source" to "dest", rewriting C-style escape sequences
    +//    -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII
    +//    equivalents.  "dest" must be sufficiently large to hold all
    +//    the characters in the rewritten string (i.e. at least as large
    +//    as strlen(source) + 1 should be safe, since the replacements
    +//    are always shorter than the original escaped sequences).  It's
    +//    safe for source and dest to be the same.  RETURNS the length
    +//    of dest.
    +//
    +//    It allows hex sequences \xhh, or generally \xhhhhh with an
    +//    arbitrary number of hex digits, but all of them together must
    +//    specify a value of a single byte (e.g. \x0045 is equivalent
    +//    to \x45, and \x1234 is erroneous).
    +//
    +//    It also allows escape sequences of the form \uhhhh (exactly four
    +//    hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight
    +//    hex digits, upper or lower case) to specify a Unicode code
    +//    point. The dest array will contain the UTF8-encoded version of
    +//    that code-point (e.g., if source contains \u2019, then dest will
    +//    contain the three bytes 0xE2, 0x80, and 0x99).
    +//
    +//    Errors: In the first form of the call, errors are reported with
    +//    LOG(ERROR). The same is true for the second form of the call if
    +//    the pointer to the string vector is NULL; otherwise, error
    +//    messages are stored in the vector. In either case, the effect on
    +//    the dest array is not defined, but rest of the source will be
    +//    processed.
    +//    ----------------------------------------------------------------------
    +
    +LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest);
    +LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
    +                                                vector *errors);
    +
    +// ----------------------------------------------------------------------
    +// UnescapeCEscapeString()
    +//    This does the same thing as UnescapeCEscapeSequences, but creates
    +//    a new string. The caller does not need to worry about allocating
    +//    a dest buffer. This should be used for non performance critical
    +//    tasks such as printing debug messages. It is safe for src and dest
    +//    to be the same.
    +//
    +//    The second call stores its errors in a supplied string vector.
    +//    If the string vector pointer is NULL, it reports the errors with LOG().
    +//
    +//    In the first and second calls, the length of dest is returned. In the
    +//    the third call, the new string is returned.
    +// ----------------------------------------------------------------------
    +
    +LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest);
    +LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
    +                                             vector *errors);
    +LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
    +
    +// ----------------------------------------------------------------------
    +// CEscapeString()
    +//    Copies 'src' to 'dest', escaping dangerous characters using
    +//    C-style escape sequences. This is very useful for preparing query
    +//    flags. 'src' and 'dest' should not overlap.
    +//    Returns the number of bytes written to 'dest' (not including the \0)
    +//    or -1 if there was insufficient space.
    +//
    +//    Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len,
    +                                     char* dest, int dest_len);
    +
    +// ----------------------------------------------------------------------
    +// CEscape()
    +//    More convenient form of CEscapeString: returns result as a "string".
    +//    This version is slower than CEscapeString() because it does more
    +//    allocation.  However, it is much more convenient to use in
    +//    non-speed-critical code like logging messages etc.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT string CEscape(const string& src);
    +
    +namespace strings {
    +// Like CEscape() but does not escape bytes with the upper bit set.
    +LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src);
    +
    +// Like CEscape() but uses hex (\x) escapes instead of octals.
    +LIBPROTOBUF_EXPORT string CHexEscape(const string& src);
    +}  // namespace strings
    +
    +// ----------------------------------------------------------------------
    +// strto32()
    +// strtou32()
    +// strto64()
    +// strtou64()
    +//    Architecture-neutral plug compatible replacements for strtol() and
    +//    strtoul().  Long's have different lengths on ILP-32 and LP-64
    +//    platforms, so using these is safer, from the point of view of
    +//    overflow behavior, than using the standard libc functions.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr,
    +                                         int base);
    +LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr,
    +                                           int base);
    +
    +inline int32 strto32(const char *nptr, char **endptr, int base) {
    +  if (sizeof(int32) == sizeof(long))
    +    return strtol(nptr, endptr, base);
    +  else
    +    return strto32_adaptor(nptr, endptr, base);
    +}
    +
    +inline uint32 strtou32(const char *nptr, char **endptr, int base) {
    +  if (sizeof(uint32) == sizeof(unsigned long))
    +    return strtoul(nptr, endptr, base);
    +  else
    +    return strtou32_adaptor(nptr, endptr, base);
    +}
    +
    +// For now, long long is 64-bit on all the platforms we care about, so these
    +// functions can simply pass the call to strto[u]ll.
    +inline int64 strto64(const char *nptr, char **endptr, int base) {
    +  static_assert(sizeof(int64) == sizeof(long long), "Protobuf needs sizeof(int64) == sizeof(long long)");
    +  GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
    +                        sizeof_int64_is_not_sizeof_long_long);
    +  return strtoll(nptr, endptr, base);
    +}
    +
    +inline uint64 strtou64(const char *nptr, char **endptr, int base) {
    +  GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
    +                        sizeof_uint64_is_not_sizeof_long_long);
    +  return strtoull(nptr, endptr, base);
    +}
    +
    +// ----------------------------------------------------------------------
    +// safe_strto32()
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT bool safe_int(string text, int32* value_p);
    +
    +inline bool safe_strto32(string text, int32* value) {
    +  return safe_int(text, value);
    +}
    +
    +// ----------------------------------------------------------------------
    +// FastIntToBuffer()
    +// FastHexToBuffer()
    +// FastHex64ToBuffer()
    +// FastHex32ToBuffer()
    +// FastTimeToBuffer()
    +//    These are intended for speed.  FastIntToBuffer() assumes the
    +//    integer is non-negative.  FastHexToBuffer() puts output in
    +//    hex rather than decimal.  FastTimeToBuffer() puts the output
    +//    into RFC822 format.
    +//
    +//    FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
    +//    padded to exactly 16 bytes (plus one byte for '\0')
    +//
    +//    FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
    +//    padded to exactly 8 bytes (plus one byte for '\0')
    +//
    +//       All functions take the output buffer as an arg.
    +//    They all return a pointer to the beginning of the output,
    +//    which may not be the beginning of the input buffer.
    +// ----------------------------------------------------------------------
    +
    +// Suggested buffer size for FastToBuffer functions.  Also works with
    +// DoubleToBuffer() and FloatToBuffer().
    +static const int kFastToBufferSize = 32;
    +
    +LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer);
    +LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer);
    +char* FastUInt32ToBuffer(uint32 i, char* buffer);  // inline below
    +char* FastUInt64ToBuffer(uint64 i, char* buffer);  // inline below
    +LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer);
    +LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer);
    +LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer);
    +
    +// at least 22 bytes long
    +inline char* FastIntToBuffer(int i, char* buffer) {
    +  return (sizeof(i) == 4 ?
    +          FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
    +}
    +inline char* FastUIntToBuffer(unsigned int i, char* buffer) {
    +  return (sizeof(i) == 4 ?
    +          FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
    +}
    +inline char* FastLongToBuffer(long i, char* buffer) {
    +  return (sizeof(i) == 4 ?
    +          FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
    +}
    +inline char* FastULongToBuffer(unsigned long i, char* buffer) {
    +  return (sizeof(i) == 4 ?
    +          FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
    +}
    +
    +// ----------------------------------------------------------------------
    +// FastInt32ToBufferLeft()
    +// FastUInt32ToBufferLeft()
    +// FastInt64ToBufferLeft()
    +// FastUInt64ToBufferLeft()
    +//
    +// Like the Fast*ToBuffer() functions above, these are intended for speed.
    +// Unlike the Fast*ToBuffer() functions, however, these functions write
    +// their output to the beginning of the buffer (hence the name, as the
    +// output is left-aligned).  The caller is responsible for ensuring that
    +// the buffer has enough space to hold the output.
    +//
    +// Returns a pointer to the end of the string (i.e. the null character
    +// terminating the string).
    +// ----------------------------------------------------------------------
    +
    +LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer);
    +LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer);
    +LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer);
    +LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer);
    +
    +// Just define these in terms of the above.
    +inline char* FastUInt32ToBuffer(uint32 i, char* buffer) {
    +  FastUInt32ToBufferLeft(i, buffer);
    +  return buffer;
    +}
    +inline char* FastUInt64ToBuffer(uint64 i, char* buffer) {
    +  FastUInt64ToBufferLeft(i, buffer);
    +  return buffer;
    +}
    +
    +// ----------------------------------------------------------------------
    +// SimpleItoa()
    +//    Description: converts an integer to a string.
    +//
    +//    Return value: string
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT string SimpleItoa(int i);
    +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i);
    +LIBPROTOBUF_EXPORT string SimpleItoa(long i);
    +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i);
    +LIBPROTOBUF_EXPORT string SimpleItoa(long long i);
    +LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i);
    +
    +// ----------------------------------------------------------------------
    +// SimpleDtoa()
    +// SimpleFtoa()
    +// DoubleToBuffer()
    +// FloatToBuffer()
    +//    Description: converts a double or float to a string which, if
    +//    passed to NoLocaleStrtod(), will produce the exact same original double
    +//    (except in case of NaN; all NaNs are considered the same value).
    +//    We try to keep the string short but it's not guaranteed to be as
    +//    short as possible.
    +//
    +//    DoubleToBuffer() and FloatToBuffer() write the text to the given
    +//    buffer and return it.  The buffer must be at least
    +//    kDoubleToBufferSize bytes for doubles and kFloatToBufferSize
    +//    bytes for floats.  kFastToBufferSize is also guaranteed to be large
    +//    enough to hold either.
    +//
    +//    Return value: string
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT string SimpleDtoa(double value);
    +LIBPROTOBUF_EXPORT string SimpleFtoa(float value);
    +
    +LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer);
    +LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer);
    +
    +// In practice, doubles should never need more than 24 bytes and floats
    +// should never need more than 14 (including null terminators), but we
    +// overestimate to be safe.
    +static const int kDoubleToBufferSize = 32;
    +static const int kFloatToBufferSize = 24;
    +
    +// ----------------------------------------------------------------------
    +// ToString() are internal help methods used in StrCat() and Join()
    +// ----------------------------------------------------------------------
    +namespace internal {
    +inline string ToString(int i) {
    +  return SimpleItoa(i);
    +}
    +
    +inline string ToString(string a) {
    +  return a;
    +}
    +}  // namespace internal
    +
    +// ----------------------------------------------------------------------
    +// StrCat()
    +//    These methods join some strings together.
    +// ----------------------------------------------------------------------
    +template 
    +string StrCat(
    +    const T1& a, const T2& b, const T3& c, const T4& d, const T5& e) {
    +  return internal::ToString(a) + internal::ToString(b) +
    +      internal::ToString(c) + internal::ToString(d) + internal::ToString(e);
    +}
    +
    +template 
    +string StrCat(
    +    const T1& a, const T2& b, const T3& c, const T4& d) {
    +  return internal::ToString(a) + internal::ToString(b) +
    +      internal::ToString(c) + internal::ToString(d);
    +}
    +
    +template 
    +string StrCat(const T1& a, const T2& b, const T3& c) {
    +  return internal::ToString(a) + internal::ToString(b) +
    +      internal::ToString(c);
    +}
    +
    +template 
    +string StrCat(const T1& a, const T2& b) {
    +  return internal::ToString(a) + internal::ToString(b);
    +}
    +
    +// ----------------------------------------------------------------------
    +// Join()
    +//    These methods concatenate a range of components into a C++ string, using
    +//    the C-string "delim" as a separator between components.
    +// ----------------------------------------------------------------------
    +template 
    +void Join(Iterator start, Iterator end,
    +          const char* delim, string* result) {
    +  for (Iterator it = start; it != end; ++it) {
    +    if (it != start) {
    +      result->append(delim);
    +    }
    +    result->append(internal::ToString(*it));
    +  }
    +}
    +
    +template 
    +string Join(const Range& components,
    +            const char* delim) {
    +  string result;
    +  Join(components.begin(), components.end(), delim, &result);
    +  return result;
    +}
    +
    +// ----------------------------------------------------------------------
    +// ToHex()
    +//    Return a lower-case hex string representation of the given integer.
    +// ----------------------------------------------------------------------
    +LIBPROTOBUF_EXPORT string ToHex(uint64 num);
    +
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc b/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc
    new file mode 100644
    index 000000000000..c9d95899f524
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc
    @@ -0,0 +1,134 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +namespace strings {
    +
    +using internal::SubstituteArg;
    +
    +// Returns the number of args in arg_array which were passed explicitly
    +// to Substitute().
    +static int CountSubstituteArgs(const SubstituteArg* const* args_array) {
    +  int count = 0;
    +  while (args_array[count] != NULL && args_array[count]->size() != -1) {
    +    ++count;
    +  }
    +  return count;
    +}
    +
    +string Substitute(
    +    const char* format,
    +    const SubstituteArg& arg0, const SubstituteArg& arg1,
    +    const SubstituteArg& arg2, const SubstituteArg& arg3,
    +    const SubstituteArg& arg4, const SubstituteArg& arg5,
    +    const SubstituteArg& arg6, const SubstituteArg& arg7,
    +    const SubstituteArg& arg8, const SubstituteArg& arg9) {
    +  string result;
    +  SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4,
    +                                       arg5, arg6, arg7, arg8, arg9);
    +  return result;
    +}
    +
    +void SubstituteAndAppend(
    +    string* output, const char* format,
    +    const SubstituteArg& arg0, const SubstituteArg& arg1,
    +    const SubstituteArg& arg2, const SubstituteArg& arg3,
    +    const SubstituteArg& arg4, const SubstituteArg& arg5,
    +    const SubstituteArg& arg6, const SubstituteArg& arg7,
    +    const SubstituteArg& arg8, const SubstituteArg& arg9) {
    +  const SubstituteArg* const args_array[] = {
    +    &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL
    +  };
    +
    +  // Determine total size needed.
    +  int size = 0;
    +  for (int i = 0; format[i] != '\0'; i++) {
    +    if (format[i] == '$') {
    +      if (ascii_isdigit(format[i+1])) {
    +        int index = format[i+1] - '0';
    +        if (args_array[index]->size() == -1) {
    +          GOOGLE_LOG(DFATAL)
    +            << "strings::Substitute format string invalid: asked for \"$"
    +            << index << "\", but only " << CountSubstituteArgs(args_array)
    +            << " args were given.  Full format string was: \""
    +            << CEscape(format) << "\".";
    +          return;
    +        }
    +        size += args_array[index]->size();
    +        ++i;  // Skip next char.
    +      } else if (format[i+1] == '$') {
    +        ++size;
    +        ++i;  // Skip next char.
    +      } else {
    +        GOOGLE_LOG(DFATAL)
    +          << "Invalid strings::Substitute() format string: \""
    +          << CEscape(format) << "\".";
    +        return;
    +      }
    +    } else {
    +      ++size;
    +    }
    +  }
    +
    +  if (size == 0) return;
    +
    +  // Build the string.
    +  int original_size = output->size();
    +  STLStringResizeUninitialized(output, original_size + size);
    +  char* target = string_as_array(output) + original_size;
    +  for (int i = 0; format[i] != '\0'; i++) {
    +    if (format[i] == '$') {
    +      if (ascii_isdigit(format[i+1])) {
    +        const SubstituteArg* src = args_array[format[i+1] - '0'];
    +        memcpy(target, src->data(), src->size());
    +        target += src->size();
    +        ++i;  // Skip next char.
    +      } else if (format[i+1] == '$') {
    +        *target++ = '$';
    +        ++i;  // Skip next char.
    +      }
    +    } else {
    +      *target++ = format[i];
    +    }
    +  }
    +
    +  GOOGLE_DCHECK_EQ(target - output->data(), output->size());
    +}
    +
    +}  // namespace strings
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h b/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h
    new file mode 100644
    index 000000000000..7ee442af77b3
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h
    @@ -0,0 +1,170 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +// from google3/strings/substitute.h
    +
    +#include 
    +#include 
    +#include 
    +
    +#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
    +#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace strings {
    +
    +// ----------------------------------------------------------------------
    +// strings::Substitute()
    +// strings::SubstituteAndAppend()
    +//   Kind of like StringPrintf, but different.
    +//
    +//   Example:
    +//     string GetMessage(string first_name, string last_name, int age) {
    +//       return strings::Substitute("My name is $0 $1 and I am $2 years old.",
    +//                                  first_name, last_name, age);
    +//     }
    +//
    +//   Differences from StringPrintf:
    +//   * The format string does not identify the types of arguments.
    +//     Instead, the magic of C++ deals with this for us.  See below
    +//     for a list of accepted types.
    +//   * Substitutions in the format string are identified by a '$'
    +//     followed by a digit.  So, you can use arguments out-of-order and
    +//     use the same argument multiple times.
    +//   * It's much faster than StringPrintf.
    +//
    +//   Supported types:
    +//   * Strings (const char*, const string&)
    +//     * Note that this means you do not have to add .c_str() to all of
    +//       your strings.  In fact, you shouldn't; it will be slower.
    +//   * int32, int64, uint32, uint64:  Formatted using SimpleItoa().
    +//   * float, double:  Formatted using SimpleFtoa() and SimpleDtoa().
    +//   * bool:  Printed as "true" or "false".
    +//
    +//   SubstituteAndAppend() is like Substitute() but appends the result to
    +//   *output.  Example:
    +//
    +//     string str;
    +//     strings::SubstituteAndAppend(&str,
    +//                                  "My name is $0 $1 and I am $2 years old.",
    +//                                  first_name, last_name, age);
    +//
    +//   Substitute() is significantly faster than StringPrintf().  For very
    +//   large strings, it may be orders of magnitude faster.
    +// ----------------------------------------------------------------------
    +
    +namespace internal {  // Implementation details.
    +
    +class SubstituteArg {
    + public:
    +  inline SubstituteArg(const char* value)
    +    : text_(value), size_(strlen(text_)) {}
    +  inline SubstituteArg(const string& value)
    +    : text_(value.data()), size_(value.size()) {}
    +
    +  // Indicates that no argument was given.
    +  inline explicit SubstituteArg()
    +    : text_(NULL), size_(-1) {}
    +
    +  // Primitives
    +  // We don't overload for signed and unsigned char because if people are
    +  // explicitly declaring their chars as signed or unsigned then they are
    +  // probably actually using them as 8-bit integers and would probably
    +  // prefer an integer representation.  But, we don't really know.  So, we
    +  // make the caller decide what to do.
    +  inline SubstituteArg(char value)
    +    : text_(scratch_), size_(1) { scratch_[0] = value; }
    +  inline SubstituteArg(short value)
    +    : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(unsigned short value)
    +    : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(int value)
    +    : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(unsigned int value)
    +    : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(long value)
    +    : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(unsigned long value)
    +    : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(long long value)
    +    : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(unsigned long long value)
    +    : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(float value)
    +    : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(double value)
    +    : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {}
    +  inline SubstituteArg(bool value)
    +    : text_(value ? "true" : "false"), size_(strlen(text_)) {}
    +
    +  inline const char* data() const { return text_; }
    +  inline int size() const { return size_; }
    +
    + private:
    +  const char* text_;
    +  int size_;
    +  char scratch_[kFastToBufferSize];
    +};
    +
    +}  // namespace internal
    +
    +LIBPROTOBUF_EXPORT string Substitute(
    +  const char* format,
    +  const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg9 = internal::SubstituteArg());
    +
    +LIBPROTOBUF_EXPORT void SubstituteAndAppend(
    +  string* output, const char* format,
    +  const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
    +  const internal::SubstituteArg& arg9 = internal::SubstituteArg());
    +
    +}  // namespace strings
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h b/toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h
    new file mode 100644
    index 000000000000..4f30ffa3bbec
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h
    @@ -0,0 +1,138 @@
    +// Copyright 2005 Google Inc.
    +// All rights reserved.
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// ----
    +// Author: lar@google.com (Laramie Leavitt)
    +//
    +// Template metaprogramming utility functions.
    +//
    +// This code is compiled directly on many platforms, including client
    +// platforms like Windows, Mac, and embedded systems.  Before making
    +// any changes here, make sure that you're not breaking any platforms.
    +//
    +//
    +// The names choosen here reflect those used in tr1 and the boost::mpl
    +// library, there are similar operations used in the Loki library as
    +// well.  I prefer the boost names for 2 reasons:
    +// 1.  I think that portions of the Boost libraries are more likely to
    +// be included in the c++ standard.
    +// 2.  It is not impossible that some of the boost libraries will be
    +// included in our own build in the future.
    +// Both of these outcomes means that we may be able to directly replace
    +// some of these with boost equivalents.
    +//
    +#ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
    +#define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +// Types small_ and big_ are guaranteed such that sizeof(small_) <
    +// sizeof(big_)
    +typedef char small_;
    +
    +struct big_ {
    +  char dummy[2];
    +};
    +
    +// Identity metafunction.
    +template 
    +struct identity_ {
    +  typedef T type;
    +};
    +
    +// integral_constant, defined in tr1, is a wrapper for an integer
    +// value. We don't really need this generality; we could get away
    +// with hardcoding the integer type to bool. We use the fully
    +// general integer_constant for compatibility with tr1.
    +
    +template
    +struct integral_constant {
    +  static const T value = v;
    +  typedef T value_type;
    +  typedef integral_constant type;
    +};
    +
    +template  const T integral_constant::value;
    +
    +
    +// Abbreviations: true_type and false_type are structs that represent boolean
    +// true and false values. Also define the boost::mpl versions of those names,
    +// true_ and false_.
    +typedef integral_constant  true_type;
    +typedef integral_constant false_type;
    +typedef true_type  true_;
    +typedef false_type false_;
    +
    +// if_ is a templatized conditional statement.
    +// if_ is a compile time evaluation of cond.
    +// if_<>::type contains A if cond is true, B otherwise.
    +template
    +struct if_{
    +  typedef A type;
    +};
    +
    +template
    +struct if_ {
    +  typedef B type;
    +};
    +
    +
    +// type_equals_ is a template type comparator, similar to Loki IsSameType.
    +// type_equals_::value is true iff "A" is the same type as "B".
    +//
    +// New code should prefer base::is_same, defined in base/type_traits.h.
    +// It is functionally identical, but is_same is the standard spelling.
    +template
    +struct type_equals_ : public false_ {
    +};
    +
    +template
    +struct type_equals_ : public true_ {
    +};
    +
    +// and_ is a template && operator.
    +// and_::value evaluates "A::value && B::value".
    +template
    +struct and_ : public integral_constant {
    +};
    +
    +// or_ is a template || operator.
    +// or_::value evaluates "A::value || B::value".
    +template
    +struct or_ : public integral_constant {
    +};
    +
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/type_traits.h b/toolkit/components/protobuf/src/google/protobuf/stubs/type_traits.h
    new file mode 100644
    index 000000000000..0ef166b7abde
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/stubs/type_traits.h
    @@ -0,0 +1,334 @@
    +// Copyright (c) 2006, Google Inc.
    +// All rights reserved.
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// ----
    +// Author: Matt Austern
    +//
    +// This code is compiled directly on many platforms, including client
    +// platforms like Windows, Mac, and embedded systems.  Before making
    +// any changes here, make sure that you're not breaking any platforms.
    +//
    +// Define a small subset of tr1 type traits. The traits we define are:
    +//   is_integral
    +//   is_floating_point
    +//   is_pointer
    +//   is_enum
    +//   is_reference
    +//   is_pod
    +//   has_trivial_constructor
    +//   has_trivial_copy
    +//   has_trivial_assign
    +//   has_trivial_destructor
    +//   remove_const
    +//   remove_volatile
    +//   remove_cv
    +//   remove_reference
    +//   add_reference
    +//   remove_pointer
    +//   is_same
    +//   is_convertible
    +// We can add more type traits as required.
    +
    +#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_
    +#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_
    +
    +#include                   // For pair
    +
    +#include   // For true_type and false_type
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +template  struct is_integral;
    +template  struct is_floating_point;
    +template  struct is_pointer;
    +// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
    +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
    +// is_enum uses is_convertible, which is not available on MSVC.
    +template  struct is_enum;
    +#endif
    +template  struct is_reference;
    +template  struct is_pod;
    +template  struct has_trivial_constructor;
    +template  struct has_trivial_copy;
    +template  struct has_trivial_assign;
    +template  struct has_trivial_destructor;
    +template  struct remove_const;
    +template  struct remove_volatile;
    +template  struct remove_cv;
    +template  struct remove_reference;
    +template  struct add_reference;
    +template  struct remove_pointer;
    +template  struct is_same;
    +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
    +template  struct is_convertible;
    +#endif
    +
    +// is_integral is false except for the built-in integer types. A
    +// cv-qualified type is integral if and only if the underlying type is.
    +template  struct is_integral : false_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +#if defined(_MSC_VER)
    +// wchar_t is not by default a distinct type from unsigned short in
    +// Microsoft C.
    +// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
    +template<> struct is_integral<__wchar_t> : true_type { };
    +#else
    +template<> struct is_integral : true_type { };
    +#endif
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template<> struct is_integral : true_type { };
    +template  struct is_integral : is_integral { };
    +template  struct is_integral : is_integral { };
    +template  struct is_integral : is_integral { };
    +
    +// is_floating_point is false except for the built-in floating-point types.
    +// A cv-qualified type is integral if and only if the underlying type is.
    +template  struct is_floating_point : false_type { };
    +template<> struct is_floating_point : true_type { };
    +template<> struct is_floating_point : true_type { };
    +template<> struct is_floating_point : true_type { };
    +template  struct is_floating_point
    +    : is_floating_point { };
    +template  struct is_floating_point
    +    : is_floating_point { };
    +template  struct is_floating_point
    +    : is_floating_point { };
    +
    +// is_pointer is false except for pointer types. A cv-qualified type (e.g.
    +// "int* const", as opposed to "int const*") is cv-qualified if and only if
    +// the underlying type is.
    +template  struct is_pointer : false_type { };
    +template  struct is_pointer : true_type { };
    +template  struct is_pointer : is_pointer { };
    +template  struct is_pointer : is_pointer { };
    +template  struct is_pointer : is_pointer { };
    +
    +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
    +
    +namespace internal {
    +
    +template  struct is_class_or_union {
    +  template  static small_ tester(void (U::*)());
    +  template  static big_ tester(...);
    +  static const bool value = sizeof(tester(0)) == sizeof(small_);
    +};
    +
    +// is_convertible chokes if the first argument is an array. That's why
    +// we use add_reference here.
    +template  struct is_enum_impl
    +    : is_convertible::type, int> { };
    +
    +template  struct is_enum_impl : false_type { };
    +
    +}  // namespace internal
    +
    +// Specified by TR1 [4.5.1] primary type categories.
    +
    +// Implementation note:
    +//
    +// Each type is either void, integral, floating point, array, pointer,
    +// reference, member object pointer, member function pointer, enum,
    +// union or class. Out of these, only integral, floating point, reference,
    +// class and enum types are potentially convertible to int. Therefore,
    +// if a type is not a reference, integral, floating point or class and
    +// is convertible to int, it's a enum. Adding cv-qualification to a type
    +// does not change whether it's an enum.
    +//
    +// Is-convertible-to-int check is done only if all other checks pass,
    +// because it can't be used with some types (e.g. void or classes with
    +// inaccessible conversion operators).
    +template  struct is_enum
    +    : internal::is_enum_impl<
    +          is_same::value ||
    +              is_integral::value ||
    +              is_floating_point::value ||
    +              is_reference::value ||
    +              internal::is_class_or_union::value,
    +          T> { };
    +
    +template  struct is_enum : is_enum { };
    +template  struct is_enum : is_enum { };
    +template  struct is_enum : is_enum { };
    +
    +#endif
    +
    +// is_reference is false except for reference types.
    +template struct is_reference : false_type {};
    +template struct is_reference : true_type {};
    +
    +
    +// We can't get is_pod right without compiler help, so fail conservatively.
    +// We will assume it's false except for arithmetic types, enumerations,
    +// pointers and cv-qualified versions thereof. Note that std::pair
    +// is not a POD even if T and U are PODs.
    +template  struct is_pod
    + : integral_constant::value ||
    +                            is_floating_point::value ||
    +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
    +                            // is_enum is not available on MSVC.
    +                            is_enum::value ||
    +#endif
    +                            is_pointer::value)> { };
    +template  struct is_pod : is_pod { };
    +template  struct is_pod : is_pod { };
    +template  struct is_pod : is_pod { };
    +
    +
    +// We can't get has_trivial_constructor right without compiler help, so
    +// fail conservatively. We will assume it's false except for: (1) types
    +// for which is_pod is true. (2) std::pair of types with trivial
    +// constructors. (3) array of a type with a trivial constructor.
    +// (4) const versions thereof.
    +template  struct has_trivial_constructor : is_pod { };
    +template  struct has_trivial_constructor >
    +  : integral_constant::value &&
    +                       has_trivial_constructor::value)> { };
    +template  struct has_trivial_constructor
    +  : has_trivial_constructor { };
    +template  struct has_trivial_constructor
    +  : has_trivial_constructor { };
    +
    +// We can't get has_trivial_copy right without compiler help, so fail
    +// conservatively. We will assume it's false except for: (1) types
    +// for which is_pod is true. (2) std::pair of types with trivial copy
    +// constructors. (3) array of a type with a trivial copy constructor.
    +// (4) const versions thereof.
    +template  struct has_trivial_copy : is_pod { };
    +template  struct has_trivial_copy >
    +  : integral_constant::value &&
    +                       has_trivial_copy::value)> { };
    +template  struct has_trivial_copy
    +  : has_trivial_copy { };
    +template  struct has_trivial_copy : has_trivial_copy { };
    +
    +// We can't get has_trivial_assign right without compiler help, so fail
    +// conservatively. We will assume it's false except for: (1) types
    +// for which is_pod is true. (2) std::pair of types with trivial copy
    +// constructors. (3) array of a type with a trivial assign constructor.
    +template  struct has_trivial_assign : is_pod { };
    +template  struct has_trivial_assign >
    +  : integral_constant::value &&
    +                       has_trivial_assign::value)> { };
    +template  struct has_trivial_assign
    +  : has_trivial_assign { };
    +
    +// We can't get has_trivial_destructor right without compiler help, so
    +// fail conservatively. We will assume it's false except for: (1) types
    +// for which is_pod is true. (2) std::pair of types with trivial
    +// destructors. (3) array of a type with a trivial destructor.
    +// (4) const versions thereof.
    +template  struct has_trivial_destructor : is_pod { };
    +template  struct has_trivial_destructor >
    +  : integral_constant::value &&
    +                       has_trivial_destructor::value)> { };
    +template  struct has_trivial_destructor
    +  : has_trivial_destructor { };
    +template  struct has_trivial_destructor
    +  : has_trivial_destructor { };
    +
    +// Specified by TR1 [4.7.1]
    +template struct remove_const { typedef T type; };
    +template struct remove_const { typedef T type; };
    +template struct remove_volatile { typedef T type; };
    +template struct remove_volatile { typedef T type; };
    +template struct remove_cv {
    +  typedef typename remove_const::type>::type type;
    +};
    +
    +
    +// Specified by TR1 [4.7.2] Reference modifications.
    +template struct remove_reference { typedef T type; };
    +template struct remove_reference { typedef T type; };
    +
    +template  struct add_reference { typedef T& type; };
    +template  struct add_reference { typedef T& type; };
    +
    +// Specified by TR1 [4.7.4] Pointer modifications.
    +template struct remove_pointer { typedef T type; };
    +template struct remove_pointer { typedef T type; };
    +template struct remove_pointer { typedef T type; };
    +template struct remove_pointer { typedef T type; };
    +template struct remove_pointer {
    +  typedef T type; };
    +
    +// Specified by TR1 [4.6] Relationships between types
    +template struct is_same : public false_type { };
    +template struct is_same : public true_type { };
    +
    +// Specified by TR1 [4.6] Relationships between types
    +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
    +namespace internal {
    +
    +// This class is an implementation detail for is_convertible, and you
    +// don't need to know how it works to use is_convertible. For those
    +// who care: we declare two different functions, one whose argument is
    +// of type To and one with a variadic argument list. We give them
    +// return types of different size, so we can use sizeof to trick the
    +// compiler into telling us which function it would have chosen if we
    +// had called it with an argument of type From.  See Alexandrescu's
    +// _Modern C++ Design_ for more details on this sort of trick.
    +
    +template 
    +struct ConvertHelper {
    +  static small_ Test(To);
    +  static big_ Test(...);
    +  static From Create();
    +};
    +}  // namespace internal
    +
    +// Inherits from true_type if From is convertible to To, false_type otherwise.
    +template 
    +struct is_convertible
    +    : integral_constant::Test(
    +                                  internal::ConvertHelper::Create()))
    +                        == sizeof(small_)> {
    +};
    +#endif
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    +
    +#endif  // GOOGLE_PROTOBUF_TYPE_TRAITS_H_
    diff --git a/toolkit/components/protobuf/src/google/protobuf/text_format.cc b/toolkit/components/protobuf/src/google/protobuf/text_format.cc
    new file mode 100644
    index 000000000000..84cdbb57e434
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/text_format.cc
    @@ -0,0 +1,1746 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: jschorr@google.com (Joseph Schorr)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +namespace {
    +
    +inline bool IsHexNumber(const string& str) {
    +  return (str.length() >= 2 && str[0] == '0' &&
    +          (str[1] == 'x' || str[1] == 'X'));
    +}
    +
    +inline bool IsOctNumber(const string& str) {
    +  return (str.length() >= 2 && str[0] == '0' &&
    +          (str[1] >= '0' && str[1] < '8'));
    +}
    +
    +}  // namespace
    +
    +string Message::DebugString() const {
    +  string debug_string;
    +
    +  TextFormat::PrintToString(*this, &debug_string);
    +
    +  return debug_string;
    +}
    +
    +string Message::ShortDebugString() const {
    +  string debug_string;
    +
    +  TextFormat::Printer printer;
    +  printer.SetSingleLineMode(true);
    +
    +  printer.PrintToString(*this, &debug_string);
    +  // Single line mode currently might have an extra space at the end.
    +  if (debug_string.size() > 0 &&
    +      debug_string[debug_string.size() - 1] == ' ') {
    +    debug_string.resize(debug_string.size() - 1);
    +  }
    +
    +  return debug_string;
    +}
    +
    +string Message::Utf8DebugString() const {
    +  string debug_string;
    +
    +  TextFormat::Printer printer;
    +  printer.SetUseUtf8StringEscaping(true);
    +
    +  printer.PrintToString(*this, &debug_string);
    +
    +  return debug_string;
    +}
    +
    +void Message::PrintDebugString() const {
    +  printf("%s", DebugString().c_str());
    +}
    +
    +
    +// ===========================================================================
    +// Implementation of the parse information tree class.
    +TextFormat::ParseInfoTree::ParseInfoTree() { }
    +
    +TextFormat::ParseInfoTree::~ParseInfoTree() {
    +  // Remove any nested information trees, as they are owned by this tree.
    +  for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) {
    +    STLDeleteElements(&(it->second));
    +  }
    +}
    +
    +void TextFormat::ParseInfoTree::RecordLocation(
    +    const FieldDescriptor* field,
    +    TextFormat::ParseLocation location) {
    +  locations_[field].push_back(location);
    +}
    +
    +TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
    +    const FieldDescriptor* field) {
    +  // Owned by us in the map.
    +  TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree();
    +  vector* trees = &nested_[field];
    +  GOOGLE_CHECK(trees);
    +  trees->push_back(instance);
    +  return instance;
    +}
    +
    +void CheckFieldIndex(const FieldDescriptor* field, int index) {
    +  if (field == NULL) { return; }
    +
    +  if (field->is_repeated() && index == -1) {
    +    GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
    +                << "Field: " << field->name();
    +  } else if (!field->is_repeated() && index != -1) {
    +    GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
    +                << "Field: " << field->name();
    +  }
    +}
    +
    +TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
    +    const FieldDescriptor* field, int index) const {
    +  CheckFieldIndex(field, index);
    +  if (index == -1) { index = 0; }
    +
    +  const vector* locations =
    +      FindOrNull(locations_, field);
    +  if (locations == NULL || index >= locations->size()) {
    +    return TextFormat::ParseLocation();
    +  }
    +
    +  return (*locations)[index];
    +}
    +
    +TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
    +    const FieldDescriptor* field, int index) const {
    +  CheckFieldIndex(field, index);
    +  if (index == -1) { index = 0; }
    +
    +  const vector* trees = FindOrNull(nested_, field);
    +  if (trees == NULL || index >= trees->size()) {
    +    return NULL;
    +  }
    +
    +  return (*trees)[index];
    +}
    +
    +
    +// ===========================================================================
    +// Internal class for parsing an ASCII representation of a Protocol Message.
    +// This class makes use of the Protocol Message compiler's tokenizer found
    +// in //google/protobuf/io/tokenizer.h. Note that class's Parse
    +// method is *not* thread-safe and should only be used in a single thread at
    +// a time.
    +
    +// Makes code slightly more readable.  The meaning of "DO(foo)" is
    +// "Execute foo and fail if it fails.", where failure is indicated by
    +// returning false. Borrowed from parser.cc (Thanks Kenton!).
    +#define DO(STATEMENT) if (STATEMENT) {} else return false
    +
    +class TextFormat::Parser::ParserImpl {
    + public:
    +
    +  // Determines if repeated values for non-repeated fields and
    +  // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
    +  // required/optional field named "foo", or "baz: 1 qux: 2"
    +  // where "baz" and "qux" are members of the same oneof.
    +  enum SingularOverwritePolicy {
    +    ALLOW_SINGULAR_OVERWRITES = 0,   // the last value is retained
    +    FORBID_SINGULAR_OVERWRITES = 1,  // an error is issued
    +  };
    +
    +  ParserImpl(const Descriptor* root_message_type,
    +             io::ZeroCopyInputStream* input_stream,
    +             io::ErrorCollector* error_collector,
    +             TextFormat::Finder* finder,
    +             ParseInfoTree* parse_info_tree,
    +             SingularOverwritePolicy singular_overwrite_policy,
    +             bool allow_case_insensitive_field,
    +             bool allow_unknown_field,
    +             bool allow_unknown_enum,
    +             bool allow_field_number,
    +             bool allow_relaxed_whitespace)
    +    : error_collector_(error_collector),
    +      finder_(finder),
    +      parse_info_tree_(parse_info_tree),
    +      tokenizer_error_collector_(this),
    +      tokenizer_(input_stream, &tokenizer_error_collector_),
    +      root_message_type_(root_message_type),
    +      singular_overwrite_policy_(singular_overwrite_policy),
    +      allow_case_insensitive_field_(allow_case_insensitive_field),
    +      allow_unknown_field_(allow_unknown_field),
    +      allow_unknown_enum_(allow_unknown_enum),
    +      allow_field_number_(allow_field_number),
    +      had_errors_(false) {
    +    // For backwards-compatibility with proto1, we need to allow the 'f' suffix
    +    // for floats.
    +    tokenizer_.set_allow_f_after_float(true);
    +
    +    // '#' starts a comment.
    +    tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
    +
    +    if (allow_relaxed_whitespace) {
    +      tokenizer_.set_require_space_after_number(false);
    +      tokenizer_.set_allow_multiline_strings(true);
    +    }
    +
    +    // Consume the starting token.
    +    tokenizer_.Next();
    +  }
    +  ~ParserImpl() { }
    +
    +  // Parses the ASCII representation specified in input and saves the
    +  // information into the output pointer (a Message). Returns
    +  // false if an error occurs (an error will also be logged to
    +  // GOOGLE_LOG(ERROR)).
    +  bool Parse(Message* output) {
    +    // Consume fields until we cannot do so anymore.
    +    while (true) {
    +      if (LookingAtType(io::Tokenizer::TYPE_END)) {
    +        return !had_errors_;
    +      }
    +
    +      DO(ConsumeField(output));
    +    }
    +  }
    +
    +  bool ParseField(const FieldDescriptor* field, Message* output) {
    +    bool suc;
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      suc = ConsumeFieldMessage(output, output->GetReflection(), field);
    +    } else {
    +      suc = ConsumeFieldValue(output, output->GetReflection(), field);
    +    }
    +    return suc && LookingAtType(io::Tokenizer::TYPE_END);
    +  }
    +
    +  void ReportError(int line, int col, const string& message) {
    +    had_errors_ = true;
    +    if (error_collector_ == NULL) {
    +      if (line >= 0) {
    +        GOOGLE_LOG(ERROR) << "Error parsing text-format "
    +                   << root_message_type_->full_name()
    +                   << ": " << (line + 1) << ":"
    +                   << (col + 1) << ": " << message;
    +      } else {
    +        GOOGLE_LOG(ERROR) << "Error parsing text-format "
    +                   << root_message_type_->full_name()
    +                   << ": " << message;
    +      }
    +    } else {
    +      error_collector_->AddError(line, col, message);
    +    }
    +  }
    +
    +  void ReportWarning(int line, int col, const string& message) {
    +    if (error_collector_ == NULL) {
    +      if (line >= 0) {
    +        GOOGLE_LOG(WARNING) << "Warning parsing text-format "
    +                     << root_message_type_->full_name()
    +                     << ": " << (line + 1) << ":"
    +                     << (col + 1) << ": " << message;
    +      } else {
    +        GOOGLE_LOG(WARNING) << "Warning parsing text-format "
    +                     << root_message_type_->full_name()
    +                     << ": " << message;
    +      }
    +    } else {
    +      error_collector_->AddWarning(line, col, message);
    +    }
    +  }
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
    +
    +  // Reports an error with the given message with information indicating
    +  // the position (as derived from the current token).
    +  void ReportError(const string& message) {
    +    ReportError(tokenizer_.current().line, tokenizer_.current().column,
    +                message);
    +  }
    +
    +  // Reports a warning with the given message with information indicating
    +  // the position (as derived from the current token).
    +  void ReportWarning(const string& message) {
    +    ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
    +                  message);
    +  }
    +
    +  // Consumes the specified message with the given starting delimeter.
    +  // This method checks to see that the end delimeter at the conclusion of
    +  // the consumption matches the starting delimeter passed in here.
    +  bool ConsumeMessage(Message* message, const string delimeter) {
    +    while (!LookingAt(">") &&  !LookingAt("}")) {
    +      DO(ConsumeField(message));
    +    }
    +
    +    // Confirm that we have a valid ending delimeter.
    +    DO(Consume(delimeter));
    +
    +    return true;
    +  }
    +
    +
    +  // Consumes the current field (as returned by the tokenizer) on the
    +  // passed in message.
    +  bool ConsumeField(Message* message) {
    +    const Reflection* reflection = message->GetReflection();
    +    const Descriptor* descriptor = message->GetDescriptor();
    +
    +    string field_name;
    +
    +    const FieldDescriptor* field = NULL;
    +    int start_line = tokenizer_.current().line;
    +    int start_column = tokenizer_.current().column;
    +
    +    if (TryConsume("[")) {
    +      // Extension.
    +      DO(ConsumeIdentifier(&field_name));
    +      while (TryConsume(".")) {
    +        string part;
    +        DO(ConsumeIdentifier(&part));
    +        field_name += ".";
    +        field_name += part;
    +      }
    +      DO(Consume("]"));
    +
    +      field = (finder_ != NULL
    +               ? finder_->FindExtension(message, field_name)
    +               : reflection->FindKnownExtensionByName(field_name));
    +
    +      if (field == NULL) {
    +        if (!allow_unknown_field_) {
    +          ReportError("Extension \"" + field_name + "\" is not defined or "
    +                      "is not an extension of \"" +
    +                      descriptor->full_name() + "\".");
    +          return false;
    +        } else {
    +          ReportWarning("Extension \"" + field_name + "\" is not defined or "
    +                        "is not an extension of \"" +
    +                        descriptor->full_name() + "\".");
    +        }
    +      }
    +    } else {
    +      DO(ConsumeIdentifier(&field_name));
    +
    +      int32 field_number;
    +      if (allow_field_number_ && safe_strto32(field_name, &field_number)) {
    +        if (descriptor->IsExtensionNumber(field_number)) {
    +          field = reflection->FindKnownExtensionByNumber(field_number);
    +        } else {
    +          field = descriptor->FindFieldByNumber(field_number);
    +        }
    +      } else {
    +        field = descriptor->FindFieldByName(field_name);
    +        // Group names are expected to be capitalized as they appear in the
    +        // .proto file, which actually matches their type names, not their
    +        // field names.
    +        if (field == NULL) {
    +          string lower_field_name = field_name;
    +          LowerString(&lower_field_name);
    +          field = descriptor->FindFieldByName(lower_field_name);
    +          // If the case-insensitive match worked but the field is NOT a group,
    +          if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
    +            field = NULL;
    +          }
    +        }
    +        // Again, special-case group names as described above.
    +        if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
    +            && field->message_type()->name() != field_name) {
    +          field = NULL;
    +        }
    +
    +        if (field == NULL && allow_case_insensitive_field_) {
    +          string lower_field_name = field_name;
    +          LowerString(&lower_field_name);
    +          field = descriptor->FindFieldByLowercaseName(lower_field_name);
    +        }
    +      }
    +
    +      if (field == NULL) {
    +        if (!allow_unknown_field_) {
    +          ReportError("Message type \"" + descriptor->full_name() +
    +                      "\" has no field named \"" + field_name + "\".");
    +          return false;
    +        } else {
    +          ReportWarning("Message type \"" + descriptor->full_name() +
    +                        "\" has no field named \"" + field_name + "\".");
    +        }
    +      }
    +    }
    +
    +    // Skips unknown field.
    +    if (field == NULL) {
    +      GOOGLE_CHECK(allow_unknown_field_);
    +      // Try to guess the type of this field.
    +      // If this field is not a message, there should be a ":" between the
    +      // field name and the field value and also the field value should not
    +      // start with "{" or "<" which indicates the begining of a message body.
    +      // If there is no ":" or there is a "{" or "<" after ":", this field has
    +      // to be a message or the input is ill-formed.
    +      if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
    +        return SkipFieldValue();
    +      } else {
    +        return SkipFieldMessage();
    +      }
    +    }
    +
    +    if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
    +      // Fail if the field is not repeated and it has already been specified.
    +      if (!field->is_repeated() && reflection->HasField(*message, field)) {
    +        ReportError("Non-repeated field \"" + field_name +
    +                    "\" is specified multiple times.");
    +        return false;
    +      }
    +      // Fail if the field is a member of a oneof and another member has already
    +      // been specified.
    +      const OneofDescriptor* oneof = field->containing_oneof();
    +      if (oneof != NULL && reflection->HasOneof(*message, oneof)) {
    +        const FieldDescriptor* other_field =
    +            reflection->GetOneofFieldDescriptor(*message, oneof);
    +        ReportError("Field \"" + field_name + "\" is specified along with "
    +                    "field \"" + other_field->name() + "\", another member "
    +                    "of oneof \"" + oneof->name() + "\".");
    +        return false;
    +      }
    +    }
    +
    +    // Perform special handling for embedded message types.
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      // ':' is optional here.
    +      TryConsume(":");
    +    } else {
    +      // ':' is required here.
    +      DO(Consume(":"));
    +    }
    +
    +    if (field->is_repeated() && TryConsume("[")) {
    +      // Short repeated format, e.g.  "foo: [1, 2, 3]"
    +      while (true) {
    +        if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +          // Perform special handling for embedded message types.
    +          DO(ConsumeFieldMessage(message, reflection, field));
    +        } else {
    +          DO(ConsumeFieldValue(message, reflection, field));
    +        }
    +        if (TryConsume("]")) {
    +          break;
    +        }
    +        DO(Consume(","));
    +      }
    +    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      DO(ConsumeFieldMessage(message, reflection, field));
    +    } else {
    +      DO(ConsumeFieldValue(message, reflection, field));
    +    }
    +
    +    // For historical reasons, fields may optionally be separated by commas or
    +    // semicolons.
    +    TryConsume(";") || TryConsume(",");
    +
    +    if (field->options().deprecated()) {
    +      ReportWarning("text format contains deprecated field \""
    +                    + field_name + "\"");
    +    }
    +
    +    // If a parse info tree exists, add the location for the parsed
    +    // field.
    +    if (parse_info_tree_ != NULL) {
    +      RecordLocation(parse_info_tree_, field,
    +                     ParseLocation(start_line, start_column));
    +    }
    +
    +    return true;
    +  }
    +
    +  // Skips the next field including the field's name and value.
    +  bool SkipField() {
    +    string field_name;
    +    if (TryConsume("[")) {
    +      // Extension name.
    +      DO(ConsumeIdentifier(&field_name));
    +      while (TryConsume(".")) {
    +        string part;
    +        DO(ConsumeIdentifier(&part));
    +        field_name += ".";
    +        field_name += part;
    +      }
    +      DO(Consume("]"));
    +    } else {
    +      DO(ConsumeIdentifier(&field_name));
    +    }
    +
    +    // Try to guess the type of this field.
    +    // If this field is not a message, there should be a ":" between the
    +    // field name and the field value and also the field value should not
    +    // start with "{" or "<" which indicates the begining of a message body.
    +    // If there is no ":" or there is a "{" or "<" after ":", this field has
    +    // to be a message or the input is ill-formed.
    +    if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
    +      DO(SkipFieldValue());
    +    } else {
    +      DO(SkipFieldMessage());
    +    }
    +    // For historical reasons, fields may optionally be separated by commas or
    +    // semicolons.
    +    TryConsume(";") || TryConsume(",");
    +    return true;
    +  }
    +
    +  bool ConsumeFieldMessage(Message* message,
    +                           const Reflection* reflection,
    +                           const FieldDescriptor* field) {
    +
    +    // If the parse information tree is not NULL, create a nested one
    +    // for the nested message.
    +    ParseInfoTree* parent = parse_info_tree_;
    +    if (parent != NULL) {
    +      parse_info_tree_ = CreateNested(parent, field);
    +    }
    +
    +    string delimeter;
    +    if (TryConsume("<")) {
    +      delimeter = ">";
    +    } else {
    +      DO(Consume("{"));
    +      delimeter = "}";
    +    }
    +
    +    if (field->is_repeated()) {
    +      DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
    +    } else {
    +      DO(ConsumeMessage(reflection->MutableMessage(message, field),
    +                        delimeter));
    +    }
    +
    +    // Reset the parse information tree.
    +    parse_info_tree_ = parent;
    +    return true;
    +  }
    +
    +  // Skips the whole body of a message including the begining delimeter and
    +  // the ending delimeter.
    +  bool SkipFieldMessage() {
    +    string delimeter;
    +    if (TryConsume("<")) {
    +      delimeter = ">";
    +    } else {
    +      DO(Consume("{"));
    +      delimeter = "}";
    +    }
    +    while (!LookingAt(">") &&  !LookingAt("}")) {
    +      DO(SkipField());
    +    }
    +    DO(Consume(delimeter));
    +    return true;
    +  }
    +
    +  bool ConsumeFieldValue(Message* message,
    +                         const Reflection* reflection,
    +                         const FieldDescriptor* field) {
    +
    +// Define an easy to use macro for setting fields. This macro checks
    +// to see if the field is repeated (in which case we need to use the Add
    +// methods or not (in which case we need to use the Set methods).
    +#define SET_FIELD(CPPTYPE, VALUE)                                  \
    +        if (field->is_repeated()) {                                \
    +          reflection->Add##CPPTYPE(message, field, VALUE);         \
    +        } else {                                                   \
    +          reflection->Set##CPPTYPE(message, field, VALUE);         \
    +        }                                                          \
    +
    +    switch(field->cpp_type()) {
    +      case FieldDescriptor::CPPTYPE_INT32: {
    +        int64 value;
    +        DO(ConsumeSignedInteger(&value, kint32max));
    +        SET_FIELD(Int32, static_cast(value));
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_UINT32: {
    +        uint64 value;
    +        DO(ConsumeUnsignedInteger(&value, kuint32max));
    +        SET_FIELD(UInt32, static_cast(value));
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_INT64: {
    +        int64 value;
    +        DO(ConsumeSignedInteger(&value, kint64max));
    +        SET_FIELD(Int64, value);
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_UINT64: {
    +        uint64 value;
    +        DO(ConsumeUnsignedInteger(&value, kuint64max));
    +        SET_FIELD(UInt64, value);
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_FLOAT: {
    +        double value;
    +        DO(ConsumeDouble(&value));
    +        SET_FIELD(Float, static_cast(value));
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_DOUBLE: {
    +        double value;
    +        DO(ConsumeDouble(&value));
    +        SET_FIELD(Double, value);
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_STRING: {
    +        string value;
    +        DO(ConsumeString(&value));
    +        SET_FIELD(String, value);
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_BOOL: {
    +        if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
    +          uint64 value;
    +          DO(ConsumeUnsignedInteger(&value, 1));
    +          SET_FIELD(Bool, value);
    +        } else {
    +          string value;
    +          DO(ConsumeIdentifier(&value));
    +          if (value == "true" || value == "True" || value == "t") {
    +            SET_FIELD(Bool, true);
    +          } else if (value == "false" || value == "False" || value == "f") {
    +            SET_FIELD(Bool, false);
    +          } else {
    +            ReportError("Invalid value for boolean field \"" + field->name()
    +                        + "\". Value: \"" + value  + "\".");
    +            return false;
    +          }
    +        }
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_ENUM: {
    +        string value;
    +        const EnumDescriptor* enum_type = field->enum_type();
    +        const EnumValueDescriptor* enum_value = NULL;
    +
    +        if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
    +          DO(ConsumeIdentifier(&value));
    +          // Find the enumeration value.
    +          enum_value = enum_type->FindValueByName(value);
    +
    +        } else if (LookingAt("-") ||
    +                   LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
    +          int64 int_value;
    +          DO(ConsumeSignedInteger(&int_value, kint32max));
    +          value = SimpleItoa(int_value);        // for error reporting
    +          enum_value = enum_type->FindValueByNumber(int_value);
    +        } else {
    +          ReportError("Expected integer or identifier.");
    +          return false;
    +        }
    +
    +        if (enum_value == NULL) {
    +          if (!allow_unknown_enum_) {
    +            ReportError("Unknown enumeration value of \"" + value  + "\" for "
    +                        "field \"" + field->name() + "\".");
    +            return false;
    +          } else {
    +            ReportWarning("Unknown enumeration value of \"" + value  + "\" for "
    +                          "field \"" + field->name() + "\".");
    +            return true;
    +          }
    +        }
    +
    +        SET_FIELD(Enum, enum_value);
    +        break;
    +      }
    +
    +      case FieldDescriptor::CPPTYPE_MESSAGE: {
    +        // We should never get here. Put here instead of a default
    +        // so that if new types are added, we get a nice compiler warning.
    +        GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
    +        break;
    +      }
    +    }
    +#undef SET_FIELD
    +    return true;
    +  }
    +
    +  bool SkipFieldValue() {
    +    if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
    +      while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
    +        tokenizer_.Next();
    +      }
    +      return true;
    +    }
    +    // Possible field values other than string:
    +    //   12345        => TYPE_INTEGER
    +    //   -12345       => TYPE_SYMBOL + TYPE_INTEGER
    +    //   1.2345       => TYPE_FLOAT
    +    //   -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
    +    //   inf          => TYPE_IDENTIFIER
    +    //   -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
    +    //   TYPE_INTEGER => TYPE_IDENTIFIER
    +    // Divides them into two group, one with TYPE_SYMBOL
    +    // and the other without:
    +    //   Group one:
    +    //     12345        => TYPE_INTEGER
    +    //     1.2345       => TYPE_FLOAT
    +    //     inf          => TYPE_IDENTIFIER
    +    //     TYPE_INTEGER => TYPE_IDENTIFIER
    +    //   Group two:
    +    //     -12345       => TYPE_SYMBOL + TYPE_INTEGER
    +    //     -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
    +    //     -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
    +    // As we can see, the field value consists of an optional '-' and one of
    +    // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
    +    bool has_minus = TryConsume("-");
    +    if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
    +        !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
    +        !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
    +      return false;
    +    }
    +    // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
    +    // value while other combinations all generate valid values.
    +    // We check if the value of this combination is valid here.
    +    // TYPE_IDENTIFIER after a '-' should be one of the float values listed
    +    // below:
    +    //   inf, inff, infinity, nan
    +    if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
    +      string text = tokenizer_.current().text;
    +      LowerString(&text);
    +      if (text != "inf" &&
    +          text != "infinity" &&
    +          text != "nan") {
    +        ReportError("Invalid float number: " + text);
    +        return false;
    +      }
    +    }
    +    tokenizer_.Next();
    +    return true;
    +  }
    +
    +  // Returns true if the current token's text is equal to that specified.
    +  bool LookingAt(const string& text) {
    +    return tokenizer_.current().text == text;
    +  }
    +
    +  // Returns true if the current token's type is equal to that specified.
    +  bool LookingAtType(io::Tokenizer::TokenType token_type) {
    +    return tokenizer_.current().type == token_type;
    +  }
    +
    +  // Consumes an identifier and saves its value in the identifier parameter.
    +  // Returns false if the token is not of type IDENTFIER.
    +  bool ConsumeIdentifier(string* identifier) {
    +    if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
    +      *identifier = tokenizer_.current().text;
    +      tokenizer_.Next();
    +      return true;
    +    }
    +
    +    // If allow_field_numer_ or allow_unknown_field_ is true, we should able
    +    // to parse integer identifiers.
    +    if ((allow_field_number_ || allow_unknown_field_)
    +        && LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
    +      *identifier = tokenizer_.current().text;
    +      tokenizer_.Next();
    +      return true;
    +    }
    +
    +    ReportError("Expected identifier.");
    +    return false;
    +  }
    +
    +  // Consumes a string and saves its value in the text parameter.
    +  // Returns false if the token is not of type STRING.
    +  bool ConsumeString(string* text) {
    +    if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
    +      ReportError("Expected string.");
    +      return false;
    +    }
    +
    +    text->clear();
    +    while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
    +      io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
    +
    +      tokenizer_.Next();
    +    }
    +
    +    return true;
    +  }
    +
    +  // Consumes a uint64 and saves its value in the value parameter.
    +  // Returns false if the token is not of type INTEGER.
    +  bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
    +    if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
    +      ReportError("Expected integer.");
    +      return false;
    +    }
    +
    +    if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
    +                                     max_value, value)) {
    +      ReportError("Integer out of range.");
    +      return false;
    +    }
    +
    +    tokenizer_.Next();
    +    return true;
    +  }
    +
    +  // Consumes an int64 and saves its value in the value parameter.
    +  // Note that since the tokenizer does not support negative numbers,
    +  // we actually may consume an additional token (for the minus sign) in this
    +  // method. Returns false if the token is not an integer
    +  // (signed or otherwise).
    +  bool ConsumeSignedInteger(int64* value, uint64 max_value) {
    +    bool negative = false;
    +
    +    if (TryConsume("-")) {
    +      negative = true;
    +      // Two's complement always allows one more negative integer than
    +      // positive.
    +      ++max_value;
    +    }
    +
    +    uint64 unsigned_value;
    +
    +    DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
    +
    +    *value = static_cast(unsigned_value);
    +
    +    if (negative) {
    +      *value = -*value;
    +    }
    +
    +    return true;
    +  }
    +
    +  // Consumes a uint64 and saves its value in the value parameter.
    +  // Accepts decimal numbers only, rejects hex or oct numbers.
    +  bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) {
    +    if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
    +      ReportError("Expected integer.");
    +      return false;
    +    }
    +
    +    const string& text = tokenizer_.current().text;
    +    if (IsHexNumber(text) || IsOctNumber(text)) {
    +      ReportError("Expect a decimal number.");
    +      return false;
    +    }
    +
    +    if (!io::Tokenizer::ParseInteger(text, max_value, value)) {
    +      ReportError("Integer out of range.");
    +      return false;
    +    }
    +
    +    tokenizer_.Next();
    +    return true;
    +  }
    +
    +  // Consumes a double and saves its value in the value parameter.
    +  // Note that since the tokenizer does not support negative numbers,
    +  // we actually may consume an additional token (for the minus sign) in this
    +  // method. Returns false if the token is not a double
    +  // (signed or otherwise).
    +  bool ConsumeDouble(double* value) {
    +    bool negative = false;
    +
    +    if (TryConsume("-")) {
    +      negative = true;
    +    }
    +
    +    // A double can actually be an integer, according to the tokenizer.
    +    // Therefore, we must check both cases here.
    +    if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
    +      // We have found an integer value for the double.
    +      uint64 integer_value;
    +      DO(ConsumeUnsignedDecimalInteger(&integer_value, kuint64max));
    +
    +      *value = static_cast(integer_value);
    +    } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
    +      // We have found a float value for the double.
    +      *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
    +
    +      // Mark the current token as consumed.
    +      tokenizer_.Next();
    +    } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
    +      string text = tokenizer_.current().text;
    +      LowerString(&text);
    +      if (text == "inf" ||
    +          text == "infinity") {
    +        *value = std::numeric_limits::infinity();
    +        tokenizer_.Next();
    +      } else if (text == "nan") {
    +        *value = std::numeric_limits::quiet_NaN();
    +        tokenizer_.Next();
    +      } else {
    +        ReportError("Expected double.");
    +        return false;
    +      }
    +    } else {
    +      ReportError("Expected double.");
    +      return false;
    +    }
    +
    +    if (negative) {
    +      *value = -*value;
    +    }
    +
    +    return true;
    +  }
    +
    +  // Consumes a token and confirms that it matches that specified in the
    +  // value parameter. Returns false if the token found does not match that
    +  // which was specified.
    +  bool Consume(const string& value) {
    +    const string& current_value = tokenizer_.current().text;
    +
    +    if (current_value != value) {
    +      ReportError("Expected \"" + value + "\", found \"" + current_value
    +                  + "\".");
    +      return false;
    +    }
    +
    +    tokenizer_.Next();
    +
    +    return true;
    +  }
    +
    +  // Attempts to consume the supplied value. Returns false if a the
    +  // token found does not match the value specified.
    +  bool TryConsume(const string& value) {
    +    if (tokenizer_.current().text == value) {
    +      tokenizer_.Next();
    +      return true;
    +    } else {
    +      return false;
    +    }
    +  }
    +
    +  // An internal instance of the Tokenizer's error collector, used to
    +  // collect any base-level parse errors and feed them to the ParserImpl.
    +  class ParserErrorCollector : public io::ErrorCollector {
    +   public:
    +    explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
    +        parser_(parser) { }
    +
    +    virtual ~ParserErrorCollector() { }
    +
    +    virtual void AddError(int line, int column, const string& message) {
    +      parser_->ReportError(line, column, message);
    +    }
    +
    +    virtual void AddWarning(int line, int column, const string& message) {
    +      parser_->ReportWarning(line, column, message);
    +    }
    +
    +   private:
    +    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
    +    TextFormat::Parser::ParserImpl* parser_;
    +  };
    +
    +  io::ErrorCollector* error_collector_;
    +  TextFormat::Finder* finder_;
    +  ParseInfoTree* parse_info_tree_;
    +  ParserErrorCollector tokenizer_error_collector_;
    +  io::Tokenizer tokenizer_;
    +  const Descriptor* root_message_type_;
    +  SingularOverwritePolicy singular_overwrite_policy_;
    +  const bool allow_case_insensitive_field_;
    +  const bool allow_unknown_field_;
    +  const bool allow_unknown_enum_;
    +  const bool allow_field_number_;
    +  bool had_errors_;
    +};
    +
    +#undef DO
    +
    +// ===========================================================================
    +// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
    +// from the Printer found in //google/protobuf/io/printer.h
    +class TextFormat::Printer::TextGenerator {
    + public:
    +  explicit TextGenerator(io::ZeroCopyOutputStream* output,
    +                         int initial_indent_level)
    +    : output_(output),
    +      buffer_(NULL),
    +      buffer_size_(0),
    +      at_start_of_line_(true),
    +      failed_(false),
    +      indent_(""),
    +      initial_indent_level_(initial_indent_level) {
    +    indent_.resize(initial_indent_level_ * 2, ' ');
    +  }
    +
    +  ~TextGenerator() {
    +    // Only BackUp() if we're sure we've successfully called Next() at least
    +    // once.
    +    if (!failed_ && buffer_size_ > 0) {
    +      output_->BackUp(buffer_size_);
    +    }
    +  }
    +
    +  // Indent text by two spaces.  After calling Indent(), two spaces will be
    +  // inserted at the beginning of each line of text.  Indent() may be called
    +  // multiple times to produce deeper indents.
    +  void Indent() {
    +    indent_ += "  ";
    +  }
    +
    +  // Reduces the current indent level by two spaces, or crashes if the indent
    +  // level is zero.
    +  void Outdent() {
    +    if (indent_.empty() ||
    +        indent_.size() < initial_indent_level_ * 2) {
    +      GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
    +      return;
    +    }
    +
    +    indent_.resize(indent_.size() - 2);
    +  }
    +
    +  // Print text to the output stream.
    +  void Print(const string& str) {
    +    Print(str.data(), str.size());
    +  }
    +
    +  // Print text to the output stream.
    +  void Print(const char* text) {
    +    Print(text, strlen(text));
    +  }
    +
    +  // Print text to the output stream.
    +  void Print(const char* text, int size) {
    +    int pos = 0;  // The number of bytes we've written so far.
    +
    +    for (int i = 0; i < size; i++) {
    +      if (text[i] == '\n') {
    +        // Saw newline.  If there is more text, we may need to insert an indent
    +        // here.  So, write what we have so far, including the '\n'.
    +        Write(text + pos, i - pos + 1);
    +        pos = i + 1;
    +
    +        // Setting this true will cause the next Write() to insert an indent
    +        // first.
    +        at_start_of_line_ = true;
    +      }
    +    }
    +
    +    // Write the rest.
    +    Write(text + pos, size - pos);
    +  }
    +
    +  // True if any write to the underlying stream failed.  (We don't just
    +  // crash in this case because this is an I/O failure, not a programming
    +  // error.)
    +  bool failed() const { return failed_; }
    +
    + private:
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
    +
    +  void Write(const char* data, int size) {
    +    if (failed_) return;
    +    if (size == 0) return;
    +
    +    if (at_start_of_line_) {
    +      // Insert an indent.
    +      at_start_of_line_ = false;
    +      Write(indent_.data(), indent_.size());
    +      if (failed_) return;
    +    }
    +
    +    while (size > buffer_size_) {
    +      // Data exceeds space in the buffer.  Copy what we can and request a
    +      // new buffer.
    +      memcpy(buffer_, data, buffer_size_);
    +      data += buffer_size_;
    +      size -= buffer_size_;
    +      void* void_buffer;
    +      failed_ = !output_->Next(&void_buffer, &buffer_size_);
    +      if (failed_) return;
    +      buffer_ = reinterpret_cast(void_buffer);
    +    }
    +
    +    // Buffer is big enough to receive the data; copy it.
    +    memcpy(buffer_, data, size);
    +    buffer_ += size;
    +    buffer_size_ -= size;
    +  }
    +
    +  io::ZeroCopyOutputStream* const output_;
    +  char* buffer_;
    +  int buffer_size_;
    +  bool at_start_of_line_;
    +  bool failed_;
    +
    +  string indent_;
    +  int initial_indent_level_;
    +};
    +
    +// ===========================================================================
    +
    +TextFormat::Finder::~Finder() {
    +}
    +
    +TextFormat::Parser::Parser()
    +  : error_collector_(NULL),
    +    finder_(NULL),
    +    parse_info_tree_(NULL),
    +    allow_partial_(false),
    +    allow_case_insensitive_field_(false),
    +    allow_unknown_field_(false),
    +    allow_unknown_enum_(false),
    +    allow_field_number_(false),
    +    allow_relaxed_whitespace_(false),
    +    allow_singular_overwrites_(false) {
    +}
    +
    +TextFormat::Parser::~Parser() {}
    +
    +bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
    +                               Message* output) {
    +  output->Clear();
    +
    +  ParserImpl::SingularOverwritePolicy overwrites_policy =
    +      allow_singular_overwrites_
    +      ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
    +      : ParserImpl::FORBID_SINGULAR_OVERWRITES;
    +
    +  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
    +                    finder_, parse_info_tree_,
    +                    overwrites_policy,
    +                    allow_case_insensitive_field_, allow_unknown_field_,
    +                    allow_unknown_enum_, allow_field_number_,
    +                    allow_relaxed_whitespace_);
    +  return MergeUsingImpl(input, output, &parser);
    +}
    +
    +bool TextFormat::Parser::ParseFromString(const string& input,
    +                                         Message* output) {
    +  io::ArrayInputStream input_stream(input.data(), input.size());
    +  return Parse(&input_stream, output);
    +}
    +
    +bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
    +                               Message* output) {
    +  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
    +                    finder_, parse_info_tree_,
    +                    ParserImpl::ALLOW_SINGULAR_OVERWRITES,
    +                    allow_case_insensitive_field_, allow_unknown_field_,
    +                    allow_unknown_enum_, allow_field_number_,
    +                    allow_relaxed_whitespace_);
    +  return MergeUsingImpl(input, output, &parser);
    +}
    +
    +bool TextFormat::Parser::MergeFromString(const string& input,
    +                                         Message* output) {
    +  io::ArrayInputStream input_stream(input.data(), input.size());
    +  return Merge(&input_stream, output);
    +}
    +
    +bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
    +                                        Message* output,
    +                                        ParserImpl* parser_impl) {
    +  if (!parser_impl->Parse(output)) return false;
    +  if (!allow_partial_ && !output->IsInitialized()) {
    +    vector missing_fields;
    +    output->FindInitializationErrors(&missing_fields);
    +    parser_impl->ReportError(-1, 0, "Message missing required fields: " +
    +                                        Join(missing_fields, ", "));
    +    return false;
    +  }
    +  return true;
    +}
    +
    +bool TextFormat::Parser::ParseFieldValueFromString(
    +    const string& input,
    +    const FieldDescriptor* field,
    +    Message* output) {
    +  io::ArrayInputStream input_stream(input.data(), input.size());
    +  ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
    +                    finder_, parse_info_tree_,
    +                    ParserImpl::ALLOW_SINGULAR_OVERWRITES,
    +                    allow_case_insensitive_field_, allow_unknown_field_,
    +                    allow_unknown_enum_, allow_field_number_,
    +                    allow_relaxed_whitespace_);
    +  return parser.ParseField(field, output);
    +}
    +
    +/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
    +                                    Message* output) {
    +  return Parser().Parse(input, output);
    +}
    +
    +/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
    +                                    Message* output) {
    +  return Parser().Merge(input, output);
    +}
    +
    +/* static */ bool TextFormat::ParseFromString(const string& input,
    +                                              Message* output) {
    +  return Parser().ParseFromString(input, output);
    +}
    +
    +/* static */ bool TextFormat::MergeFromString(const string& input,
    +                                              Message* output) {
    +  return Parser().MergeFromString(input, output);
    +}
    +
    +// ===========================================================================
    +
    +// The default implementation for FieldValuePrinter. The base class just
    +// does simple formatting. That way, deriving classes could decide to fallback
    +// to that behavior.
    +TextFormat::FieldValuePrinter::FieldValuePrinter() {}
    +TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
    +string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
    +  return val ? "true" : "false";
    +}
    +string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const {
    +  return SimpleItoa(val);
    +}
    +string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const {
    +  return SimpleItoa(val);
    +}
    +string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const {
    +  return SimpleItoa(val);
    +}
    +string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const {
    +  return SimpleItoa(val);
    +}
    +string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
    +  return SimpleFtoa(val);
    +}
    +string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
    +  return SimpleDtoa(val);
    +}
    +string TextFormat::FieldValuePrinter::PrintString(const string& val) const {
    +  return StrCat("\"", CEscape(val), "\"");
    +}
    +string TextFormat::FieldValuePrinter::PrintBytes(const string& val) const {
    +  return PrintString(val);
    +}
    +string TextFormat::FieldValuePrinter::PrintEnum(int32 val,
    +                                                const string& name) const {
    +  return name;
    +}
    +string TextFormat::FieldValuePrinter::PrintFieldName(
    +    const Message& message,
    +    const Reflection* reflection,
    +    const FieldDescriptor* field) const {
    +  if (field->is_extension()) {
    +    // We special-case MessageSet elements for compatibility with proto1.
    +    if (field->containing_type()->options().message_set_wire_format()
    +        && field->type() == FieldDescriptor::TYPE_MESSAGE
    +        && field->is_optional()
    +        && field->extension_scope() == field->message_type()) {
    +      return StrCat("[", field->message_type()->full_name(), "]");
    +    } else {
    +      return StrCat("[", field->full_name(), "]");
    +    }
    +  } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
    +    // Groups must be serialized with their original capitalization.
    +    return field->message_type()->name();
    +  } else {
    +    return field->name();
    +  }
    +}
    +string TextFormat::FieldValuePrinter::PrintMessageStart(
    +    const Message& message,
    +    int field_index,
    +    int field_count,
    +    bool single_line_mode) const {
    +  return single_line_mode ? " { " : " {\n";
    +}
    +string TextFormat::FieldValuePrinter::PrintMessageEnd(
    +    const Message& message,
    +    int field_index,
    +    int field_count,
    +    bool single_line_mode) const {
    +  return single_line_mode ? "} " : "}\n";
    +}
    +
    +namespace {
    +// Our own specialization: for UTF8 escaped strings.
    +class FieldValuePrinterUtf8Escaping : public TextFormat::FieldValuePrinter {
    + public:
    +  virtual string PrintString(const string& val) const {
    +    return StrCat("\"", strings::Utf8SafeCEscape(val), "\"");
    +  }
    +  virtual string PrintBytes(const string& val) const {
    +    return TextFormat::FieldValuePrinter::PrintString(val);
    +  }
    +};
    +
    +}  // namespace
    +
    +TextFormat::Printer::Printer()
    +  : initial_indent_level_(0),
    +    single_line_mode_(false),
    +    use_field_number_(false),
    +    use_short_repeated_primitives_(false),
    +    hide_unknown_fields_(false),
    +    print_message_fields_in_index_order_(false) {
    +  SetUseUtf8StringEscaping(false);
    +}
    +
    +TextFormat::Printer::~Printer() {
    +  STLDeleteValues(&custom_printers_);
    +}
    +
    +void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) {
    +  SetDefaultFieldValuePrinter(as_utf8
    +                              ? new FieldValuePrinterUtf8Escaping()
    +                              : new FieldValuePrinter());
    +}
    +
    +void TextFormat::Printer::SetDefaultFieldValuePrinter(
    +    const FieldValuePrinter* printer) {
    +  default_field_value_printer_.reset(printer);
    +}
    +
    +bool TextFormat::Printer::RegisterFieldValuePrinter(
    +    const FieldDescriptor* field,
    +    const FieldValuePrinter* printer) {
    +  return field != NULL
    +      && printer != NULL
    +      && custom_printers_.insert(make_pair(field, printer)).second;
    +}
    +
    +bool TextFormat::Printer::PrintToString(const Message& message,
    +                                        string* output) const {
    +  GOOGLE_DCHECK(output) << "output specified is NULL";
    +
    +  output->clear();
    +  io::StringOutputStream output_stream(output);
    +
    +  return Print(message, &output_stream);
    +}
    +
    +bool TextFormat::Printer::PrintUnknownFieldsToString(
    +    const UnknownFieldSet& unknown_fields,
    +    string* output) const {
    +  GOOGLE_DCHECK(output) << "output specified is NULL";
    +
    +  output->clear();
    +  io::StringOutputStream output_stream(output);
    +  return PrintUnknownFields(unknown_fields, &output_stream);
    +}
    +
    +bool TextFormat::Printer::Print(const Message& message,
    +                                io::ZeroCopyOutputStream* output) const {
    +  TextGenerator generator(output, initial_indent_level_);
    +
    +  Print(message, generator);
    +
    +  // Output false if the generator failed internally.
    +  return !generator.failed();
    +}
    +
    +bool TextFormat::Printer::PrintUnknownFields(
    +    const UnknownFieldSet& unknown_fields,
    +    io::ZeroCopyOutputStream* output) const {
    +  TextGenerator generator(output, initial_indent_level_);
    +
    +  PrintUnknownFields(unknown_fields, generator);
    +
    +  // Output false if the generator failed internally.
    +  return !generator.failed();
    +}
    +
    +namespace {
    +// Comparison functor for sorting FieldDescriptors by field index.
    +struct FieldIndexSorter {
    +  bool operator()(const FieldDescriptor* left,
    +                  const FieldDescriptor* right) const {
    +    return left->index() < right->index();
    +  }
    +};
    +}  // namespace
    +
    +void TextFormat::Printer::Print(const Message& message,
    +                                TextGenerator& generator) const {
    +  const Reflection* reflection = message.GetReflection();
    +  vector fields;
    +  reflection->ListFields(message, &fields);
    +  if (print_message_fields_in_index_order_) {
    +    sort(fields.begin(), fields.end(), FieldIndexSorter());
    +  }
    +  for (int i = 0; i < fields.size(); i++) {
    +    PrintField(message, reflection, fields[i], generator);
    +  }
    +  if (!hide_unknown_fields_) {
    +    PrintUnknownFields(reflection->GetUnknownFields(message), generator);
    +  }
    +}
    +
    +void TextFormat::Printer::PrintFieldValueToString(
    +    const Message& message,
    +    const FieldDescriptor* field,
    +    int index,
    +    string* output) const {
    +
    +  GOOGLE_DCHECK(output) << "output specified is NULL";
    +
    +  output->clear();
    +  io::StringOutputStream output_stream(output);
    +  TextGenerator generator(&output_stream, initial_indent_level_);
    +
    +  PrintFieldValue(message, message.GetReflection(), field, index, generator);
    +}
    +
    +void TextFormat::Printer::PrintField(const Message& message,
    +                                     const Reflection* reflection,
    +                                     const FieldDescriptor* field,
    +                                     TextGenerator& generator) const {
    +  if (use_short_repeated_primitives_ &&
    +      field->is_repeated() &&
    +      field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
    +      field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
    +    PrintShortRepeatedField(message, reflection, field, generator);
    +    return;
    +  }
    +
    +  int count = 0;
    +
    +  if (field->is_repeated()) {
    +    count = reflection->FieldSize(message, field);
    +  } else if (reflection->HasField(message, field)) {
    +    count = 1;
    +  }
    +
    +  for (int j = 0; j < count; ++j) {
    +    const int field_index = field->is_repeated() ? j : -1;
    +
    +    PrintFieldName(message, reflection, field, generator);
    +
    +    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    +      const FieldValuePrinter* printer = FindWithDefault(
    +          custom_printers_, field, default_field_value_printer_.get());
    +      const Message& sub_message =
    +              field->is_repeated()
    +              ? reflection->GetRepeatedMessage(message, field, j)
    +              : reflection->GetMessage(message, field);
    +      generator.Print(
    +          printer->PrintMessageStart(
    +              sub_message, field_index, count, single_line_mode_));
    +      generator.Indent();
    +      Print(sub_message, generator);
    +      generator.Outdent();
    +      generator.Print(
    +          printer->PrintMessageEnd(
    +              sub_message, field_index, count, single_line_mode_));
    +    } else {
    +      generator.Print(": ");
    +      // Write the field value.
    +      PrintFieldValue(message, reflection, field, field_index, generator);
    +      if (single_line_mode_) {
    +        generator.Print(" ");
    +      } else {
    +        generator.Print("\n");
    +      }
    +    }
    +  }
    +}
    +
    +void TextFormat::Printer::PrintShortRepeatedField(
    +    const Message& message,
    +    const Reflection* reflection,
    +    const FieldDescriptor* field,
    +    TextGenerator& generator) const {
    +  // Print primitive repeated field in short form.
    +  PrintFieldName(message, reflection, field, generator);
    +
    +  int size = reflection->FieldSize(message, field);
    +  generator.Print(": [");
    +  for (int i = 0; i < size; i++) {
    +    if (i > 0) generator.Print(", ");
    +    PrintFieldValue(message, reflection, field, i, generator);
    +  }
    +  if (single_line_mode_) {
    +    generator.Print("] ");
    +  } else {
    +    generator.Print("]\n");
    +  }
    +}
    +
    +void TextFormat::Printer::PrintFieldName(const Message& message,
    +                                         const Reflection* reflection,
    +                                         const FieldDescriptor* field,
    +                                         TextGenerator& generator) const {
    +  // if use_field_number_ is true, prints field number instead
    +  // of field name.
    +  if (use_field_number_) {
    +    generator.Print(SimpleItoa(field->number()));
    +    return;
    +  }
    +
    +  const FieldValuePrinter* printer = FindWithDefault(
    +      custom_printers_, field, default_field_value_printer_.get());
    +  generator.Print(printer->PrintFieldName(message, reflection, field));
    +}
    +
    +void TextFormat::Printer::PrintFieldValue(
    +    const Message& message,
    +    const Reflection* reflection,
    +    const FieldDescriptor* field,
    +    int index,
    +    TextGenerator& generator) const {
    +  GOOGLE_DCHECK(field->is_repeated() || (index == -1))
    +      << "Index must be -1 for non-repeated fields";
    +
    +  const FieldValuePrinter* printer
    +      = FindWithDefault(custom_printers_, field,
    +                        default_field_value_printer_.get());
    +
    +  switch (field->cpp_type()) {
    +#define OUTPUT_FIELD(CPPTYPE, METHOD)                                   \
    +    case FieldDescriptor::CPPTYPE_##CPPTYPE:                            \
    +      generator.Print(printer->Print##METHOD(field->is_repeated()       \
    +               ? reflection->GetRepeated##METHOD(message, field, index) \
    +               : reflection->Get##METHOD(message, field)));             \
    +        break
    +
    +    OUTPUT_FIELD( INT32,  Int32);
    +    OUTPUT_FIELD( INT64,  Int64);
    +    OUTPUT_FIELD(UINT32, UInt32);
    +    OUTPUT_FIELD(UINT64, UInt64);
    +    OUTPUT_FIELD( FLOAT,  Float);
    +    OUTPUT_FIELD(DOUBLE, Double);
    +    OUTPUT_FIELD(  BOOL,   Bool);
    +#undef OUTPUT_FIELD
    +
    +    case FieldDescriptor::CPPTYPE_STRING: {
    +      string scratch;
    +      const string& value = field->is_repeated()
    +          ? reflection->GetRepeatedStringReference(
    +              message, field, index, &scratch)
    +          : reflection->GetStringReference(message, field, &scratch);
    +      if (field->type() == FieldDescriptor::TYPE_STRING) {
    +        generator.Print(printer->PrintString(value));
    +      } else {
    +        GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
    +        generator.Print(printer->PrintBytes(value));
    +      }
    +      break;
    +    }
    +
    +    case FieldDescriptor::CPPTYPE_ENUM: {
    +      const EnumValueDescriptor *enum_val = field->is_repeated()
    +          ? reflection->GetRepeatedEnum(message, field, index)
    +          : reflection->GetEnum(message, field);
    +      generator.Print(printer->PrintEnum(enum_val->number(), enum_val->name()));
    +      break;
    +    }
    +
    +    case FieldDescriptor::CPPTYPE_MESSAGE:
    +      Print(field->is_repeated()
    +            ? reflection->GetRepeatedMessage(message, field, index)
    +            : reflection->GetMessage(message, field),
    +            generator);
    +      break;
    +  }
    +}
    +
    +/* static */ bool TextFormat::Print(const Message& message,
    +                                    io::ZeroCopyOutputStream* output) {
    +  return Printer().Print(message, output);
    +}
    +
    +/* static */ bool TextFormat::PrintUnknownFields(
    +    const UnknownFieldSet& unknown_fields,
    +    io::ZeroCopyOutputStream* output) {
    +  return Printer().PrintUnknownFields(unknown_fields, output);
    +}
    +
    +/* static */ bool TextFormat::PrintToString(
    +    const Message& message, string* output) {
    +  return Printer().PrintToString(message, output);
    +}
    +
    +/* static */ bool TextFormat::PrintUnknownFieldsToString(
    +    const UnknownFieldSet& unknown_fields, string* output) {
    +  return Printer().PrintUnknownFieldsToString(unknown_fields, output);
    +}
    +
    +/* static */ void TextFormat::PrintFieldValueToString(
    +    const Message& message,
    +    const FieldDescriptor* field,
    +    int index,
    +    string* output) {
    +  return Printer().PrintFieldValueToString(message, field, index, output);
    +}
    +
    +/* static */ bool TextFormat::ParseFieldValueFromString(
    +    const string& input,
    +    const FieldDescriptor* field,
    +    Message* message) {
    +  return Parser().ParseFieldValueFromString(input, field, message);
    +}
    +
    +// Prints an integer as hex with a fixed number of digits dependent on the
    +// integer type.
    +template
    +static string PaddedHex(IntType value) {
    +  string result;
    +  result.reserve(sizeof(value) * 2);
    +  for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
    +    result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
    +  }
    +  return result;
    +}
    +
    +void TextFormat::Printer::PrintUnknownFields(
    +    const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    const UnknownField& field = unknown_fields.field(i);
    +    string field_number = SimpleItoa(field.number());
    +
    +    switch (field.type()) {
    +      case UnknownField::TYPE_VARINT:
    +        generator.Print(field_number);
    +        generator.Print(": ");
    +        generator.Print(SimpleItoa(field.varint()));
    +        if (single_line_mode_) {
    +          generator.Print(" ");
    +        } else {
    +          generator.Print("\n");
    +        }
    +        break;
    +      case UnknownField::TYPE_FIXED32: {
    +        generator.Print(field_number);
    +        generator.Print(": 0x");
    +        char buffer[kFastToBufferSize];
    +        generator.Print(FastHex32ToBuffer(field.fixed32(), buffer));
    +        if (single_line_mode_) {
    +          generator.Print(" ");
    +        } else {
    +          generator.Print("\n");
    +        }
    +        break;
    +      }
    +      case UnknownField::TYPE_FIXED64: {
    +        generator.Print(field_number);
    +        generator.Print(": 0x");
    +        char buffer[kFastToBufferSize];
    +        generator.Print(FastHex64ToBuffer(field.fixed64(), buffer));
    +        if (single_line_mode_) {
    +          generator.Print(" ");
    +        } else {
    +          generator.Print("\n");
    +        }
    +        break;
    +      }
    +      case UnknownField::TYPE_LENGTH_DELIMITED: {
    +        generator.Print(field_number);
    +        const string& value = field.length_delimited();
    +        UnknownFieldSet embedded_unknown_fields;
    +        if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
    +          // This field is parseable as a Message.
    +          // So it is probably an embedded message.
    +          if (single_line_mode_) {
    +            generator.Print(" { ");
    +          } else {
    +            generator.Print(" {\n");
    +            generator.Indent();
    +          }
    +          PrintUnknownFields(embedded_unknown_fields, generator);
    +          if (single_line_mode_) {
    +            generator.Print("} ");
    +          } else {
    +            generator.Outdent();
    +            generator.Print("}\n");
    +          }
    +        } else {
    +          // This field is not parseable as a Message.
    +          // So it is probably just a plain string.
    +          generator.Print(": \"");
    +          generator.Print(CEscape(value));
    +          generator.Print("\"");
    +          if (single_line_mode_) {
    +            generator.Print(" ");
    +          } else {
    +            generator.Print("\n");
    +          }
    +        }
    +        break;
    +      }
    +      case UnknownField::TYPE_GROUP:
    +        generator.Print(field_number);
    +        if (single_line_mode_) {
    +          generator.Print(" { ");
    +        } else {
    +          generator.Print(" {\n");
    +          generator.Indent();
    +        }
    +        PrintUnknownFields(field.group(), generator);
    +        if (single_line_mode_) {
    +          generator.Print("} ");
    +        } else {
    +          generator.Outdent();
    +          generator.Print("}\n");
    +        }
    +        break;
    +    }
    +  }
    +}
    +
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/text_format.h b/toolkit/components/protobuf/src/google/protobuf/text_format.h
    new file mode 100644
    index 000000000000..2954941082d6
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/text_format.h
    @@ -0,0 +1,473 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: jschorr@google.com (Joseph Schorr)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Utilities for printing and parsing protocol messages in a human-readable,
    +// text-based format.
    +
    +#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
    +#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +namespace io {
    +  class ErrorCollector;      // tokenizer.h
    +}
    +
    +// This class implements protocol buffer text format.  Printing and parsing
    +// protocol messages in text format is useful for debugging and human editing
    +// of messages.
    +//
    +// This class is really a namespace that contains only static methods.
    +class LIBPROTOBUF_EXPORT TextFormat {
    + public:
    +  // Outputs a textual representation of the given message to the given
    +  // output stream.
    +  static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
    +
    +  // Print the fields in an UnknownFieldSet.  They are printed by tag number
    +  // only.  Embedded messages are heuristically identified by attempting to
    +  // parse them.
    +  static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
    +                                 io::ZeroCopyOutputStream* output);
    +
    +  // Like Print(), but outputs directly to a string.
    +  static bool PrintToString(const Message& message, string* output);
    +
    +  // Like PrintUnknownFields(), but outputs directly to a string.
    +  static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
    +                                         string* output);
    +
    +  // Outputs a textual representation of the value of the field supplied on
    +  // the message supplied. For non-repeated fields, an index of -1 must
    +  // be supplied. Note that this method will print the default value for a
    +  // field if it is not set.
    +  static void PrintFieldValueToString(const Message& message,
    +                                      const FieldDescriptor* field,
    +                                      int index,
    +                                      string* output);
    +
    +  // The default printer that converts scalar values from fields into
    +  // their string representation.
    +  // You can derive from this FieldValuePrinter if you want to have
    +  // fields to be printed in a different way and register it at the
    +  // Printer.
    +  class LIBPROTOBUF_EXPORT FieldValuePrinter {
    +   public:
    +    FieldValuePrinter();
    +    virtual ~FieldValuePrinter();
    +    virtual string PrintBool(bool val) const;
    +    virtual string PrintInt32(int32 val) const;
    +    virtual string PrintUInt32(uint32 val) const;
    +    virtual string PrintInt64(int64 val) const;
    +    virtual string PrintUInt64(uint64 val) const;
    +    virtual string PrintFloat(float val) const;
    +    virtual string PrintDouble(double val) const;
    +    virtual string PrintString(const string& val) const;
    +    virtual string PrintBytes(const string& val) const;
    +    virtual string PrintEnum(int32 val, const string& name) const;
    +    virtual string PrintFieldName(const Message& message,
    +                                  const Reflection* reflection,
    +                                  const FieldDescriptor* field) const;
    +    virtual string PrintMessageStart(const Message& message,
    +                                     int field_index,
    +                                     int field_count,
    +                                     bool single_line_mode) const;
    +    virtual string PrintMessageEnd(const Message& message,
    +                                   int field_index,
    +                                   int field_count,
    +                                   bool single_line_mode) const;
    +
    +   private:
    +    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter);
    +  };
    +
    +  // Class for those users which require more fine-grained control over how
    +  // a protobuffer message is printed out.
    +  class LIBPROTOBUF_EXPORT Printer {
    +   public:
    +    Printer();
    +    ~Printer();
    +
    +    // Like TextFormat::Print
    +    bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
    +    // Like TextFormat::PrintUnknownFields
    +    bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
    +                            io::ZeroCopyOutputStream* output) const;
    +    // Like TextFormat::PrintToString
    +    bool PrintToString(const Message& message, string* output) const;
    +    // Like TextFormat::PrintUnknownFieldsToString
    +    bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
    +                                    string* output) const;
    +    // Like TextFormat::PrintFieldValueToString
    +    void PrintFieldValueToString(const Message& message,
    +                                 const FieldDescriptor* field,
    +                                 int index,
    +                                 string* output) const;
    +
    +    // Adjust the initial indent level of all output.  Each indent level is
    +    // equal to two spaces.
    +    void SetInitialIndentLevel(int indent_level) {
    +      initial_indent_level_ = indent_level;
    +    }
    +
    +    // If printing in single line mode, then the entire message will be output
    +    // on a single line with no line breaks.
    +    void SetSingleLineMode(bool single_line_mode) {
    +      single_line_mode_ = single_line_mode;
    +    }
    +
    +    bool IsInSingleLineMode() {
    +      return single_line_mode_;
    +    }
    +
    +    // If use_field_number is true, uses field number instead of field name.
    +    void SetUseFieldNumber(bool use_field_number) {
    +      use_field_number_ = use_field_number;
    +    }
    +
    +    // Set true to print repeated primitives in a format like:
    +    //   field_name: [1, 2, 3, 4]
    +    // instead of printing each value on its own line.  Short format applies
    +    // only to primitive values -- i.e. everything except strings and
    +    // sub-messages/groups.
    +    void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
    +      use_short_repeated_primitives_ = use_short_repeated_primitives;
    +    }
    +
    +    // Set true to output UTF-8 instead of ASCII.  The only difference
    +    // is that bytes >= 0x80 in string fields will not be escaped,
    +    // because they are assumed to be part of UTF-8 multi-byte
    +    // sequences. This will change the default FieldValuePrinter.
    +    void SetUseUtf8StringEscaping(bool as_utf8);
    +
    +    // Set the default FieldValuePrinter that is used for all fields that
    +    // don't have a field-specific printer registered.
    +    // Takes ownership of the printer.
    +    void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
    +
    +    // Sets whether we want to hide unknown fields or not.
    +    // Usually unknown fields are printed in a generic way that includes the
    +    // tag number of the field instead of field name. However, sometimes it
    +    // is useful to be able to print the message without unknown fields (e.g.
    +    // for the python protobuf version to maintain consistency between its pure
    +    // python and c++ implementations).
    +    void SetHideUnknownFields(bool hide) {
    +      hide_unknown_fields_ = hide;
    +    }
    +
    +    // If print_message_fields_in_index_order is true, print fields of a proto
    +    // message using the order defined in source code instead of the field
    +    // number. By default, use the field number order.
    +    void SetPrintMessageFieldsInIndexOrder(
    +        bool print_message_fields_in_index_order) {
    +      print_message_fields_in_index_order_ =
    +          print_message_fields_in_index_order;
    +    }
    +
    +    // Register a custom field-specific FieldValuePrinter for fields
    +    // with a particular FieldDescriptor.
    +    // Returns "true" if the registration succeeded, or "false", if there is
    +    // already a printer for that FieldDescriptor.
    +    // Takes ownership of the printer on successful registration.
    +    bool RegisterFieldValuePrinter(const FieldDescriptor* field,
    +                                   const FieldValuePrinter* printer);
    +
    +   private:
    +    // Forward declaration of an internal class used to print the text
    +    // output to the OutputStream (see text_format.cc for implementation).
    +    class TextGenerator;
    +
    +    // Internal Print method, used for writing to the OutputStream via
    +    // the TextGenerator class.
    +    void Print(const Message& message,
    +               TextGenerator& generator) const;
    +
    +    // Print a single field.
    +    void PrintField(const Message& message,
    +                    const Reflection* reflection,
    +                    const FieldDescriptor* field,
    +                    TextGenerator& generator) const;
    +
    +    // Print a repeated primitive field in short form.
    +    void PrintShortRepeatedField(const Message& message,
    +                                 const Reflection* reflection,
    +                                 const FieldDescriptor* field,
    +                                 TextGenerator& generator) const;
    +
    +    // Print the name of a field -- i.e. everything that comes before the
    +    // ':' for a single name/value pair.
    +    void PrintFieldName(const Message& message,
    +                        const Reflection* reflection,
    +                        const FieldDescriptor* field,
    +                        TextGenerator& generator) const;
    +
    +    // Outputs a textual representation of the value of the field supplied on
    +    // the message supplied or the default value if not set.
    +    void PrintFieldValue(const Message& message,
    +                         const Reflection* reflection,
    +                         const FieldDescriptor* field,
    +                         int index,
    +                         TextGenerator& generator) const;
    +
    +    // Print the fields in an UnknownFieldSet.  They are printed by tag number
    +    // only.  Embedded messages are heuristically identified by attempting to
    +    // parse them.
    +    void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
    +                            TextGenerator& generator) const;
    +
    +    int initial_indent_level_;
    +
    +    bool single_line_mode_;
    +
    +    bool use_field_number_;
    +
    +    bool use_short_repeated_primitives_;
    +
    +    bool hide_unknown_fields_;
    +
    +    bool print_message_fields_in_index_order_;
    +
    +    scoped_ptr default_field_value_printer_;
    +    typedef map CustomPrinterMap;
    +    CustomPrinterMap custom_printers_;
    +  };
    +
    +  // Parses a text-format protocol message from the given input stream to
    +  // the given message object.  This function parses the format written
    +  // by Print().
    +  static bool Parse(io::ZeroCopyInputStream* input, Message* output);
    +  // Like Parse(), but reads directly from a string.
    +  static bool ParseFromString(const string& input, Message* output);
    +
    +  // Like Parse(), but the data is merged into the given message, as if
    +  // using Message::MergeFrom().
    +  static bool Merge(io::ZeroCopyInputStream* input, Message* output);
    +  // Like Merge(), but reads directly from a string.
    +  static bool MergeFromString(const string& input, Message* output);
    +
    +  // Parse the given text as a single field value and store it into the
    +  // given field of the given message. If the field is a repeated field,
    +  // the new value will be added to the end
    +  static bool ParseFieldValueFromString(const string& input,
    +                                        const FieldDescriptor* field,
    +                                        Message* message);
    +
    +  // Interface that TextFormat::Parser can use to find extensions.
    +  // This class may be extended in the future to find more information
    +  // like fields, etc.
    +  class LIBPROTOBUF_EXPORT Finder {
    +   public:
    +    virtual ~Finder();
    +
    +    // Try to find an extension of *message by fully-qualified field
    +    // name.  Returns NULL if no extension is known for this name or number.
    +    virtual const FieldDescriptor* FindExtension(
    +        Message* message,
    +        const string& name) const = 0;
    +  };
    +
    +  // A location in the parsed text.
    +  struct ParseLocation {
    +    int line;
    +    int column;
    +
    +    ParseLocation() : line(-1), column(-1) {}
    +    ParseLocation(int line_param, int column_param)
    +        : line(line_param), column(column_param) {}
    +  };
    +
    +  // Data structure which is populated with the locations of each field
    +  // value parsed from the text.
    +  class LIBPROTOBUF_EXPORT ParseInfoTree {
    +   public:
    +    ParseInfoTree();
    +    ~ParseInfoTree();
    +
    +    // Returns the parse location for index-th value of the field in the parsed
    +    // text. If none exists, returns a location with line = -1. Index should be
    +    // -1 for not-repeated fields.
    +    ParseLocation GetLocation(const FieldDescriptor* field, int index) const;
    +
    +    // Returns the parse info tree for the given field, which must be a message
    +    // type. The nested information tree is owned by the root tree and will be
    +    // deleted when it is deleted.
    +    ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
    +                                    int index) const;
    +
    +   private:
    +    // Allow the text format parser to record information into the tree.
    +    friend class TextFormat;
    +
    +    // Records the starting location of a single value for a field.
    +    void RecordLocation(const FieldDescriptor* field, ParseLocation location);
    +
    +    // Create and records a nested tree for a nested message field.
    +    ParseInfoTree* CreateNested(const FieldDescriptor* field);
    +
    +    // Defines the map from the index-th field descriptor to its parse location.
    +    typedef map > LocationMap;
    +
    +    // Defines the map from the index-th field descriptor to the nested parse
    +    // info tree.
    +    typedef map > NestedMap;
    +
    +    LocationMap locations_;
    +    NestedMap nested_;
    +
    +    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree);
    +  };
    +
    +  // For more control over parsing, use this class.
    +  class LIBPROTOBUF_EXPORT Parser {
    +   public:
    +    Parser();
    +    ~Parser();
    +
    +    // Like TextFormat::Parse().
    +    bool Parse(io::ZeroCopyInputStream* input, Message* output);
    +    // Like TextFormat::ParseFromString().
    +    bool ParseFromString(const string& input, Message* output);
    +    // Like TextFormat::Merge().
    +    bool Merge(io::ZeroCopyInputStream* input, Message* output);
    +    // Like TextFormat::MergeFromString().
    +    bool MergeFromString(const string& input, Message* output);
    +
    +    // Set where to report parse errors.  If NULL (the default), errors will
    +    // be printed to stderr.
    +    void RecordErrorsTo(io::ErrorCollector* error_collector) {
    +      error_collector_ = error_collector;
    +    }
    +
    +    // Set how parser finds extensions.  If NULL (the default), the
    +    // parser will use the standard Reflection object associated with
    +    // the message being parsed.
    +    void SetFinder(Finder* finder) {
    +      finder_ = finder;
    +    }
    +
    +    // Sets where location information about the parse will be written. If NULL
    +    // (the default), then no location will be written.
    +    void WriteLocationsTo(ParseInfoTree* tree) {
    +      parse_info_tree_ = tree;
    +    }
    +
    +    // Normally parsing fails if, after parsing, output->IsInitialized()
    +    // returns false.  Call AllowPartialMessage(true) to skip this check.
    +    void AllowPartialMessage(bool allow) {
    +      allow_partial_ = allow;
    +    }
    +
    +    // Allow field names to be matched case-insensitively.
    +    // This is not advisable if there are fields that only differ in case, or
    +    // if you want to enforce writing in the canonical form.
    +    // This is 'false' by default.
    +    void AllowCaseInsensitiveField(bool allow) {
    +      allow_case_insensitive_field_ = allow;
    +    }
    +
    +    // Like TextFormat::ParseFieldValueFromString
    +    bool ParseFieldValueFromString(const string& input,
    +                                   const FieldDescriptor* field,
    +                                   Message* output);
    +
    +
    +    void AllowFieldNumber(bool allow) {
    +      allow_field_number_ = allow;
    +    }
    +
    +   private:
    +    // Forward declaration of an internal class used to parse text
    +    // representations (see text_format.cc for implementation).
    +    class ParserImpl;
    +
    +    // Like TextFormat::Merge().  The provided implementation is used
    +    // to do the parsing.
    +    bool MergeUsingImpl(io::ZeroCopyInputStream* input,
    +                        Message* output,
    +                        ParserImpl* parser_impl);
    +
    +    io::ErrorCollector* error_collector_;
    +    Finder* finder_;
    +    ParseInfoTree* parse_info_tree_;
    +    bool allow_partial_;
    +    bool allow_case_insensitive_field_;
    +    bool allow_unknown_field_;
    +    bool allow_unknown_enum_;
    +    bool allow_field_number_;
    +    bool allow_relaxed_whitespace_;
    +    bool allow_singular_overwrites_;
    +  };
    +
    +
    + private:
    +  // Hack: ParseInfoTree declares TextFormat as a friend which should extend
    +  // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some
    +  // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide
    +  // helpers for ParserImpl to call methods of ParseInfoTree.
    +  static inline void RecordLocation(ParseInfoTree* info_tree,
    +                                    const FieldDescriptor* field,
    +                                    ParseLocation location);
    +  static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
    +                                            const FieldDescriptor* field);
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
    +};
    +
    +inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
    +                                       const FieldDescriptor* field,
    +                                       ParseLocation location) {
    +  info_tree->RecordLocation(field, location);
    +}
    +
    +
    +inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
    +    ParseInfoTree* info_tree, const FieldDescriptor* field) {
    +  return info_tree->CreateNested(field);
    +}
    +
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc
    new file mode 100644
    index 000000000000..020a323b34d9
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc
    @@ -0,0 +1,265 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +
    +UnknownFieldSet::UnknownFieldSet()
    +    : fields_(NULL) {}
    +
    +UnknownFieldSet::~UnknownFieldSet() {
    +  Clear();
    +  delete fields_;
    +}
    +
    +void UnknownFieldSet::ClearFallback() {
    +  GOOGLE_DCHECK(fields_ != NULL);
    +  for (int i = 0; i < fields_->size(); i++) {
    +    (*fields_)[i].Delete();
    +  }
    +  fields_->clear();
    +}
    +
    +void UnknownFieldSet::ClearAndFreeMemory() {
    +  if (fields_ != NULL) {
    +    Clear();
    +    delete fields_;
    +    fields_ = NULL;
    +  }
    +}
    +
    +void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
    +  for (int i = 0; i < other.field_count(); i++) {
    +    AddField(other.field(i));
    +  }
    +}
    +
    +int UnknownFieldSet::SpaceUsedExcludingSelf() const {
    +  if (fields_ == NULL) return 0;
    +
    +  int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size();
    +  for (int i = 0; i < fields_->size(); i++) {
    +    const UnknownField& field = (*fields_)[i];
    +    switch (field.type()) {
    +      case UnknownField::TYPE_LENGTH_DELIMITED:
    +        total_size += sizeof(*field.length_delimited_.string_value_) +
    +                      internal::StringSpaceUsedExcludingSelf(
    +                          *field.length_delimited_.string_value_);
    +        break;
    +      case UnknownField::TYPE_GROUP:
    +        total_size += field.group_->SpaceUsed();
    +        break;
    +      default:
    +        break;
    +    }
    +  }
    +  return total_size;
    +}
    +
    +int UnknownFieldSet::SpaceUsed() const {
    +  return sizeof(*this) + SpaceUsedExcludingSelf();
    +}
    +
    +void UnknownFieldSet::AddVarint(int number, uint64 value) {
    +  if (fields_ == NULL) fields_ = new vector;
    +  UnknownField field;
    +  field.number_ = number;
    +  field.SetType(UnknownField::TYPE_VARINT);
    +  field.varint_ = value;
    +  fields_->push_back(field);
    +}
    +
    +void UnknownFieldSet::AddFixed32(int number, uint32 value) {
    +  if (fields_ == NULL) fields_ = new vector;
    +  UnknownField field;
    +  field.number_ = number;
    +  field.SetType(UnknownField::TYPE_FIXED32);
    +  field.fixed32_ = value;
    +  fields_->push_back(field);
    +}
    +
    +void UnknownFieldSet::AddFixed64(int number, uint64 value) {
    +  if (fields_ == NULL) fields_ = new vector;
    +  UnknownField field;
    +  field.number_ = number;
    +  field.SetType(UnknownField::TYPE_FIXED64);
    +  field.fixed64_ = value;
    +  fields_->push_back(field);
    +}
    +
    +string* UnknownFieldSet::AddLengthDelimited(int number) {
    +  if (fields_ == NULL) fields_ = new vector;
    +  UnknownField field;
    +  field.number_ = number;
    +  field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
    +  field.length_delimited_.string_value_ = new string;
    +  fields_->push_back(field);
    +  return field.length_delimited_.string_value_;
    +}
    +
    +
    +UnknownFieldSet* UnknownFieldSet::AddGroup(int number) {
    +  if (fields_ == NULL) fields_ = new vector;
    +  UnknownField field;
    +  field.number_ = number;
    +  field.SetType(UnknownField::TYPE_GROUP);
    +  field.group_ = new UnknownFieldSet;
    +  fields_->push_back(field);
    +  return field.group_;
    +}
    +
    +void UnknownFieldSet::AddField(const UnknownField& field) {
    +  if (fields_ == NULL) fields_ = new vector;
    +  fields_->push_back(field);
    +  fields_->back().DeepCopy();
    +}
    +
    +void UnknownFieldSet::DeleteSubrange(int start, int num) {
    +  GOOGLE_DCHECK(fields_ != NULL);
    +  // Delete the specified fields.
    +  for (int i = 0; i < num; ++i) {
    +    (*fields_)[i + start].Delete();
    +  }
    +  // Slide down the remaining fields.
    +  for (int i = start + num; i < fields_->size(); ++i) {
    +    (*fields_)[i - num] = (*fields_)[i];
    +  }
    +  // Pop off the # of deleted fields.
    +  for (int i = 0; i < num; ++i) {
    +    fields_->pop_back();
    +  }
    +}
    +
    +void UnknownFieldSet::DeleteByNumber(int number) {
    +  if (fields_ == NULL) return;
    +  int left = 0;  // The number of fields left after deletion.
    +  for (int i = 0; i < fields_->size(); ++i) {
    +    UnknownField* field = &(*fields_)[i];
    +    if (field->number() == number) {
    +      field->Delete();
    +    } else {
    +      if (i != left) {
    +        (*fields_)[left] = (*fields_)[i];
    +      }
    +      ++left;
    +    }
    +  }
    +  fields_->resize(left);
    +}
    +
    +bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
    +  UnknownFieldSet other;
    +  if (internal::WireFormat::SkipMessage(input, &other) &&
    +      input->ConsumedEntireMessage()) {
    +    MergeFrom(other);
    +    return true;
    +  } else {
    +    return false;
    +  }
    +}
    +
    +bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) {
    +  Clear();
    +  return MergeFromCodedStream(input);
    +}
    +
    +bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
    +  io::CodedInputStream coded_input(input);
    +  return (ParseFromCodedStream(&coded_input) &&
    +          coded_input.ConsumedEntireMessage());
    +}
    +
    +bool UnknownFieldSet::ParseFromArray(const void* data, int size) {
    +  io::ArrayInputStream input(data, size);
    +  return ParseFromZeroCopyStream(&input);
    +}
    +
    +void UnknownField::Delete() {
    +  switch (type()) {
    +    case UnknownField::TYPE_LENGTH_DELIMITED:
    +      delete length_delimited_.string_value_;
    +      break;
    +    case UnknownField::TYPE_GROUP:
    +      delete group_;
    +      break;
    +    default:
    +      break;
    +  }
    +}
    +
    +void UnknownField::DeepCopy() {
    +  switch (type()) {
    +    case UnknownField::TYPE_LENGTH_DELIMITED:
    +      length_delimited_.string_value_ = new string(
    +          *length_delimited_.string_value_);
    +      break;
    +    case UnknownField::TYPE_GROUP: {
    +      UnknownFieldSet* group = new UnknownFieldSet;
    +      group->MergeFrom(*group_);
    +      group_ = group;
    +      break;
    +    }
    +    default:
    +      break;
    +  }
    +}
    +
    +
    +void UnknownField::SerializeLengthDelimitedNoTag(
    +    io::CodedOutputStream* output) const {
    +  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
    +  const string& data = *length_delimited_.string_value_;
    +  output->WriteVarint32(data.size());
    +  output->WriteRawMaybeAliased(data.data(), data.size());
    +}
    +
    +uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
    +  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
    +  const string& data = *length_delimited_.string_value_;
    +  target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
    +  target = io::CodedOutputStream::WriteStringToArray(data, target);
    +  return target;
    +}
    +
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h
    new file mode 100644
    index 000000000000..ba202eb6863c
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h
    @@ -0,0 +1,318 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// Contains classes used to keep track of unrecognized fields seen while
    +// parsing a protocol message.
    +
    +#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
    +#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +namespace google {
    +namespace protobuf {
    +  namespace io {
    +    class CodedInputStream;         // coded_stream.h
    +    class CodedOutputStream;        // coded_stream.h
    +    class ZeroCopyInputStream;      // zero_copy_stream.h
    +  }
    +  namespace internal {
    +    class WireFormat;               // wire_format.h
    +    class MessageSetFieldSkipperUsingCord;
    +                                    // extension_set_heavy.cc
    +  }
    +
    +class Message;                      // message.h
    +class UnknownField;                 // below
    +
    +// An UnknownFieldSet contains fields that were encountered while parsing a
    +// message but were not defined by its type.  Keeping track of these can be
    +// useful, especially in that they may be written if the message is serialized
    +// again without being cleared in between.  This means that software which
    +// simply receives messages and forwards them to other servers does not need
    +// to be updated every time a new field is added to the message definition.
    +//
    +// To get the UnknownFieldSet attached to any message, call
    +// Reflection::GetUnknownFields().
    +//
    +// This class is necessarily tied to the protocol buffer wire format, unlike
    +// the Reflection interface which is independent of any serialization scheme.
    +class LIBPROTOBUF_EXPORT UnknownFieldSet {
    + public:
    +  UnknownFieldSet();
    +  ~UnknownFieldSet();
    +
    +  // Remove all fields.
    +  inline void Clear();
    +
    +  // Remove all fields and deallocate internal data objects
    +  void ClearAndFreeMemory();
    +
    +  // Is this set empty?
    +  inline bool empty() const;
    +
    +  // Merge the contents of some other UnknownFieldSet with this one.
    +  void MergeFrom(const UnknownFieldSet& other);
    +
    +  // Swaps the contents of some other UnknownFieldSet with this one.
    +  inline void Swap(UnknownFieldSet* x);
    +
    +  // Computes (an estimate of) the total number of bytes currently used for
    +  // storing the unknown fields in memory. Does NOT include
    +  // sizeof(*this) in the calculation.
    +  int SpaceUsedExcludingSelf() const;
    +
    +  // Version of SpaceUsed() including sizeof(*this).
    +  int SpaceUsed() const;
    +
    +  // Returns the number of fields present in the UnknownFieldSet.
    +  inline int field_count() const;
    +  // Get a field in the set, where 0 <= index < field_count().  The fields
    +  // appear in the order in which they were added.
    +  inline const UnknownField& field(int index) const;
    +  // Get a mutable pointer to a field in the set, where
    +  // 0 <= index < field_count().  The fields appear in the order in which
    +  // they were added.
    +  inline UnknownField* mutable_field(int index);
    +
    +  // Adding fields ---------------------------------------------------
    +
    +  void AddVarint(int number, uint64 value);
    +  void AddFixed32(int number, uint32 value);
    +  void AddFixed64(int number, uint64 value);
    +  void AddLengthDelimited(int number, const string& value);
    +  string* AddLengthDelimited(int number);
    +  UnknownFieldSet* AddGroup(int number);
    +
    +  // Adds an unknown field from another set.
    +  void AddField(const UnknownField& field);
    +
    +  // Delete fields with indices in the range [start .. start+num-1].
    +  // Caution: implementation moves all fields with indices [start+num .. ].
    +  void DeleteSubrange(int start, int num);
    +
    +  // Delete all fields with a specific field number. The order of left fields
    +  // is preserved.
    +  // Caution: implementation moves all fields after the first deleted field.
    +  void DeleteByNumber(int number);
    +
    +  // Parsing helpers -------------------------------------------------
    +  // These work exactly like the similarly-named methods of Message.
    +
    +  bool MergeFromCodedStream(io::CodedInputStream* input);
    +  bool ParseFromCodedStream(io::CodedInputStream* input);
    +  bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
    +  bool ParseFromArray(const void* data, int size);
    +  inline bool ParseFromString(const string& data) {
    +    return ParseFromArray(data.data(), static_cast(data.size()));
    +  }
    +
    + private:
    +
    +  void ClearFallback();
    +
    +  vector* fields_;
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
    +};
    +
    +// Represents one field in an UnknownFieldSet.
    +class LIBPROTOBUF_EXPORT UnknownField {
    + public:
    +  enum Type {
    +    TYPE_VARINT,
    +    TYPE_FIXED32,
    +    TYPE_FIXED64,
    +    TYPE_LENGTH_DELIMITED,
    +    TYPE_GROUP
    +  };
    +
    +  // The field's tag number, as seen on the wire.
    +  inline int number() const;
    +
    +  // The field type.
    +  inline Type type() const;
    +
    +  // Accessors -------------------------------------------------------
    +  // Each method works only for UnknownFields of the corresponding type.
    +
    +  inline uint64 varint() const;
    +  inline uint32 fixed32() const;
    +  inline uint64 fixed64() const;
    +  inline const string& length_delimited() const;
    +  inline const UnknownFieldSet& group() const;
    +
    +  inline void set_varint(uint64 value);
    +  inline void set_fixed32(uint32 value);
    +  inline void set_fixed64(uint64 value);
    +  inline void set_length_delimited(const string& value);
    +  inline string* mutable_length_delimited();
    +  inline UnknownFieldSet* mutable_group();
    +
    +  // Serialization API.
    +  // These methods can take advantage of the underlying implementation and may
    +  // archieve a better performance than using getters to retrieve the data and
    +  // do the serialization yourself.
    +  void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const;
    +  uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const;
    +
    +  inline int GetLengthDelimitedSize() const;
    +
    + private:
    +  friend class UnknownFieldSet;
    +
    +  // If this UnknownField contains a pointer, delete it.
    +  void Delete();
    +
    +  // Make a deep copy of any pointers in this UnknownField.
    +  void DeepCopy();
    +
    +  // Set the wire type of this UnknownField. Should only be used when this
    +  // UnknownField is being created.
    +  inline void SetType(Type type);
    +
    +  uint32 number_;
    +  uint32 type_;
    +  union {
    +    uint64 varint_;
    +    uint32 fixed32_;
    +    uint64 fixed64_;
    +    mutable union {
    +      string* string_value_;
    +    } length_delimited_;
    +    UnknownFieldSet* group_;
    +  };
    +};
    +
    +// ===================================================================
    +// inline implementations
    +
    +inline void UnknownFieldSet::Clear() {
    +  if (fields_ != NULL) {
    +    ClearFallback();
    +  }
    +}
    +
    +inline bool UnknownFieldSet::empty() const {
    +  return fields_ == NULL || fields_->empty();
    +}
    +
    +inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
    +  std::swap(fields_, x->fields_);
    +}
    +
    +inline int UnknownFieldSet::field_count() const {
    +  return (fields_ == NULL) ? 0 : static_cast(fields_->size());
    +}
    +inline const UnknownField& UnknownFieldSet::field(int index) const {
    +  return (*fields_)[index];
    +}
    +inline UnknownField* UnknownFieldSet::mutable_field(int index) {
    +  return &(*fields_)[index];
    +}
    +
    +inline void UnknownFieldSet::AddLengthDelimited(
    +    int number, const string& value) {
    +  AddLengthDelimited(number)->assign(value);
    +}
    +
    +
    +inline int UnknownField::number() const { return number_; }
    +inline UnknownField::Type UnknownField::type() const {
    +  return static_cast(type_);
    +}
    +
    +inline uint64 UnknownField::varint() const {
    +  assert(type() == TYPE_VARINT);
    +  return varint_;
    +}
    +inline uint32 UnknownField::fixed32() const {
    +  assert(type() == TYPE_FIXED32);
    +  return fixed32_;
    +}
    +inline uint64 UnknownField::fixed64() const {
    +  assert(type() == TYPE_FIXED64);
    +  return fixed64_;
    +}
    +inline const string& UnknownField::length_delimited() const {
    +  assert(type() == TYPE_LENGTH_DELIMITED);
    +  return *length_delimited_.string_value_;
    +}
    +inline const UnknownFieldSet& UnknownField::group() const {
    +  assert(type() == TYPE_GROUP);
    +  return *group_;
    +}
    +
    +inline void UnknownField::set_varint(uint64 value) {
    +  assert(type() == TYPE_VARINT);
    +  varint_ = value;
    +}
    +inline void UnknownField::set_fixed32(uint32 value) {
    +  assert(type() == TYPE_FIXED32);
    +  fixed32_ = value;
    +}
    +inline void UnknownField::set_fixed64(uint64 value) {
    +  assert(type() == TYPE_FIXED64);
    +  fixed64_ = value;
    +}
    +inline void UnknownField::set_length_delimited(const string& value) {
    +  assert(type() == TYPE_LENGTH_DELIMITED);
    +  length_delimited_.string_value_->assign(value);
    +}
    +inline string* UnknownField::mutable_length_delimited() {
    +  assert(type() == TYPE_LENGTH_DELIMITED);
    +  return length_delimited_.string_value_;
    +}
    +inline UnknownFieldSet* UnknownField::mutable_group() {
    +  assert(type() == TYPE_GROUP);
    +  return group_;
    +}
    +
    +inline int UnknownField::GetLengthDelimitedSize() const {
    +  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
    +  return static_cast(length_delimited_.string_value_->size());
    +}
    +
    +inline void UnknownField::SetType(Type type) {
    +  type_ = type;
    +}
    +
    +
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
    diff --git a/toolkit/components/protobuf/src/google/protobuf/wire_format.cc b/toolkit/components/protobuf/src/google/protobuf/wire_format.cc
    new file mode 100644
    index 000000000000..fc6210c2846f
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/wire_format.cc
    @@ -0,0 +1,1106 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +
    +
    +namespace google {
    +namespace protobuf {
    +namespace internal {
    +
    +namespace {
    +
    +// This function turns out to be convenient when using some macros later.
    +inline int GetEnumNumber(const EnumValueDescriptor* descriptor) {
    +  return descriptor->number();
    +}
    +
    +}  // anonymous namespace
    +
    +// ===================================================================
    +
    +bool UnknownFieldSetFieldSkipper::SkipField(
    +    io::CodedInputStream* input, uint32 tag) {
    +  return WireFormat::SkipField(input, tag, unknown_fields_);
    +}
    +
    +bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) {
    +  return WireFormat::SkipMessage(input, unknown_fields_);
    +}
    +
    +void UnknownFieldSetFieldSkipper::SkipUnknownEnum(
    +    int field_number, int value) {
    +  unknown_fields_->AddVarint(field_number, value);
    +}
    +
    +bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag,
    +                           UnknownFieldSet* unknown_fields) {
    +  int number = WireFormatLite::GetTagFieldNumber(tag);
    +
    +  switch (WireFormatLite::GetTagWireType(tag)) {
    +    case WireFormatLite::WIRETYPE_VARINT: {
    +      uint64 value;
    +      if (!input->ReadVarint64(&value)) return false;
    +      if (unknown_fields != NULL) unknown_fields->AddVarint(number, value);
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_FIXED64: {
    +      uint64 value;
    +      if (!input->ReadLittleEndian64(&value)) return false;
    +      if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value);
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
    +      uint32 length;
    +      if (!input->ReadVarint32(&length)) return false;
    +      if (unknown_fields == NULL) {
    +        if (!input->Skip(length)) return false;
    +      } else {
    +        if (!input->ReadString(unknown_fields->AddLengthDelimited(number),
    +                               length)) {
    +          return false;
    +        }
    +      }
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_START_GROUP: {
    +      if (!input->IncrementRecursionDepth()) return false;
    +      if (!SkipMessage(input, (unknown_fields == NULL) ?
    +                              NULL : unknown_fields->AddGroup(number))) {
    +        return false;
    +      }
    +      input->DecrementRecursionDepth();
    +      // Check that the ending tag matched the starting tag.
    +      if (!input->LastTagWas(WireFormatLite::MakeTag(
    +          WireFormatLite::GetTagFieldNumber(tag),
    +          WireFormatLite::WIRETYPE_END_GROUP))) {
    +        return false;
    +      }
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_END_GROUP: {
    +      return false;
    +    }
    +    case WireFormatLite::WIRETYPE_FIXED32: {
    +      uint32 value;
    +      if (!input->ReadLittleEndian32(&value)) return false;
    +      if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value);
    +      return true;
    +    }
    +    default: {
    +      return false;
    +    }
    +  }
    +}
    +
    +bool WireFormat::SkipMessage(io::CodedInputStream* input,
    +                             UnknownFieldSet* unknown_fields) {
    +  while(true) {
    +    uint32 tag = input->ReadTag();
    +    if (tag == 0) {
    +      // End of input.  This is a valid place to end, so return true.
    +      return true;
    +    }
    +
    +    WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
    +
    +    if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
    +      // Must be the end of the message.
    +      return true;
    +    }
    +
    +    if (!SkipField(input, tag, unknown_fields)) return false;
    +  }
    +}
    +
    +void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
    +                                        io::CodedOutputStream* output) {
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    const UnknownField& field = unknown_fields.field(i);
    +    switch (field.type()) {
    +      case UnknownField::TYPE_VARINT:
    +        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_VARINT));
    +        output->WriteVarint64(field.varint());
    +        break;
    +      case UnknownField::TYPE_FIXED32:
    +        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_FIXED32));
    +        output->WriteLittleEndian32(field.fixed32());
    +        break;
    +      case UnknownField::TYPE_FIXED64:
    +        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_FIXED64));
    +        output->WriteLittleEndian64(field.fixed64());
    +        break;
    +      case UnknownField::TYPE_LENGTH_DELIMITED:
    +        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
    +        output->WriteVarint32(field.length_delimited().size());
    +        output->WriteRawMaybeAliased(field.length_delimited().data(),
    +                                     field.length_delimited().size());
    +        break;
    +      case UnknownField::TYPE_GROUP:
    +        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_START_GROUP));
    +        SerializeUnknownFields(field.group(), output);
    +        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_END_GROUP));
    +        break;
    +    }
    +  }
    +}
    +
    +uint8* WireFormat::SerializeUnknownFieldsToArray(
    +    const UnknownFieldSet& unknown_fields,
    +    uint8* target) {
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    const UnknownField& field = unknown_fields.field(i);
    +
    +    switch (field.type()) {
    +      case UnknownField::TYPE_VARINT:
    +        target = WireFormatLite::WriteInt64ToArray(
    +            field.number(), field.varint(), target);
    +        break;
    +      case UnknownField::TYPE_FIXED32:
    +        target = WireFormatLite::WriteFixed32ToArray(
    +            field.number(), field.fixed32(), target);
    +        break;
    +      case UnknownField::TYPE_FIXED64:
    +        target = WireFormatLite::WriteFixed64ToArray(
    +            field.number(), field.fixed64(), target);
    +        break;
    +      case UnknownField::TYPE_LENGTH_DELIMITED:
    +        target = WireFormatLite::WriteBytesToArray(
    +            field.number(), field.length_delimited(), target);
    +        break;
    +      case UnknownField::TYPE_GROUP:
    +        target = WireFormatLite::WriteTagToArray(
    +            field.number(), WireFormatLite::WIRETYPE_START_GROUP, target);
    +        target = SerializeUnknownFieldsToArray(field.group(), target);
    +        target = WireFormatLite::WriteTagToArray(
    +            field.number(), WireFormatLite::WIRETYPE_END_GROUP, target);
    +        break;
    +    }
    +  }
    +  return target;
    +}
    +
    +void WireFormat::SerializeUnknownMessageSetItems(
    +    const UnknownFieldSet& unknown_fields,
    +    io::CodedOutputStream* output) {
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    const UnknownField& field = unknown_fields.field(i);
    +    // The only unknown fields that are allowed to exist in a MessageSet are
    +    // messages, which are length-delimited.
    +    if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
    +      // Start group.
    +      output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
    +
    +      // Write type ID.
    +      output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
    +      output->WriteVarint32(field.number());
    +
    +      // Write message.
    +      output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
    +      field.SerializeLengthDelimitedNoTag(output);
    +
    +      // End group.
    +      output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
    +    }
    +  }
    +}
    +
    +uint8* WireFormat::SerializeUnknownMessageSetItemsToArray(
    +    const UnknownFieldSet& unknown_fields,
    +    uint8* target) {
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    const UnknownField& field = unknown_fields.field(i);
    +
    +    // The only unknown fields that are allowed to exist in a MessageSet are
    +    // messages, which are length-delimited.
    +    if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
    +      // Start group.
    +      target = io::CodedOutputStream::WriteTagToArray(
    +          WireFormatLite::kMessageSetItemStartTag, target);
    +
    +      // Write type ID.
    +      target = io::CodedOutputStream::WriteTagToArray(
    +          WireFormatLite::kMessageSetTypeIdTag, target);
    +      target = io::CodedOutputStream::WriteVarint32ToArray(
    +          field.number(), target);
    +
    +      // Write message.
    +      target = io::CodedOutputStream::WriteTagToArray(
    +          WireFormatLite::kMessageSetMessageTag, target);
    +      target = field.SerializeLengthDelimitedNoTagToArray(target);
    +
    +      // End group.
    +      target = io::CodedOutputStream::WriteTagToArray(
    +          WireFormatLite::kMessageSetItemEndTag, target);
    +    }
    +  }
    +
    +  return target;
    +}
    +
    +int WireFormat::ComputeUnknownFieldsSize(
    +    const UnknownFieldSet& unknown_fields) {
    +  int size = 0;
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    const UnknownField& field = unknown_fields.field(i);
    +
    +    switch (field.type()) {
    +      case UnknownField::TYPE_VARINT:
    +        size += io::CodedOutputStream::VarintSize32(
    +            WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_VARINT));
    +        size += io::CodedOutputStream::VarintSize64(field.varint());
    +        break;
    +      case UnknownField::TYPE_FIXED32:
    +        size += io::CodedOutputStream::VarintSize32(
    +            WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_FIXED32));
    +        size += sizeof(int32);
    +        break;
    +      case UnknownField::TYPE_FIXED64:
    +        size += io::CodedOutputStream::VarintSize32(
    +            WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_FIXED64));
    +        size += sizeof(int64);
    +        break;
    +      case UnknownField::TYPE_LENGTH_DELIMITED:
    +        size += io::CodedOutputStream::VarintSize32(
    +            WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
    +        size += io::CodedOutputStream::VarintSize32(
    +            field.length_delimited().size());
    +        size += field.length_delimited().size();
    +        break;
    +      case UnknownField::TYPE_GROUP:
    +        size += io::CodedOutputStream::VarintSize32(
    +            WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_START_GROUP));
    +        size += ComputeUnknownFieldsSize(field.group());
    +        size += io::CodedOutputStream::VarintSize32(
    +            WireFormatLite::MakeTag(field.number(),
    +            WireFormatLite::WIRETYPE_END_GROUP));
    +        break;
    +    }
    +  }
    +
    +  return size;
    +}
    +
    +int WireFormat::ComputeUnknownMessageSetItemsSize(
    +    const UnknownFieldSet& unknown_fields) {
    +  int size = 0;
    +  for (int i = 0; i < unknown_fields.field_count(); i++) {
    +    const UnknownField& field = unknown_fields.field(i);
    +
    +    // The only unknown fields that are allowed to exist in a MessageSet are
    +    // messages, which are length-delimited.
    +    if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
    +      size += WireFormatLite::kMessageSetItemTagsSize;
    +      size += io::CodedOutputStream::VarintSize32(field.number());
    +
    +      int field_size = field.GetLengthDelimitedSize();
    +      size += io::CodedOutputStream::VarintSize32(field_size);
    +      size += field_size;
    +    }
    +  }
    +
    +  return size;
    +}
    +
    +// ===================================================================
    +
    +bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
    +                                      Message* message) {
    +  const Descriptor* descriptor = message->GetDescriptor();
    +  const Reflection* message_reflection = message->GetReflection();
    +
    +  while(true) {
    +    uint32 tag = input->ReadTag();
    +    if (tag == 0) {
    +      // End of input.  This is a valid place to end, so return true.
    +      return true;
    +    }
    +
    +    if (WireFormatLite::GetTagWireType(tag) ==
    +        WireFormatLite::WIRETYPE_END_GROUP) {
    +      // Must be the end of the message.
    +      return true;
    +    }
    +
    +    const FieldDescriptor* field = NULL;
    +
    +    if (descriptor != NULL) {
    +      int field_number = WireFormatLite::GetTagFieldNumber(tag);
    +      field = descriptor->FindFieldByNumber(field_number);
    +
    +      // If that failed, check if the field is an extension.
    +      if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
    +        if (input->GetExtensionPool() == NULL) {
    +          field = message_reflection->FindKnownExtensionByNumber(field_number);
    +        } else {
    +          field = input->GetExtensionPool()
    +                       ->FindExtensionByNumber(descriptor, field_number);
    +        }
    +      }
    +
    +      // If that failed, but we're a MessageSet, and this is the tag for a
    +      // MessageSet item, then parse that.
    +      if (field == NULL &&
    +          descriptor->options().message_set_wire_format() &&
    +          tag == WireFormatLite::kMessageSetItemStartTag) {
    +        if (!ParseAndMergeMessageSetItem(input, message)) {
    +          return false;
    +        }
    +        continue;  // Skip ParseAndMergeField(); already taken care of.
    +      }
    +    }
    +
    +    if (!ParseAndMergeField(tag, field, message, input)) {
    +      return false;
    +    }
    +  }
    +}
    +
    +bool WireFormat::SkipMessageSetField(io::CodedInputStream* input,
    +                                     uint32 field_number,
    +                                     UnknownFieldSet* unknown_fields) {
    +  uint32 length;
    +  if (!input->ReadVarint32(&length)) return false;
    +  return input->ReadString(
    +      unknown_fields->AddLengthDelimited(field_number), length);
    +}
    +
    +bool WireFormat::ParseAndMergeMessageSetField(uint32 field_number,
    +                                              const FieldDescriptor* field,
    +                                              Message* message,
    +                                              io::CodedInputStream* input) {
    +  const Reflection* message_reflection = message->GetReflection();
    +  if (field == NULL) {
    +    // We store unknown MessageSet extensions as groups.
    +    return SkipMessageSetField(
    +        input, field_number, message_reflection->MutableUnknownFields(message));
    +  } else if (field->is_repeated() ||
    +             field->type() != FieldDescriptor::TYPE_MESSAGE) {
    +    // This shouldn't happen as we only allow optional message extensions to
    +    // MessageSet.
    +    GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages.";
    +    return false;
    +  } else {
    +    Message* sub_message = message_reflection->MutableMessage(
    +        message, field, input->GetExtensionFactory());
    +    return WireFormatLite::ReadMessage(input, sub_message);
    +  }
    +}
    +
    +bool WireFormat::ParseAndMergeField(
    +    uint32 tag,
    +    const FieldDescriptor* field,        // May be NULL for unknown
    +    Message* message,
    +    io::CodedInputStream* input) {
    +  const Reflection* message_reflection = message->GetReflection();
    +
    +  enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
    +
    +  if (field == NULL) {
    +    value_format = UNKNOWN;
    +  } else if (WireFormatLite::GetTagWireType(tag) ==
    +             WireTypeForFieldType(field->type())) {
    +    value_format = NORMAL_FORMAT;
    +  } else if (field->is_packable() &&
    +             WireFormatLite::GetTagWireType(tag) ==
    +             WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
    +    value_format = PACKED_FORMAT;
    +  } else {
    +    // We don't recognize this field. Either the field number is unknown
    +    // or the wire type doesn't match. Put it in our unknown field set.
    +    value_format = UNKNOWN;
    +  }
    +
    +  if (value_format == UNKNOWN) {
    +    return SkipField(input, tag,
    +                     message_reflection->MutableUnknownFields(message));
    +  } else if (value_format == PACKED_FORMAT) {
    +    uint32 length;
    +    if (!input->ReadVarint32(&length)) return false;
    +    io::CodedInputStream::Limit limit = input->PushLimit(length);
    +
    +    switch (field->type()) {
    +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                      \
    +      case FieldDescriptor::TYPE_##TYPE: {                                     \
    +        while (input->BytesUntilLimit() > 0) {                                 \
    +          CPPTYPE value;                                                       \
    +          if (!WireFormatLite::ReadPrimitive<                                  \
    +                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))          \
    +            return false;                                                      \
    +          message_reflection->Add##CPPTYPE_METHOD(message, field, value);      \
    +        }                                                                      \
    +        break;                                                                 \
    +      }
    +
    +      HANDLE_PACKED_TYPE( INT32,  int32,  Int32)
    +      HANDLE_PACKED_TYPE( INT64,  int64,  Int64)
    +      HANDLE_PACKED_TYPE(SINT32,  int32,  Int32)
    +      HANDLE_PACKED_TYPE(SINT64,  int64,  Int64)
    +      HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
    +      HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
    +
    +      HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32)
    +      HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64)
    +      HANDLE_PACKED_TYPE(SFIXED32,  int32,  Int32)
    +      HANDLE_PACKED_TYPE(SFIXED64,  int64,  Int64)
    +
    +      HANDLE_PACKED_TYPE(FLOAT , float , Float )
    +      HANDLE_PACKED_TYPE(DOUBLE, double, Double)
    +
    +      HANDLE_PACKED_TYPE(BOOL, bool, Bool)
    +#undef HANDLE_PACKED_TYPE
    +
    +      case FieldDescriptor::TYPE_ENUM: {
    +        while (input->BytesUntilLimit() > 0) {
    +          int value;
    +          if (!WireFormatLite::ReadPrimitive(
    +                  input, &value)) return false;
    +          const EnumValueDescriptor* enum_value =
    +              field->enum_type()->FindValueByNumber(value);
    +          if (enum_value != NULL) {
    +            message_reflection->AddEnum(message, field, enum_value);
    +          }
    +        }
    +
    +        break;
    +      }
    +
    +      case FieldDescriptor::TYPE_STRING:
    +      case FieldDescriptor::TYPE_GROUP:
    +      case FieldDescriptor::TYPE_MESSAGE:
    +      case FieldDescriptor::TYPE_BYTES:
    +        // Can't have packed fields of these types: these should be caught by
    +        // the protocol compiler.
    +        return false;
    +        break;
    +    }
    +
    +    input->PopLimit(limit);
    +  } else {
    +    // Non-packed value (value_format == NORMAL_FORMAT)
    +    switch (field->type()) {
    +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                            \
    +      case FieldDescriptor::TYPE_##TYPE: {                                    \
    +        CPPTYPE value;                                                        \
    +        if (!WireFormatLite::ReadPrimitive<                                   \
    +                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))         \
    +          return false;                                                       \
    +        if (field->is_repeated()) {                                           \
    +          message_reflection->Add##CPPTYPE_METHOD(message, field, value);     \
    +        } else {                                                              \
    +          message_reflection->Set##CPPTYPE_METHOD(message, field, value);     \
    +        }                                                                     \
    +        break;                                                                \
    +      }
    +
    +      HANDLE_TYPE( INT32,  int32,  Int32)
    +      HANDLE_TYPE( INT64,  int64,  Int64)
    +      HANDLE_TYPE(SINT32,  int32,  Int32)
    +      HANDLE_TYPE(SINT64,  int64,  Int64)
    +      HANDLE_TYPE(UINT32, uint32, UInt32)
    +      HANDLE_TYPE(UINT64, uint64, UInt64)
    +
    +      HANDLE_TYPE( FIXED32, uint32, UInt32)
    +      HANDLE_TYPE( FIXED64, uint64, UInt64)
    +      HANDLE_TYPE(SFIXED32,  int32,  Int32)
    +      HANDLE_TYPE(SFIXED64,  int64,  Int64)
    +
    +      HANDLE_TYPE(FLOAT , float , Float )
    +      HANDLE_TYPE(DOUBLE, double, Double)
    +
    +      HANDLE_TYPE(BOOL, bool, Bool)
    +#undef HANDLE_TYPE
    +
    +      case FieldDescriptor::TYPE_ENUM: {
    +        int value;
    +        if (!WireFormatLite::ReadPrimitive(
    +                input, &value)) return false;
    +        const EnumValueDescriptor* enum_value =
    +          field->enum_type()->FindValueByNumber(value);
    +        if (enum_value != NULL) {
    +          if (field->is_repeated()) {
    +            message_reflection->AddEnum(message, field, enum_value);
    +          } else {
    +            message_reflection->SetEnum(message, field, enum_value);
    +          }
    +        } else {
    +          // The enum value is not one of the known values.  Add it to the
    +          // UnknownFieldSet.
    +          int64 sign_extended_value = static_cast(value);
    +          message_reflection->MutableUnknownFields(message)
    +                            ->AddVarint(WireFormatLite::GetTagFieldNumber(tag),
    +                                        sign_extended_value);
    +        }
    +        break;
    +      }
    +
    +      // Handle strings separately so that we can optimize the ctype=CORD case.
    +      case FieldDescriptor::TYPE_STRING: {
    +        string value;
    +        if (!WireFormatLite::ReadString(input, &value)) return false;
    +        VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
    +                                   field->name().c_str());
    +        if (field->is_repeated()) {
    +          message_reflection->AddString(message, field, value);
    +        } else {
    +          message_reflection->SetString(message, field, value);
    +        }
    +        break;
    +      }
    +
    +      case FieldDescriptor::TYPE_BYTES: {
    +        string value;
    +        if (!WireFormatLite::ReadBytes(input, &value)) return false;
    +        if (field->is_repeated()) {
    +          message_reflection->AddString(message, field, value);
    +        } else {
    +          message_reflection->SetString(message, field, value);
    +        }
    +        break;
    +      }
    +
    +      case FieldDescriptor::TYPE_GROUP: {
    +        Message* sub_message;
    +        if (field->is_repeated()) {
    +          sub_message = message_reflection->AddMessage(
    +              message, field, input->GetExtensionFactory());
    +        } else {
    +          sub_message = message_reflection->MutableMessage(
    +              message, field, input->GetExtensionFactory());
    +        }
    +
    +        if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
    +                                       input, sub_message))
    +          return false;
    +        break;
    +      }
    +
    +      case FieldDescriptor::TYPE_MESSAGE: {
    +        Message* sub_message;
    +        if (field->is_repeated()) {
    +          sub_message = message_reflection->AddMessage(
    +              message, field, input->GetExtensionFactory());
    +        } else {
    +          sub_message = message_reflection->MutableMessage(
    +              message, field, input->GetExtensionFactory());
    +        }
    +
    +        if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
    +        break;
    +      }
    +    }
    +  }
    +
    +  return true;
    +}
    +
    +bool WireFormat::ParseAndMergeMessageSetItem(
    +    io::CodedInputStream* input,
    +    Message* message) {
    +  const Reflection* message_reflection = message->GetReflection();
    +
    +  // This method parses a group which should contain two fields:
    +  //   required int32 type_id = 2;
    +  //   required data message = 3;
    +
    +  uint32 last_type_id = 0;
    +
    +  // Once we see a type_id, we'll look up the FieldDescriptor for the
    +  // extension.
    +  const FieldDescriptor* field = NULL;
    +
    +  // If we see message data before the type_id, we'll append it to this so
    +  // we can parse it later.
    +  string message_data;
    +
    +  while (true) {
    +    uint32 tag = input->ReadTag();
    +    if (tag == 0) return false;
    +
    +    switch (tag) {
    +      case WireFormatLite::kMessageSetTypeIdTag: {
    +        uint32 type_id;
    +        if (!input->ReadVarint32(&type_id)) return false;
    +        last_type_id = type_id;
    +        field = message_reflection->FindKnownExtensionByNumber(type_id);
    +
    +        if (!message_data.empty()) {
    +          // We saw some message data before the type_id.  Have to parse it
    +          // now.
    +          io::ArrayInputStream raw_input(message_data.data(),
    +                                         message_data.size());
    +          io::CodedInputStream sub_input(&raw_input);
    +          if (!ParseAndMergeMessageSetField(last_type_id, field, message,
    +                                            &sub_input)) {
    +            return false;
    +          }
    +          message_data.clear();
    +        }
    +
    +        break;
    +      }
    +
    +      case WireFormatLite::kMessageSetMessageTag: {
    +        if (last_type_id == 0) {
    +          // We haven't seen a type_id yet.  Append this data to message_data.
    +          string temp;
    +          uint32 length;
    +          if (!input->ReadVarint32(&length)) return false;
    +          if (!input->ReadString(&temp, length)) return false;
    +          io::StringOutputStream output_stream(&message_data);
    +          io::CodedOutputStream coded_output(&output_stream);
    +          coded_output.WriteVarint32(length);
    +          coded_output.WriteString(temp);
    +        } else {
    +          // Already saw type_id, so we can parse this directly.
    +          if (!ParseAndMergeMessageSetField(last_type_id, field, message,
    +                                            input)) {
    +            return false;
    +          }
    +        }
    +
    +        break;
    +      }
    +
    +      case WireFormatLite::kMessageSetItemEndTag: {
    +        return true;
    +      }
    +
    +      default: {
    +        if (!SkipField(input, tag, NULL)) return false;
    +      }
    +    }
    +  }
    +}
    +
    +// ===================================================================
    +
    +void WireFormat::SerializeWithCachedSizes(
    +    const Message& message,
    +    int size, io::CodedOutputStream* output) {
    +  const Descriptor* descriptor = message.GetDescriptor();
    +  const Reflection* message_reflection = message.GetReflection();
    +  int expected_endpoint = output->ByteCount() + size;
    +
    +  vector fields;
    +  message_reflection->ListFields(message, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    SerializeFieldWithCachedSizes(fields[i], message, output);
    +  }
    +
    +  if (descriptor->options().message_set_wire_format()) {
    +    SerializeUnknownMessageSetItems(
    +        message_reflection->GetUnknownFields(message), output);
    +  } else {
    +    SerializeUnknownFields(
    +        message_reflection->GetUnknownFields(message), output);
    +  }
    +
    +  GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint)
    +    << ": Protocol message serialized to a size different from what was "
    +       "originally expected.  Perhaps it was modified by another thread "
    +       "during serialization?";
    +}
    +
    +void WireFormat::SerializeFieldWithCachedSizes(
    +    const FieldDescriptor* field,
    +    const Message& message,
    +    io::CodedOutputStream* output) {
    +  const Reflection* message_reflection = message.GetReflection();
    +
    +  if (field->is_extension() &&
    +      field->containing_type()->options().message_set_wire_format() &&
    +      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
    +      !field->is_repeated()) {
    +    SerializeMessageSetItemWithCachedSizes(field, message, output);
    +    return;
    +  }
    +
    +  int count = 0;
    +
    +  if (field->is_repeated()) {
    +    count = message_reflection->FieldSize(message, field);
    +  } else if (message_reflection->HasField(message, field)) {
    +    count = 1;
    +  }
    +
    +  const bool is_packed = field->options().packed();
    +  if (is_packed && count > 0) {
    +    WireFormatLite::WriteTag(field->number(),
    +        WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    +    const int data_size = FieldDataOnlyByteSize(field, message);
    +    output->WriteVarint32(data_size);
    +  }
    +
    +  for (int j = 0; j < count; j++) {
    +    switch (field->type()) {
    +#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)      \
    +      case FieldDescriptor::TYPE_##TYPE: {                                     \
    +        const CPPTYPE value = field->is_repeated() ?                           \
    +                              message_reflection->GetRepeated##CPPTYPE_METHOD( \
    +                                message, field, j) :                           \
    +                              message_reflection->Get##CPPTYPE_METHOD(         \
    +                                message, field);                               \
    +        if (is_packed) {                                                       \
    +          WireFormatLite::Write##TYPE_METHOD##NoTag(value, output);            \
    +        } else {                                                               \
    +          WireFormatLite::Write##TYPE_METHOD(field->number(), value, output);  \
    +        }                                                                      \
    +        break;                                                                 \
    +      }
    +
    +      HANDLE_PRIMITIVE_TYPE( INT32,  int32,  Int32,  Int32)
    +      HANDLE_PRIMITIVE_TYPE( INT64,  int64,  Int64,  Int64)
    +      HANDLE_PRIMITIVE_TYPE(SINT32,  int32, SInt32,  Int32)
    +      HANDLE_PRIMITIVE_TYPE(SINT64,  int64, SInt64,  Int64)
    +      HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
    +      HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
    +
    +      HANDLE_PRIMITIVE_TYPE( FIXED32, uint32,  Fixed32, UInt32)
    +      HANDLE_PRIMITIVE_TYPE( FIXED64, uint64,  Fixed64, UInt64)
    +      HANDLE_PRIMITIVE_TYPE(SFIXED32,  int32, SFixed32,  Int32)
    +      HANDLE_PRIMITIVE_TYPE(SFIXED64,  int64, SFixed64,  Int64)
    +
    +      HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
    +      HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
    +
    +      HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
    +#undef HANDLE_PRIMITIVE_TYPE
    +
    +      case FieldDescriptor::TYPE_GROUP:
    +        WireFormatLite::WriteGroup(
    +              field->number(),
    +              field->is_repeated() ?
    +                message_reflection->GetRepeatedMessage(
    +                  message, field, j) :
    +                message_reflection->GetMessage(message, field),
    +              output);
    +        break;
    +
    +      case FieldDescriptor::TYPE_MESSAGE:
    +        WireFormatLite::WriteMessage(
    +              field->number(),
    +              field->is_repeated() ?
    +                message_reflection->GetRepeatedMessage(
    +                  message, field, j) :
    +                message_reflection->GetMessage(message, field),
    +              output);
    +        break;
    +
    +      case FieldDescriptor::TYPE_ENUM: {
    +        const EnumValueDescriptor* value = field->is_repeated() ?
    +          message_reflection->GetRepeatedEnum(message, field, j) :
    +          message_reflection->GetEnum(message, field);
    +        if (is_packed) {
    +          WireFormatLite::WriteEnumNoTag(value->number(), output);
    +        } else {
    +          WireFormatLite::WriteEnum(field->number(), value->number(), output);
    +        }
    +        break;
    +      }
    +
    +      // Handle strings separately so that we can get string references
    +      // instead of copying.
    +      case FieldDescriptor::TYPE_STRING: {
    +        string scratch;
    +        const string& value = field->is_repeated() ?
    +          message_reflection->GetRepeatedStringReference(
    +            message, field, j, &scratch) :
    +          message_reflection->GetStringReference(message, field, &scratch);
    +        VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
    +                                   field->name().c_str());
    +        WireFormatLite::WriteString(field->number(), value, output);
    +        break;
    +      }
    +
    +      case FieldDescriptor::TYPE_BYTES: {
    +        string scratch;
    +        const string& value = field->is_repeated() ?
    +          message_reflection->GetRepeatedStringReference(
    +            message, field, j, &scratch) :
    +          message_reflection->GetStringReference(message, field, &scratch);
    +        WireFormatLite::WriteBytes(field->number(), value, output);
    +        break;
    +      }
    +    }
    +  }
    +}
    +
    +void WireFormat::SerializeMessageSetItemWithCachedSizes(
    +    const FieldDescriptor* field,
    +    const Message& message,
    +    io::CodedOutputStream* output) {
    +  const Reflection* message_reflection = message.GetReflection();
    +
    +  // Start group.
    +  output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
    +
    +  // Write type ID.
    +  output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
    +  output->WriteVarint32(field->number());
    +
    +  // Write message.
    +  output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
    +
    +  const Message& sub_message = message_reflection->GetMessage(message, field);
    +  output->WriteVarint32(sub_message.GetCachedSize());
    +  sub_message.SerializeWithCachedSizes(output);
    +
    +  // End group.
    +  output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
    +}
    +
    +// ===================================================================
    +
    +int WireFormat::ByteSize(const Message& message) {
    +  const Descriptor* descriptor = message.GetDescriptor();
    +  const Reflection* message_reflection = message.GetReflection();
    +
    +  int our_size = 0;
    +
    +  vector fields;
    +  message_reflection->ListFields(message, &fields);
    +  for (int i = 0; i < fields.size(); i++) {
    +    our_size += FieldByteSize(fields[i], message);
    +  }
    +
    +  if (descriptor->options().message_set_wire_format()) {
    +    our_size += ComputeUnknownMessageSetItemsSize(
    +      message_reflection->GetUnknownFields(message));
    +  } else {
    +    our_size += ComputeUnknownFieldsSize(
    +      message_reflection->GetUnknownFields(message));
    +  }
    +
    +  return our_size;
    +}
    +
    +int WireFormat::FieldByteSize(
    +    const FieldDescriptor* field,
    +    const Message& message) {
    +  const Reflection* message_reflection = message.GetReflection();
    +
    +  if (field->is_extension() &&
    +      field->containing_type()->options().message_set_wire_format() &&
    +      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
    +      !field->is_repeated()) {
    +    return MessageSetItemByteSize(field, message);
    +  }
    +
    +  int count = 0;
    +  if (field->is_repeated()) {
    +    count = message_reflection->FieldSize(message, field);
    +  } else if (message_reflection->HasField(message, field)) {
    +    count = 1;
    +  }
    +
    +  const int data_size = FieldDataOnlyByteSize(field, message);
    +  int our_size = data_size;
    +  if (field->options().packed()) {
    +    if (data_size > 0) {
    +      // Packed fields get serialized like a string, not their native type.
    +      // Technically this doesn't really matter; the size only changes if it's
    +      // a GROUP
    +      our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
    +      our_size += io::CodedOutputStream::VarintSize32(data_size);
    +    }
    +  } else {
    +    our_size += count * TagSize(field->number(), field->type());
    +  }
    +  return our_size;
    +}
    +
    +int WireFormat::FieldDataOnlyByteSize(
    +    const FieldDescriptor* field,
    +    const Message& message) {
    +  const Reflection* message_reflection = message.GetReflection();
    +
    +  int count = 0;
    +  if (field->is_repeated()) {
    +    count = message_reflection->FieldSize(message, field);
    +  } else if (message_reflection->HasField(message, field)) {
    +    count = 1;
    +  }
    +
    +  int data_size = 0;
    +  switch (field->type()) {
    +#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                     \
    +    case FieldDescriptor::TYPE_##TYPE:                                     \
    +      if (field->is_repeated()) {                                          \
    +        for (int j = 0; j < count; j++) {                                  \
    +          data_size += WireFormatLite::TYPE_METHOD##Size(                  \
    +            message_reflection->GetRepeated##CPPTYPE_METHOD(               \
    +              message, field, j));                                         \
    +        }                                                                  \
    +      } else {                                                             \
    +        data_size += WireFormatLite::TYPE_METHOD##Size(                    \
    +          message_reflection->Get##CPPTYPE_METHOD(message, field));        \
    +      }                                                                    \
    +      break;
    +
    +#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD)                               \
    +    case FieldDescriptor::TYPE_##TYPE:                                     \
    +      data_size += count * WireFormatLite::k##TYPE_METHOD##Size;           \
    +      break;
    +
    +    HANDLE_TYPE( INT32,  Int32,  Int32)
    +    HANDLE_TYPE( INT64,  Int64,  Int64)
    +    HANDLE_TYPE(SINT32, SInt32,  Int32)
    +    HANDLE_TYPE(SINT64, SInt64,  Int64)
    +    HANDLE_TYPE(UINT32, UInt32, UInt32)
    +    HANDLE_TYPE(UINT64, UInt64, UInt64)
    +
    +    HANDLE_FIXED_TYPE( FIXED32,  Fixed32)
    +    HANDLE_FIXED_TYPE( FIXED64,  Fixed64)
    +    HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
    +    HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
    +
    +    HANDLE_FIXED_TYPE(FLOAT , Float )
    +    HANDLE_FIXED_TYPE(DOUBLE, Double)
    +
    +    HANDLE_FIXED_TYPE(BOOL, Bool)
    +
    +    HANDLE_TYPE(GROUP  , Group  , Message)
    +    HANDLE_TYPE(MESSAGE, Message, Message)
    +#undef HANDLE_TYPE
    +#undef HANDLE_FIXED_TYPE
    +
    +    case FieldDescriptor::TYPE_ENUM: {
    +      if (field->is_repeated()) {
    +        for (int j = 0; j < count; j++) {
    +          data_size += WireFormatLite::EnumSize(
    +            message_reflection->GetRepeatedEnum(message, field, j)->number());
    +        }
    +      } else {
    +        data_size += WireFormatLite::EnumSize(
    +          message_reflection->GetEnum(message, field)->number());
    +      }
    +      break;
    +    }
    +
    +    // Handle strings separately so that we can get string references
    +    // instead of copying.
    +    case FieldDescriptor::TYPE_STRING:
    +    case FieldDescriptor::TYPE_BYTES: {
    +      for (int j = 0; j < count; j++) {
    +        string scratch;
    +        const string& value = field->is_repeated() ?
    +          message_reflection->GetRepeatedStringReference(
    +            message, field, j, &scratch) :
    +          message_reflection->GetStringReference(message, field, &scratch);
    +        data_size += WireFormatLite::StringSize(value);
    +      }
    +      break;
    +    }
    +  }
    +  return data_size;
    +}
    +
    +int WireFormat::MessageSetItemByteSize(
    +    const FieldDescriptor* field,
    +    const Message& message) {
    +  const Reflection* message_reflection = message.GetReflection();
    +
    +  int our_size = WireFormatLite::kMessageSetItemTagsSize;
    +
    +  // type_id
    +  our_size += io::CodedOutputStream::VarintSize32(field->number());
    +
    +  // message
    +  const Message& sub_message = message_reflection->GetMessage(message, field);
    +  int message_size = sub_message.ByteSize();
    +
    +  our_size += io::CodedOutputStream::VarintSize32(message_size);
    +  our_size += message_size;
    +
    +  return our_size;
    +}
    +
    +void WireFormat::VerifyUTF8StringFallback(const char* data,
    +                                          int size,
    +                                          Operation op,
    +                                          const char* field_name) {
    +  if (!IsStructurallyValidUTF8(data, size)) {
    +    const char* operation_str = NULL;
    +    switch (op) {
    +      case PARSE:
    +        operation_str = "parsing";
    +        break;
    +      case SERIALIZE:
    +        operation_str = "serializing";
    +        break;
    +      // no default case: have the compiler warn if a case is not covered.
    +    }
    +    string quoted_field_name = "";
    +    if (field_name != NULL) {
    +      quoted_field_name = StringPrintf(" '%s'", field_name);
    +    }
    +    // no space below to avoid double space when the field name is missing.
    +    GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "
    +               << "UTF-8 data when " << operation_str << " a protocol "
    +               << "buffer. Use the 'bytes' type if you intend to send raw "
    +               << "bytes. ";
    +  }
    +}
    +
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +}  // namespace google
    diff --git a/toolkit/components/protobuf/src/google/protobuf/wire_format.h b/toolkit/components/protobuf/src/google/protobuf/wire_format.h
    new file mode 100644
    index 000000000000..9f26eb29bdf5
    --- /dev/null
    +++ b/toolkit/components/protobuf/src/google/protobuf/wire_format.h
    @@ -0,0 +1,336 @@
    +// Protocol Buffers - Google's data interchange format
    +// Copyright 2008 Google Inc.  All rights reserved.
    +// https://developers.google.com/protocol-buffers/
    +//
    +// Redistribution and use in source and binary forms, with or without
    +// modification, are permitted provided that the following conditions are
    +// met:
    +//
    +//     * Redistributions of source code must retain the above copyright
    +// notice, this list of conditions and the following disclaimer.
    +//     * Redistributions in binary form must reproduce the above
    +// copyright notice, this list of conditions and the following disclaimer
    +// in the documentation and/or other materials provided with the
    +// distribution.
    +//     * Neither the name of Google Inc. nor the names of its
    +// contributors may be used to endorse or promote products derived from
    +// this software without specific prior written permission.
    +//
    +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +// Author: kenton@google.com (Kenton Varda)
    +//         atenasio@google.com (Chris Atenasio) (ZigZag transform)
    +//  Based on original Protocol Buffers design by
    +//  Sanjay Ghemawat, Jeff Dean, and others.
    +//
    +// This header is logically internal, but is made public because it is used
    +// from protocol-compiler-generated code, which may reside in other components.
    +
    +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__
    +#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +// Do UTF-8 validation on string type in Debug build only
    +#ifndef NDEBUG
    +#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
    +#endif
    +
    +namespace google {
    +namespace protobuf {
    +  namespace io {
    +    class CodedInputStream;      // coded_stream.h
    +    class CodedOutputStream;     // coded_stream.h
    +  }
    +  class UnknownFieldSet;         // unknown_field_set.h
    +}
    +
    +namespace protobuf {
    +namespace internal {
    +
    +// This class is for internal use by the protocol buffer library and by
    +// protocol-complier-generated message classes.  It must not be called
    +// directly by clients.
    +//
    +// This class contains code for implementing the binary protocol buffer
    +// wire format via reflection.  The WireFormatLite class implements the
    +// non-reflection based routines.
    +//
    +// This class is really a namespace that contains only static methods
    +class LIBPROTOBUF_EXPORT WireFormat {
    + public:
    +
    +  // Given a field return its WireType
    +  static inline WireFormatLite::WireType WireTypeForField(
    +      const FieldDescriptor* field);
    +
    +  // Given a FieldDescriptor::Type return its WireType
    +  static inline WireFormatLite::WireType WireTypeForFieldType(
    +      FieldDescriptor::Type type);
    +
    +  // Compute the byte size of a tag.  For groups, this includes both the start
    +  // and end tags.
    +  static inline int TagSize(int field_number, FieldDescriptor::Type type);
    +
    +  // These procedures can be used to implement the methods of Message which
    +  // handle parsing and serialization of the protocol buffer wire format
    +  // using only the Reflection interface.  When you ask the protocol
    +  // compiler to optimize for code size rather than speed, it will implement
    +  // those methods in terms of these procedures.  Of course, these are much
    +  // slower than the specialized implementations which the protocol compiler
    +  // generates when told to optimize for speed.
    +
    +  // Read a message in protocol buffer wire format.
    +  //
    +  // This procedure reads either to the end of the input stream or through
    +  // a WIRETYPE_END_GROUP tag ending the message, whichever comes first.
    +  // It returns false if the input is invalid.
    +  //
    +  // Required fields are NOT checked by this method.  You must call
    +  // IsInitialized() on the resulting message yourself.
    +  static bool ParseAndMergePartial(io::CodedInputStream* input,
    +                                   Message* message);
    +
    +  // Serialize a message in protocol buffer wire format.
    +  //
    +  // Any embedded messages within the message must have their correct sizes
    +  // cached.  However, the top-level message need not; its size is passed as
    +  // a parameter to this procedure.
    +  //
    +  // These return false iff the underlying stream returns a write error.
    +  static void SerializeWithCachedSizes(
    +      const Message& message,
    +      int size, io::CodedOutputStream* output);
    +
    +  // Implements Message::ByteSize() via reflection.  WARNING:  The result
    +  // of this method is *not* cached anywhere.  However, all embedded messages
    +  // will have their ByteSize() methods called, so their sizes will be cached.
    +  // Therefore, calling this method is sufficient to allow you to call
    +  // WireFormat::SerializeWithCachedSizes() on the same object.
    +  static int ByteSize(const Message& message);
    +
    +  // -----------------------------------------------------------------
    +  // Helpers for dealing with unknown fields
    +
    +  // Skips a field value of the given WireType.  The input should start
    +  // positioned immediately after the tag.  If unknown_fields is non-NULL,
    +  // the contents of the field will be added to it.
    +  static bool SkipField(io::CodedInputStream* input, uint32 tag,
    +                        UnknownFieldSet* unknown_fields);
    +
    +  // Reads and ignores a message from the input.  If unknown_fields is non-NULL,
    +  // the contents will be added to it.
    +  static bool SkipMessage(io::CodedInputStream* input,
    +                          UnknownFieldSet* unknown_fields);
    +
    +  // Write the contents of an UnknownFieldSet to the output.
    +  static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
    +                                     io::CodedOutputStream* output);
    +  // Same as above, except writing directly to the provided buffer.
    +  // Requires that the buffer have sufficient capacity for
    +  // ComputeUnknownFieldsSize(unknown_fields).
    +  //
    +  // Returns a pointer past the last written byte.
    +  static uint8* SerializeUnknownFieldsToArray(
    +      const UnknownFieldSet& unknown_fields,
    +      uint8* target);
    +
    +  // Same thing except for messages that have the message_set_wire_format
    +  // option.
    +  static void SerializeUnknownMessageSetItems(
    +      const UnknownFieldSet& unknown_fields,
    +      io::CodedOutputStream* output);
    +  // Same as above, except writing directly to the provided buffer.
    +  // Requires that the buffer have sufficient capacity for
    +  // ComputeUnknownMessageSetItemsSize(unknown_fields).
    +  //
    +  // Returns a pointer past the last written byte.
    +  static uint8* SerializeUnknownMessageSetItemsToArray(
    +      const UnknownFieldSet& unknown_fields,
    +      uint8* target);
    +
    +  // Compute the size of the UnknownFieldSet on the wire.
    +  static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields);
    +
    +  // Same thing except for messages that have the message_set_wire_format
    +  // option.
    +  static int ComputeUnknownMessageSetItemsSize(
    +      const UnknownFieldSet& unknown_fields);
    +
    +
    +  // Helper functions for encoding and decoding tags.  (Inlined below and in
    +  // _inl.h)
    +  //
    +  // This is different from MakeTag(field->number(), field->type()) in the case
    +  // of packed repeated fields.
    +  static uint32 MakeTag(const FieldDescriptor* field);
    +
    +  // Parse a single field.  The input should start out positioned immediately
    +  // after the tag.
    +  static bool ParseAndMergeField(
    +      uint32 tag,
    +      const FieldDescriptor* field,        // May be NULL for unknown
    +      Message* message,
    +      io::CodedInputStream* input);
    +
    +  // Serialize a single field.
    +  static void SerializeFieldWithCachedSizes(
    +      const FieldDescriptor* field,        // Cannot be NULL
    +      const Message& message,
    +      io::CodedOutputStream* output);
    +
    +  // Compute size of a single field.  If the field is a message type, this
    +  // will call ByteSize() for the embedded message, insuring that it caches
    +  // its size.
    +  static int FieldByteSize(
    +      const FieldDescriptor* field,        // Cannot be NULL
    +      const Message& message);
    +
    +  // Parse/serialize a MessageSet::Item group.  Used with messages that use
    +  // opion message_set_wire_format = true.
    +  static bool ParseAndMergeMessageSetItem(
    +      io::CodedInputStream* input,
    +      Message* message);
    +  static void SerializeMessageSetItemWithCachedSizes(
    +      const FieldDescriptor* field,
    +      const Message& message,
    +      io::CodedOutputStream* output);
    +  static int MessageSetItemByteSize(
    +      const FieldDescriptor* field,
    +      const Message& message);
    +
    +  // Computes the byte size of a field, excluding tags. For packed fields, it
    +  // only includes the size of the raw data, and not the size of the total
    +  // length, but for other length-delimited types, the size of the length is
    +  // included.
    +  static int FieldDataOnlyByteSize(
    +      const FieldDescriptor* field,        // Cannot be NULL
    +      const Message& message);
    +
    +  enum Operation {
    +    PARSE,
    +    SERIALIZE,
    +  };
    +
    +  // Verifies that a string field is valid UTF8, logging an error if not.
    +  // This function will not be called by newly generated protobuf code
    +  // but remains present to support existing code.
    +  static void VerifyUTF8String(const char* data, int size, Operation op);
    +  // The NamedField variant takes a field name in order to produce an
    +  // informative error message if verification fails.
    +  static void VerifyUTF8StringNamedField(const char* data,
    +                                         int size,
    +                                         Operation op,
    +                                         const char* field_name);
    +
    + private:
    +  // Verifies that a string field is valid UTF8, logging an error if not.
    +  static void VerifyUTF8StringFallback(
    +      const char* data,
    +      int size,
    +      Operation op,
    +      const char* field_name);
    +
    +  // Skip a MessageSet field.
    +  static bool SkipMessageSetField(io::CodedInputStream* input,
    +                                  uint32 field_number,
    +                                  UnknownFieldSet* unknown_fields);
    +
    +  // Parse a MessageSet field.
    +  static bool ParseAndMergeMessageSetField(uint32 field_number,
    +                                           const FieldDescriptor* field,
    +                                           Message* message,
    +                                           io::CodedInputStream* input);
    +
    +
    +
    +  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
    +};
    +
    +// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet.
    +class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper {
    + public:
    +  UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields)
    +      : unknown_fields_(unknown_fields) {}
    +  virtual ~UnknownFieldSetFieldSkipper() {}
    +
    +  // implements FieldSkipper -----------------------------------------
    +  virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
    +  virtual bool SkipMessage(io::CodedInputStream* input);
    +  virtual void SkipUnknownEnum(int field_number, int value);
    +
    + protected:
    +  UnknownFieldSet* unknown_fields_;
    +};
    +
    +// inline methods ====================================================
    +
    +inline WireFormatLite::WireType WireFormat::WireTypeForField(
    +    const FieldDescriptor* field) {
    +  if (field->options().packed()) {
    +    return WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
    +  } else {
    +    return WireTypeForFieldType(field->type());
    +  }
    +}
    +
    +inline WireFormatLite::WireType WireFormat::WireTypeForFieldType(
    +    FieldDescriptor::Type type) {
    +  // Some compilers don't like enum -> enum casts, so we implicit_cast to
    +  // int first.
    +  return WireFormatLite::WireTypeForFieldType(
    +      static_cast(
    +        implicit_cast(type)));
    +}
    +
    +inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
    +  return WireFormatLite::MakeTag(field->number(), WireTypeForField(field));
    +}
    +
    +inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) {
    +  // Some compilers don't like enum -> enum casts, so we implicit_cast to
    +  // int first.
    +  return WireFormatLite::TagSize(field_number,
    +      static_cast(
    +        implicit_cast(type)));
    +}
    +
    +inline void WireFormat::VerifyUTF8String(const char* data, int size,
    +    WireFormat::Operation op) {
    +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
    +  WireFormat::VerifyUTF8StringFallback(data, size, op, NULL);
    +#else
    +  // Avoid the compiler warning about unsued variables.
    +  (void)data; (void)size; (void)op;
    +#endif
    +}
    +
    +inline void WireFormat::VerifyUTF8StringNamedField(
    +    const char* data, int size, WireFormat::Operation op,
    +    const char* field_name) {
    +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
    +  WireFormat::VerifyUTF8StringFallback(data, size, op, field_name);
    +#endif
    +}
    +
    +
    +}  // namespace internal
    +}  // namespace protobuf
    +
    +}  // namespace google
    +#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_H__
    diff --git a/toolkit/components/protobuf/google/protobuf/wire_format_lite.cc b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc
    similarity index 76%
    rename from toolkit/components/protobuf/google/protobuf/wire_format_lite.cc
    rename to toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc
    index b1ff93a293ce..8de827849da8 100644
    --- a/toolkit/components/protobuf/google/protobuf/wire_format_lite.cc
    +++ b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.cc
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -56,10 +56,10 @@ const int WireFormatLite::kMessageSetMessageTag;
     #endif
     
     const int WireFormatLite::kMessageSetItemTagsSize =
    -  io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) +
    -  io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
    -  io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
    -  io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
    +  io::CodedOutputStream::StaticVarintSize32::value +
    +  io::CodedOutputStream::StaticVarintSize32::value +
    +  io::CodedOutputStream::StaticVarintSize32::value +
    +  io::CodedOutputStream::StaticVarintSize32::value;
     
     const WireFormatLite::CppType
     WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
    @@ -153,8 +153,65 @@ bool WireFormatLite::SkipField(
       }
     }
     
    +bool WireFormatLite::SkipField(
    +    io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
    +  switch (WireFormatLite::GetTagWireType(tag)) {
    +    case WireFormatLite::WIRETYPE_VARINT: {
    +      uint64 value;
    +      if (!input->ReadVarint64(&value)) return false;
    +      output->WriteVarint32(tag);
    +      output->WriteVarint64(value);
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_FIXED64: {
    +      uint64 value;
    +      if (!input->ReadLittleEndian64(&value)) return false;
    +      output->WriteVarint32(tag);
    +      output->WriteLittleEndian64(value);
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
    +      uint32 length;
    +      if (!input->ReadVarint32(&length)) return false;
    +      output->WriteVarint32(tag);
    +      output->WriteVarint32(length);
    +      // TODO(mkilavuz): Provide API to prevent extra string copying.
    +      string temp;
    +      if (!input->ReadString(&temp, length)) return false;
    +      output->WriteString(temp);
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_START_GROUP: {
    +      output->WriteVarint32(tag);
    +      if (!input->IncrementRecursionDepth()) return false;
    +      if (!SkipMessage(input, output)) return false;
    +      input->DecrementRecursionDepth();
    +      // Check that the ending tag matched the starting tag.
    +      if (!input->LastTagWas(WireFormatLite::MakeTag(
    +          WireFormatLite::GetTagFieldNumber(tag),
    +          WireFormatLite::WIRETYPE_END_GROUP))) {
    +        return false;
    +      }
    +      return true;
    +    }
    +    case WireFormatLite::WIRETYPE_END_GROUP: {
    +      return false;
    +    }
    +    case WireFormatLite::WIRETYPE_FIXED32: {
    +      uint32 value;
    +      if (!input->ReadLittleEndian32(&value)) return false;
    +      output->WriteVarint32(tag);
    +      output->WriteLittleEndian32(value);
    +      return true;
    +    }
    +    default: {
    +      return false;
    +    }
    +  }
    +}
    +
     bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
    -  while(true) {
    +  while (true) {
         uint32 tag = input->ReadTag();
         if (tag == 0) {
           // End of input.  This is a valid place to end, so return true.
    @@ -172,6 +229,27 @@ bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
       }
     }
     
    +bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
    +    io::CodedOutputStream* output) {
    +  while (true) {
    +    uint32 tag = input->ReadTag();
    +    if (tag == 0) {
    +      // End of input.  This is a valid place to end, so return true.
    +      return true;
    +    }
    +
    +    WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
    +
    +    if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
    +      output->WriteVarint32(tag);
    +      // Must be the end of the message.
    +      return true;
    +    }
    +
    +    if (!SkipField(input, tag, output)) return false;
    +  }
    +}
    +
     bool FieldSkipper::SkipField(
         io::CodedInputStream* input, uint32 tag) {
       return WireFormatLite::SkipField(input, tag);
    @@ -182,10 +260,25 @@ bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
     }
     
     void FieldSkipper::SkipUnknownEnum(
    -    int field_number, int value) {
    +    int /* field_number */, int /* value */) {
       // Nothing.
     }
     
    +bool CodedOutputStreamFieldSkipper::SkipField(
    +    io::CodedInputStream* input, uint32 tag) {
    +  return WireFormatLite::SkipField(input, tag, unknown_fields_);
    +}
    +
    +bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
    +  return WireFormatLite::SkipMessage(input, unknown_fields_);
    +}
    +
    +void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
    +    int field_number, int value) {
    +  unknown_fields_->WriteVarint32(field_number);
    +  unknown_fields_->WriteVarint64(value);
    +}
    +
     bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
                                                 bool (*is_valid)(int),
                                                 RepeatedField* values) {
    @@ -281,15 +374,34 @@ void WireFormatLite::WriteString(int field_number, const string& value,
                                      io::CodedOutputStream* output) {
       // String is for UTF-8 text only
       WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    +  GOOGLE_CHECK(value.size() <= kint32max);
       output->WriteVarint32(value.size());
       output->WriteString(value);
     }
    +void WireFormatLite::WriteStringMaybeAliased(
    +    int field_number, const string& value,
    +    io::CodedOutputStream* output) {
    +  // String is for UTF-8 text only
    +  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    +  GOOGLE_CHECK(value.size() <= kint32max);
    +  output->WriteVarint32(value.size());
    +  output->WriteRawMaybeAliased(value.data(), value.size());
    +}
     void WireFormatLite::WriteBytes(int field_number, const string& value,
                                     io::CodedOutputStream* output) {
       WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    +  GOOGLE_CHECK(value.size() <= kint32max);
       output->WriteVarint32(value.size());
       output->WriteString(value);
     }
    +void WireFormatLite::WriteBytesMaybeAliased(
    +    int field_number, const string& value,
    +    io::CodedOutputStream* output) {
    +  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    +  GOOGLE_CHECK(value.size() <= kint32max);
    +  output->WriteVarint32(value.size());
    +  output->WriteRawMaybeAliased(value.data(), value.size());
    +}
     
     
     void WireFormatLite::WriteGroup(int field_number,
    diff --git a/toolkit/components/protobuf/google/protobuf/wire_format_lite.h b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
    similarity index 92%
    rename from toolkit/components/protobuf/google/protobuf/wire_format_lite.h
    rename to toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
    index e3d5b2d8d05c..14b3feb6ab2e 100644
    --- a/toolkit/components/protobuf/google/protobuf/wire_format_lite.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -40,17 +40,16 @@
     #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
     #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
     
    +#include 
     #include 
    +#include 
     #include 
    +#include   // for CodedOutputStream::Varint32Size
     
     namespace google {
     
     namespace protobuf {
       template  class RepeatedField;  // repeated_field.h
    -  namespace io {
    -    class CodedInputStream;             // coded_stream.h
    -    class CodedOutputStream;            // coded_stream.h
    -  }
     }
     
     namespace protobuf {
    @@ -165,11 +164,22 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
       // records to an UnknownFieldSet.
       static bool SkipField(io::CodedInputStream* input, uint32 tag);
     
    +  // Skips a field value with the given tag.  The input should start
    +  // positioned immediately after the tag. Skipped values are recorded to a
    +  // CodedOutputStream.
    +  static bool SkipField(io::CodedInputStream* input, uint32 tag,
    +                        io::CodedOutputStream* output);
    +
       // Reads and ignores a message from the input.  Skipped values are simply
       // discarded, not recorded anywhere.  See WireFormat::SkipMessage() for a
       // version that records to an UnknownFieldSet.
       static bool SkipMessage(io::CodedInputStream* input);
     
    +  // Reads and ignores a message from the input.  Skipped values are recorded
    +  // to a CodedOutputStream.
    +  static bool SkipMessage(io::CodedInputStream* input,
    +                          io::CodedOutputStream* output);
    +
     // This macro does the same thing as WireFormatLite::MakeTag(), but the
     // result is usable as a compile-time constant, which makes it usable
     // as a switch case or a template input.  WireFormatLite::MakeTag() is more
    @@ -230,9 +240,9 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
       // that file to use these.
     
     // Avoid ugly line wrapping
    -#define input  io::CodedInputStream*  input
    -#define output io::CodedOutputStream* output
    -#define field_number int field_number
    +#define input  io::CodedInputStream*  input_arg
    +#define output io::CodedOutputStream* output_arg
    +#define field_number int field_number_arg
     #define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE
     
       // Read fields, not including tags.  The assumption is that you already
    @@ -342,6 +352,10 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
     
       static void WriteString(field_number, const string& value, output);
       static void WriteBytes (field_number, const string& value, output);
    +  static void WriteStringMaybeAliased(
    +      field_number, const string& value, output);
    +  static void WriteBytesMaybeAliased(
    +      field_number, const string& value, output);
     
       static void WriteGroup(
         field_number, const MessageLite& value, output);
    @@ -477,6 +491,10 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
       template
       static inline int MessageSizeNoVirtual(const MessageType& value);
     
    +  // Given the length of data, calculate the byte size of the data on the
    +  // wire if we encode the data as a length delimited field.
    +  static inline int LengthDelimitedSize(int length);
    +
      private:
       // A helper method for the repeated primitive reader. This method has
       // optimizations for primitive types that have fixed size on the wire, and
    @@ -488,6 +506,12 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
           google::protobuf::io::CodedInputStream* input,
           RepeatedField* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
     
    +  // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
    +  template 
    +  static inline bool ReadPackedFixedSizePrimitive(
    +      google::protobuf::io::CodedInputStream* input,
    +      RepeatedField* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
    +
       static const CppType kFieldTypeToCppTypeMap[];
       static const WireFormatLite::WireType kWireTypeForFieldType[];
     
    @@ -516,6 +540,24 @@ class LIBPROTOBUF_EXPORT FieldSkipper {
       virtual void SkipUnknownEnum(int field_number, int value);
     };
     
    +// Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream.
    +
    +class LIBPROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper {
    + public:
    +  explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields)
    +      : unknown_fields_(unknown_fields) {}
    +  virtual ~CodedOutputStreamFieldSkipper() {}
    +
    +  // implements FieldSkipper -----------------------------------------
    +  virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
    +  virtual bool SkipMessage(io::CodedInputStream* input);
    +  virtual void SkipUnknownEnum(int field_number, int value);
    +
    + protected:
    +  io::CodedOutputStream* unknown_fields_;
    +};
    +
    +
     // inline methods ====================================================
     
     inline WireFormatLite::CppType
    diff --git a/toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite_inl.h
    similarity index 86%
    rename from toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h
    rename to toolkit/components/protobuf/src/google/protobuf/wire_format_lite_inl.h
    index 729767464977..feb225404364 100644
    --- a/toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h
    +++ b/toolkit/components/protobuf/src/google/protobuf/wire_format_lite_inl.h
    @@ -1,6 +1,6 @@
     // Protocol Buffers - Google's data interchange format
     // Copyright 2008 Google Inc.  All rights reserved.
    -// http://code.google.com/p/protobuf/
    +// https://developers.google.com/protocol-buffers/
     //
     // Redistribution and use in source and binary forms, with or without
     // modification, are permitted provided that the following conditions are
    @@ -36,13 +36,16 @@
     #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
     #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
     
    +#ifdef _MSC_VER
    +// This is required for min/max on VS2013 only.
     #include 
    +#endif
    +
     #include 
     #include 
     #include 
     #include 
     #include 
    -#include 
     #include 
     
     
    @@ -152,8 +155,8 @@ template <>
     inline bool WireFormatLite::ReadPrimitive(
         io::CodedInputStream* input,
         bool* value) {
    -  uint32 temp;
    -  if (!input->ReadVarint32(&temp)) return false;
    +  uint64 temp;
    +  if (!input->ReadVarint64(&temp)) return false;
       *value = temp != 0;
       return true;
     }
    @@ -223,10 +226,11 @@ inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
     }
     
     template 
    -inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused.
    -                                               uint32 tag,
    -                                               io::CodedInputStream* input,
    -                                               RepeatedField* values) {
    +inline bool WireFormatLite::ReadRepeatedPrimitive(
    +    int,  // tag_size, unused.
    +    uint32 tag,
    +    io::CodedInputStream* input,
    +    RepeatedField* values) {
       CType value;
       if (!ReadPrimitive(input, &value)) return false;
       values->Add(value);
    @@ -286,7 +290,7 @@ inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
       return true;
     }
     
    -// Specializations of ReadRepeatedPrimitive for the fixed size types, which use 
    +// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
     // the optimized code path.
     #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)             \
     template <>                                                                    \
    @@ -301,12 +305,12 @@ inline bool WireFormatLite::ReadRepeatedPrimitive<                             \
           tag_size, tag, input, values);                                           \
     }
     
    -READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
    -READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
    -READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
    -READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
    -READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
    -READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
    +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
    +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
    +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
    +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
    +READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
    +READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
     
     #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
     
    @@ -335,6 +339,86 @@ inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
       return true;
     }
     
    +template 
    +inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
    +    io::CodedInputStream* input, RepeatedField* values) {
    +  uint32 length;
    +  if (!input->ReadVarint32(&length)) return false;
    +  const uint32 old_entries = values->size();
    +  const uint32 new_entries = length / sizeof(CType);
    +  const uint32 new_bytes = new_entries * sizeof(CType);
    +  if (new_bytes != length) return false;
    +  // We would *like* to pre-allocate the buffer to write into (for
    +  // speed), but *must* avoid performing a very large allocation due
    +  // to a malicious user-supplied "length" above.  So we have a fast
    +  // path that pre-allocates when the "length" is less than a bound.
    +  // We determine the bound by calling BytesUntilTotalBytesLimit() and
    +  // BytesUntilLimit().  These return -1 to mean "no limit set".
    +  // There are four cases:
    +  // TotalBytesLimit  Limit
    +  // -1               -1     Use slow path.
    +  // -1               >= 0   Use fast path if length <= Limit.
    +  // >= 0             -1     Use slow path.
    +  // >= 0             >= 0   Use fast path if length <= min(both limits).
    +  int64 bytes_limit = input->BytesUntilTotalBytesLimit();
    +  if (bytes_limit == -1) {
    +    bytes_limit = input->BytesUntilLimit();
    +  } else {
    +    bytes_limit =
    +        min(bytes_limit, static_cast(input->BytesUntilLimit()));
    +  }
    +  if (bytes_limit >= new_bytes) {
    +    // Fast-path that pre-allocates *values to the final size.
    +#if defined(PROTOBUF_LITTLE_ENDIAN)
    +    values->Resize(old_entries + new_entries, 0);
    +    // values->mutable_data() may change after Resize(), so do this after:
    +    void* dest = reinterpret_cast(values->mutable_data() + old_entries);
    +    if (!input->ReadRaw(dest, new_bytes)) {
    +      values->Truncate(old_entries);
    +      return false;
    +    }
    +#else
    +    values->Reserve(old_entries + new_entries);
    +    CType value;
    +    for (uint32 i = 0; i < new_entries; ++i) {
    +      if (!ReadPrimitive(input, &value)) return false;
    +      values->AddAlreadyReserved(value);
    +    }
    +#endif
    +  } else {
    +    // This is the slow-path case where "length" may be too large to
    +    // safely allocate.  We read as much as we can into *values
    +    // without pre-allocating "length" bytes.
    +    CType value;
    +    for (uint32 i = 0; i < new_entries; ++i) {
    +      if (!ReadPrimitive(input, &value)) return false;
    +      values->Add(value);
    +    }
    +  }
    +  return true;
    +}
    +
    +// Specializations of ReadPackedPrimitive for the fixed size types, which use
    +// an optimized code path.
    +#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)      \
    +template <>                                                                    \
    +inline bool WireFormatLite::ReadPackedPrimitive<                               \
    +  CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
    +    io::CodedInputStream* input,                                               \
    +    RepeatedField* values) {                                          \
    +  return ReadPackedFixedSizePrimitive<                                         \
    +      CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values);                  \
    +}
    +
    +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
    +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
    +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
    +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
    +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
    +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
    +
    +#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
    +
     template 
     bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
                                                      RepeatedField* values) {
    @@ -662,15 +746,13 @@ inline uint8* WireFormatLite::WriteStringToArray(int field_number,
       //   WriteString() to avoid code duplication.  If the implementations become
       //   different, you will need to update that usage.
       target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
    -  target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
    -  return io::CodedOutputStream::WriteStringToArray(value, target);
    +  return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
     }
     inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
                                                     const string& value,
                                                     uint8* target) {
       target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
    -  target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
    -  return io::CodedOutputStream::WriteStringToArray(value, target);
    +  return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
     }
     
     
    @@ -750,8 +832,7 @@ inline int WireFormatLite::GroupSize(const MessageLite& value) {
       return value.ByteSize();
     }
     inline int WireFormatLite::MessageSize(const MessageLite& value) {
    -  int size = value.ByteSize();
    -  return io::CodedOutputStream::VarintSize32(size) + size;
    +  return LengthDelimitedSize(value.ByteSize());
     }
     
     // See comment on ReadGroupNoVirtual to understand the need for this template
    @@ -764,8 +845,12 @@ inline int WireFormatLite::GroupSizeNoVirtual(
     template
     inline int WireFormatLite::MessageSizeNoVirtual(
         const MessageType_WorkAroundCppLookupDefect& value) {
    -  int size = value.MessageType_WorkAroundCppLookupDefect::ByteSize();
    -  return io::CodedOutputStream::VarintSize32(size) + size;
    +  return LengthDelimitedSize(
    +      value.MessageType_WorkAroundCppLookupDefect::ByteSize());
    +}
    +
    +inline int WireFormatLite::LengthDelimitedSize(int length) {
    +  return io::CodedOutputStream::VarintSize32(length) + length;
     }
     
     }  // namespace internal
    diff --git a/toolkit/components/protobuf/update.sh b/toolkit/components/protobuf/update.sh
    deleted file mode 100644
    index 3472a76fe1e2..000000000000
    --- a/toolkit/components/protobuf/update.sh
    +++ /dev/null
    @@ -1,2 +0,0 @@
    -#!/bin/sh
    -patch -p1 < r512.patch
    diff --git a/toolkit/components/protobuf/upgrade_protobuf.sh b/toolkit/components/protobuf/upgrade_protobuf.sh
    new file mode 100755
    index 000000000000..bdaa4ce6338e
    --- /dev/null
    +++ b/toolkit/components/protobuf/upgrade_protobuf.sh
    @@ -0,0 +1,71 @@
    +#!/usr/bin/env bash
    +
    +set -e
    +
    +usage() {
    +    echo "Usage: upgrade_protobuf.sh path/to/protobuf"
    +    echo
    +    echo "    Upgrades mozilla-central's copy of the protobuf library."
    +    echo
    +    echo "    Get a protobuf release from here:"
    +    echo "    https://github.com/google/protobuf/releases"
    +}
    +
    +if [[ "$#" -ne 1 ]]; then
    +    usage
    +    exit 1
    +fi
    +
    +PROTOBUF_LIB_PATH=$1
    +
    +if [[ ! -d "$PROTOBUF_LIB_PATH" ]]; then
    +    echo No such directory: $PROTOBUF_LIB_PATH
    +    echo
    +    usage
    +    exit 1
    +fi
    +
    +realpath() {
    +    if [[ $1 = /* ]]; then
    +        echo "$1"
    +    else
    +        echo "$PWD/${1#./}"
    +    fi
    +}
    +
    +PROTOBUF_LIB_PATH=$(realpath $PROTOBUF_LIB_PATH)
    +
    +cd $(dirname $0)
    +
    +# Remove the old protobuf sources.
    +rm -rf src/google/*
    +
    +# Add all the new protobuf sources.
    +cp -r $PROTOBUF_LIB_PATH/src/google/* src/google/
    +
    +# Remove compiler sources.
    +rm -rf src/google/protobuf/compiler
    +
    +# Remove test files.
    +find src/google -name '*test*' | xargs rm -rf
    +
    +# Remove protobuf's build files.
    +find src/google/ -name '.deps' | xargs rm -rf
    +find src/google/ -name '.dirstamp' | xargs rm -rf
    +rm -rf src/google/protobuf/SEBS
    +
    +# Apply custom changes for building as part of mozilla-central.
    +
    +cd ../../.. # Top level.
    +
    +echo
    +echo Applying custom changes for mozilla-central. If this fails, you need to
    +echo edit the 'toolkit/components/protobuf/src/google/*' sources manually and
    +echo update the 'toolkit/components/protobuf/m-c-changes.patch' patch file
    +echo accordingly.
    +echo
    +
    +patch -p1 < toolkit/components/protobuf/m-c-changes.patch
    +
    +echo
    +echo Successfully upgraded the protobuf lib!
    diff --git a/toolkit/components/protobuf/vs2013.patch b/toolkit/components/protobuf/vs2013.patch
    deleted file mode 100644
    index f14f00060f37..000000000000
    --- a/toolkit/components/protobuf/vs2013.patch
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -diff --git a/toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h b/toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h
    ---- a/toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h
    -+++ b/toolkit/components/protobuf/google/protobuf/wire_format_lite_inl.h
    -@@ -31,16 +31,17 @@
    - // Author: kenton@google.com (Kenton Varda)
    - //         wink@google.com (Wink Saville) (refactored from wire_format.h)
    - //  Based on original Protocol Buffers design by
    - //  Sanjay Ghemawat, Jeff Dean, and others.
    - 
    - #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
    - #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
    - 
    -+#include 
    - #include 
    - #include 
    - #include 
    - #include 
    - #include 
    - #include 
    - #include 
    - 
    
    From 5f8c8f100a304229d9a3630d0b6649a8db4c4e4b Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:54 -0700
    Subject: [PATCH 213/241] Bug 1024774 - Part 1: Add the ChromeUtils WebIDL
     interface. r=bholley
    
    ---
     dom/bindings/Bindings.conf    |  8 +++++
     dom/webidl/ChromeUtils.webidl | 55 +++++++++++++++++++++++++++++++++++
     dom/webidl/moz.build          |  1 +
     3 files changed, 64 insertions(+)
     create mode 100644 dom/webidl/ChromeUtils.webidl
    
    diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
    index f6f249284b5c..72415e1e3fbd 100644
    --- a/dom/bindings/Bindings.conf
    +++ b/dom/bindings/Bindings.conf
    @@ -262,6 +262,14 @@ DOMInterfaces = {
         'concrete': False
     },
     
    +'ChromeUtils': {
    +    # The codegen is dumb, and doesn't understand that this interface is only a
    +    # collection of static methods, so we have this `concrete: False` hack.
    +    'concrete': False,
    +    'nativeType': 'mozilla::devtools::ChromeUtils',
    +    'implicitJSContext': ['saveHeapSnapshot']
    +},
    +
     'ChromeWindow': {
         'concrete': False,
     },
    diff --git a/dom/webidl/ChromeUtils.webidl b/dom/webidl/ChromeUtils.webidl
    new file mode 100644
    index 000000000000..43ab2b7dd9f4
    --- /dev/null
    +++ b/dom/webidl/ChromeUtils.webidl
    @@ -0,0 +1,55 @@
    +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
    + * You can obtain one at http://mozilla.org/MPL/2.0/.
    + */
    +
    +/**
    + * A collection of static utility methods that are only exposed to Chrome.
    + */
    +[ChromeOnly, Exposed=(Window,System)]
    +interface ChromeUtils {
    +  /**
    +   * Serialize a snapshot of the heap graph, as seen by |JS::ubi::Node| and
    +   * restricted by |boundaries|, and write it to the provided file path.
    +   *
    +   * @param filePath          The file path to write the heap snapshot to.
    +   *
    +   * @param boundaries        The portion of the heap graph to write.
    +   */
    +  [Throws]
    +  static void saveHeapSnapshot(DOMString filePath,
    +                               optional HeapSnapshotBoundaries boundaries);
    +};
    +
    +/**
    + * A JS object whose properties specify what portion of the heap graph to
    + * write. The recognized properties are:
    + *
    + * * globals: [ global, ... ]
    + *   Dump only nodes that either:
    + *   - belong in the compartment of one of the given globals;
    + *   - belong to no compartment, but do belong to a Zone that contains one of
    + *     the given globals;
    + *   - are referred to directly by one of the last two kinds of nodes; or
    + *   - is the fictional root node, described below.
    + *
    + * * debugger: Debugger object
    + *   Like "globals", but use the Debugger's debuggees as the globals.
    + *
    + * * runtime: true
    + *   Dump the entire heap graph, starting with the JSRuntime's roots.
    + *
    + * One, and only one, of these properties must exist on the boundaries object.
    + *
    + * The root of the dumped graph is a fictional node whose ubi::Node type name is
    + * "CoreDumpRoot". If we are dumping the entire ubi::Node graph, this root node
    + * has an edge for each of the JSRuntime's roots. If we are dumping a selected
    + * set of globals, the root has an edge to each global, and an edge for each
    + * incoming JS reference to the selected Zones.
    + */
    +dictionary HeapSnapshotBoundaries {
    +  sequence globals;
    +  object           debugger;
    +  boolean          runtime;
    +};
    diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
    index b272700cf671..5a4ff936dab3 100644
    --- a/dom/webidl/moz.build
    +++ b/dom/webidl/moz.build
    @@ -73,6 +73,7 @@ WEBIDL_FILES = [
         'CharacterData.webidl',
         'ChildNode.webidl',
         'ChromeNotifications.webidl',
    +    'ChromeUtils.webidl',
         'Client.webidl',
         'Clients.webidl',
         'ClipboardEvent.webidl',
    
    From 26904e13eae5f87ec18a9f2982cb6a114143f6a6 Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:54 -0700
    Subject: [PATCH 214/241] Bug 1024774 - Part 2: Implement a
     google::protobuf::ZeroCopyOutputStream wrapper around nsIOutputStream; r=jimb
    
    ---
     .../server/ZeroCopyNSIOutputStream.cpp        | 99 +++++++++++++++++++
     .../devtools/server/ZeroCopyNSIOutputStream.h | 70 +++++++++++++
     toolkit/devtools/server/moz.build             |  5 +
     3 files changed, 174 insertions(+)
     create mode 100644 toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp
     create mode 100644 toolkit/devtools/server/ZeroCopyNSIOutputStream.h
    
    diff --git a/toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp b/toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp
    new file mode 100644
    index 000000000000..41e85923eba1
    --- /dev/null
    +++ b/toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp
    @@ -0,0 +1,99 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +#include "mozilla/devtools/ZeroCopyNSIOutputStream.h"
    +
    +#include "mozilla/DebugOnly.h"
    +
    +namespace mozilla {
    +namespace devtools {
    +
    +ZeroCopyNSIOutputStream::ZeroCopyNSIOutputStream(nsCOMPtr &out)
    +  : out(out)
    +  , result_(NS_OK)
    +  , amountUsed(0)
    +  , writtenCount(0)
    +{
    +  DebugOnly nonBlocking = false;
    +  MOZ_ASSERT(out->IsNonBlocking(&nonBlocking) == NS_OK);
    +  MOZ_ASSERT(!nonBlocking);
    +}
    +
    +ZeroCopyNSIOutputStream::~ZeroCopyNSIOutputStream()
    +{
    +  if (!failed())
    +    NS_WARN_IF(NS_FAILED(writeBuffer()));
    +}
    +
    +nsresult
    +ZeroCopyNSIOutputStream::writeBuffer()
    +{
    +  if (failed())
    +    return result_;
    +
    +  if (amountUsed == 0)
    +    return NS_OK;
    +
    +  int32_t amountWritten = 0;
    +  while (amountWritten < amountUsed) {
    +    uint32_t justWritten = 0;
    +
    +    result_ = out->Write(buffer + amountWritten,
    +                         amountUsed - amountWritten,
    +                         &justWritten);
    +    if (NS_WARN_IF(NS_FAILED(result_)))
    +      return result_;
    +
    +    amountWritten += justWritten;
    +  }
    +
    +  writtenCount += amountUsed;
    +  amountUsed = 0;
    +  return NS_OK;
    +}
    +
    +// ZeroCopyOutputStream Interface
    +
    +bool
    +ZeroCopyNSIOutputStream::Next(void **data, int *size)
    +{
    +  MOZ_ASSERT(data != nullptr);
    +  MOZ_ASSERT(size != nullptr);
    +
    +  if (failed())
    +    return false;
    +
    +  if (amountUsed == BUFFER_SIZE) {
    +    if (NS_FAILED(writeBuffer()))
    +      return false;
    +  }
    +
    +  *data = buffer + amountUsed;
    +  *size = BUFFER_SIZE - amountUsed;
    +  amountUsed = BUFFER_SIZE;
    +  return true;
    +}
    +
    +void
    +ZeroCopyNSIOutputStream::BackUp(int count)
    +{
    +  MOZ_ASSERT(count > 0,
    +             "Must back up a positive number of bytes.");
    +  MOZ_ASSERT(amountUsed == BUFFER_SIZE,
    +             "Can only call BackUp directly after calling Next.");
    +  MOZ_ASSERT(count <= amountUsed,
    +             "Can't back up further than we've given out.");
    +
    +  amountUsed -= count;
    +}
    +
    +::google::protobuf::int64
    +ZeroCopyNSIOutputStream::ByteCount() const
    +{
    +  return writtenCount + amountUsed;
    +}
    +
    +} // namespace devtools
    +} // namespace mozilla
    diff --git a/toolkit/devtools/server/ZeroCopyNSIOutputStream.h b/toolkit/devtools/server/ZeroCopyNSIOutputStream.h
    new file mode 100644
    index 000000000000..80ec55dc6e0a
    --- /dev/null
    +++ b/toolkit/devtools/server/ZeroCopyNSIOutputStream.h
    @@ -0,0 +1,70 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +#ifndef mozilla_devtools_ZeroCopyNSIOutputStream__
    +#define mozilla_devtools_ZeroCopyNSIOutputStream__
    +
    +#include 
    +#include 
    +
    +#include "nsCOMPtr.h"
    +#include "nsIOutputStream.h"
    +
    +namespace mozilla {
    +namespace devtools {
    +
    +// A `google::protobuf::io::ZeroCopyOutputStream` implementation that uses an
    +// `nsIOutputStream` under the covers.
    +//
    +// This class will automatically write and flush its data to the
    +// `nsIOutputStream` in its destructor, but if you care whether that call
    +// succeeds or fails, then you should call the `flush` method yourself. Errors
    +// will be logged, however.
    +class MOZ_STACK_CLASS ZeroCopyNSIOutputStream
    +  : public ::google::protobuf::io::ZeroCopyOutputStream
    +{
    +  static const int BUFFER_SIZE = 8192;
    +
    +  // The nsIOutputStream we are streaming to.
    +  nsCOMPtr &out;
    +
    +  // The buffer we write data to before passing it to the output stream.
    +  char buffer[BUFFER_SIZE];
    +
    +  // The status of writing to the underlying output stream.
    +  nsresult result_;
    +
    +  // The number of bytes in the buffer that have been used thus far.
    +  int amountUsed;
    +
    +  // Excluding the amount of the buffer currently used (which hasn't been
    +  // written and flushed yet), this is the number of bytes written to the output
    +  // stream.
    +  int64_t writtenCount;
    +
    +  // Write the internal buffer to the output stream and flush it.
    +  nsresult writeBuffer();
    +
    +public:
    +  explicit ZeroCopyNSIOutputStream(nsCOMPtr &out);
    +
    +  nsresult flush() { return writeBuffer(); }
    +
    +  // Return true if writing to the underlying output stream ever failed.
    +  bool failed() const { return NS_FAILED(result_); }
    +
    +  nsresult result() const { return result_; }
    +
    +  // ZeroCopyOutputStream Interface
    +  virtual ~ZeroCopyNSIOutputStream() override;
    +  virtual bool Next(void **data, int *size) override;
    +  virtual void BackUp(int count) override;
    +  virtual ::google::protobuf::int64 ByteCount() const override;
    +};
    +
    +} // namespace devtools
    +} // namespace mozilla
    +
    +#endif // mozilla_devtools_ZeroCopyNSIOutputStream__
    diff --git a/toolkit/devtools/server/moz.build b/toolkit/devtools/server/moz.build
    index f2cd973a1012..5ccde2952b8b 100644
    --- a/toolkit/devtools/server/moz.build
    +++ b/toolkit/devtools/server/moz.build
    @@ -14,8 +14,13 @@ XPIDL_SOURCES += [
     
     XPIDL_MODULE = 'jsinspector'
     
    +EXPORTS.mozilla.devtools += [
    +    'ZeroCopyNSIOutputStream.h',
    +]
    +
     SOURCES += [
         'nsJSInspector.cpp',
    +    'ZeroCopyNSIOutputStream.cpp',
     ]
     
     FINAL_LIBRARY = 'xul'
    
    From 32af3e9ef80af6429fd1d6310276bf48e7015f1c Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:54 -0700
    Subject: [PATCH 215/241] Bug 1024774 - Part 3: Serialize heap snapshots.
     r=jimb
    
    ---
     js/public/Debug.h                             |   15 +-
     js/public/UbiNode.h                           |   50 +-
     js/public/UbiNodeTraverse.h                   |    2 +-
     js/src/jsfriendapi.cpp                        |    6 +
     js/src/jsfriendapi.h                          |    3 +
     js/src/vm/Debugger-inl.h                      |    2 +-
     js/src/vm/Debugger.cpp                        |   25 +-
     js/src/vm/Debugger.h                          |    5 +-
     js/src/vm/DebuggerMemory.cpp                  |   11 +-
     js/src/vm/UbiNode.cpp                         |   24 +-
     toolkit/devtools/server/ChromeUtils.cpp       |  386 +++++++
     toolkit/devtools/server/ChromeUtils.h         |   72 ++
     toolkit/devtools/server/CoreDump.pb.cc        | 1005 +++++++++++++++++
     toolkit/devtools/server/CoreDump.pb.h         |  643 +++++++++++
     toolkit/devtools/server/CoreDump.proto        |   69 ++
     .../server/generate-core-dump-sources.sh      |   26 +
     toolkit/devtools/server/moz.build             |    7 +
     17 files changed, 2312 insertions(+), 39 deletions(-)
     create mode 100644 toolkit/devtools/server/ChromeUtils.cpp
     create mode 100644 toolkit/devtools/server/ChromeUtils.h
     create mode 100644 toolkit/devtools/server/CoreDump.pb.cc
     create mode 100644 toolkit/devtools/server/CoreDump.pb.h
     create mode 100644 toolkit/devtools/server/CoreDump.proto
     create mode 100755 toolkit/devtools/server/generate-core-dump-sources.sh
    
    diff --git a/js/public/Debug.h b/js/public/Debug.h
    index bafd6ce2154e..3ba915fb55a1 100644
    --- a/js/public/Debug.h
    +++ b/js/public/Debug.h
    @@ -262,7 +262,13 @@ class BuilderOrigin : public Builder {
     
     // Tell Debuggers in |runtime| to use |mallocSizeOf| to find the size of
     // malloc'd blocks.
    -void SetDebuggerMallocSizeOf(JSRuntime* runtime, mozilla::MallocSizeOf mallocSizeOf);
    +JS_PUBLIC_API(void)
    +SetDebuggerMallocSizeOf(JSRuntime* runtime, mozilla::MallocSizeOf mallocSizeOf);
    +
    +// Get the MallocSizeOf function that the given runtime is using to find the
    +// size of malloc'd blocks.
    +JS_PUBLIC_API(mozilla::MallocSizeOf)
    +GetDebuggerMallocSizeOf(JSRuntime* runtime);
     
     
     
    @@ -316,7 +322,12 @@ onPromiseSettled(JSContext* cx, HandleObject promise);
     
     // Return true if the given value is a Debugger object, false otherwise.
     JS_PUBLIC_API(bool)
    -IsDebugger(JS::Value val);
    +IsDebugger(const JSObject &obj);
    +
    +// Append each of the debuggee global objects observed by the Debugger object
    +// |dbgObj| to |vector|. Returns true on success, false on failure.
    +JS_PUBLIC_API(bool)
    +GetDebuggeeGlobals(JSContext *cx, const JSObject &dbgObj, AutoObjectVector &vector);
     
     } // namespace dbg
     } // namespace JS
    diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h
    index dadeed3c33d8..e17690e89fac 100644
    --- a/js/public/UbiNode.h
    +++ b/js/public/UbiNode.h
    @@ -251,8 +251,8 @@ struct Concrete {
         static void construct(void* storage, Referent* referent);
     };
     
    -// A container for a Base instance; all members simply forward to the contained instance.
    -// This container allows us to pass ubi::Node instances by value.
    +// A container for a Base instance; all members simply forward to the contained
    +// instance.  This container allows us to pass ubi::Node instances by value.
     class Node {
         // Storage in which we allocate Base subclasses.
         mozilla::AlignedStorage2 storage;
    @@ -356,6 +356,21 @@ class Node {
             return base()->edges(cx, wantNames);
         }
     
    +    // An identifier for this node, guaranteed to be stable and unique for as
    +    // long as this ubi::Node's referent is alive and at the same address.
    +    //
    +    // This is probably suitable for use in serializations, as it is an integral
    +    // type. It may also help save memory when constructing HashSets of
    +    // ubi::Nodes: since a uintptr_t will always be smaller than a ubi::Node, a
    +    // HashSet will use less space per element than a
    +    // HashSet.
    +    //
    +    // (Note that 'unique' only means 'up to equality on ubi::Node'; see the
    +    // caveats about multiple objects allocated at the same address for
    +    // 'ubi::Node::operator=='.)
    +    typedef uintptr_t Id;
    +    Id identifier() const { return reinterpret_cast(base()->ptr); }
    +
         // A hash policy for ubi::Nodes.
         // This simply uses the stock PointerHasher on the ubi::Node's pointer.
         // We specialize DefaultHasher below to make this the default.
    @@ -475,6 +490,33 @@ class SimpleEdge : public Edge {
     
     typedef mozilla::Vector SimpleEdgeVector;
     
    +// An EdgeRange concrete class that holds a pre-existing vector of
    +// SimpleEdges. A PreComputedEdgeRange does not take ownership of its
    +// SimpleEdgeVector; it is up to the PreComputedEdgeRange's consumer to manage
    +// that lifetime.
    +class PreComputedEdgeRange : public EdgeRange {
    +    SimpleEdgeVector& edges;
    +    size_t            i;
    +
    +    void settle() {
    +        front_ = i < edges.length() ? &edges[i] : nullptr;
    +    }
    +
    +  public:
    +    explicit PreComputedEdgeRange(JSContext* cx, SimpleEdgeVector& edges)
    +      : edges(edges),
    +        i(0)
    +    {
    +        settle();
    +    }
    +
    +    void popFront() override {
    +        MOZ_ASSERT(!empty());
    +        i++;
    +        settle();
    +    }
    +};
    +
     
     // RootList is a class that can be pointed to by a |ubi::Node|, creating a
     // fictional root-of-roots which has edges to every GC root in the JS
    @@ -521,6 +563,10 @@ class MOZ_STACK_CLASS RootList {
         // Find only GC roots in the given Debugger object's set of debuggee zones.
         bool init(HandleObject debuggees);
     
    +    // Returns true if the RootList has been initialized successfully, false
    +    // otherwise.
    +    bool initialized() { return noGC.isSome(); }
    +
         // Explicitly add the given Node as a root in this RootList. If wantNames is
         // true, you must pass an edgeName. The RootList does not take ownership of
         // edgeName.
    diff --git a/js/public/UbiNodeTraverse.h b/js/public/UbiNodeTraverse.h
    index 159de27e7d5c..5d8650f04719 100644
    --- a/js/public/UbiNodeTraverse.h
    +++ b/js/public/UbiNodeTraverse.h
    @@ -120,7 +120,7 @@ struct BreadthFirst {
             MOZ_ASSERT(!traversalBegun);
             traversalBegun = true;
     
    -        // While there are pending nodes, visit them, until we've found a path to the target.
    +        // While there are pending nodes, visit them.
             while (!pending.empty()) {
                 Node origin = pending.front();
                 pending.popFront();
    diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp
    index 4f7edf4d72da..e5d403594248 100644
    --- a/js/src/jsfriendapi.cpp
    +++ b/js/src/jsfriendapi.cpp
    @@ -295,6 +295,12 @@ js::IsAtomsCompartment(JSCompartment* comp)
         return comp->runtimeFromAnyThread()->isAtomsCompartment(comp);
     }
     
    +JS_FRIEND_API(bool)
    +js::IsAtomsZone(JS::Zone* zone)
    +{
    +    return zone->runtimeFromAnyThread()->isAtomsZone(zone);
    +}
    +
     JS_FRIEND_API(bool)
     js::IsInNonStrictPropertySet(JSContext* cx)
     {
    diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h
    index 6515947ea3b9..409618a8a166 100644
    --- a/js/src/jsfriendapi.h
    +++ b/js/src/jsfriendapi.h
    @@ -473,6 +473,9 @@ IsSystemZone(JS::Zone* zone);
     extern JS_FRIEND_API(bool)
     IsAtomsCompartment(JSCompartment* comp);
     
    +extern JS_FRIEND_API(bool)
    +IsAtomsZone(JS::Zone *zone);
    +
     /*
      * Returns whether we're in a non-strict property set (in that we're in a
      * non-strict script and the bytecode we're on is a property set).  The return
    diff --git a/js/src/vm/Debugger-inl.h b/js/src/vm/Debugger-inl.h
    index 007267b3be5d..73ca6b2caf9e 100644
    --- a/js/src/vm/Debugger-inl.h
    +++ b/js/src/vm/Debugger-inl.h
    @@ -27,7 +27,7 @@ js::Debugger::onLeaveFrame(JSContext* cx, AbstractFramePtr frame, bool ok)
     }
     
     /* static */ inline js::Debugger*
    -js::Debugger::fromJSObject(JSObject* obj)
    +js::Debugger::fromJSObject(const JSObject* obj)
     {
         MOZ_ASSERT(js::GetObjectClass(obj) == &jsclass);
         return (Debugger*) obj->as().getPrivate();
    diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
    index 46eb86dbaf4d..4dae4b37326d 100644
    --- a/js/src/vm/Debugger.cpp
    +++ b/js/src/vm/Debugger.cpp
    @@ -7882,16 +7882,27 @@ JS::dbg::onPromiseSettled(JSContext* cx, HandleObject promise)
     }
     
     JS_PUBLIC_API(bool)
    -JS::dbg::IsDebugger(JS::Value val)
    +JS::dbg::IsDebugger(const JSObject &obj)
     {
    -    if (!val.isObject())
    -        return false;
    +    return js::GetObjectClass(&obj) == &Debugger::jsclass &&
    +           js::Debugger::fromJSObject(&obj) != nullptr;
    +}
     
    -    JSObject& obj = val.toObject();
    -    if (obj.getClass() != &Debugger::jsclass)
    -        return false;
    +JS_PUBLIC_API(bool)
    +JS::dbg::GetDebuggeeGlobals(JSContext *cx, const JSObject &dbgObj, AutoObjectVector &vector)
    +{
    +    MOZ_ASSERT(IsDebugger(dbgObj));
    +    js::Debugger *dbg = js::Debugger::fromJSObject(&dbgObj);
     
    -    return js::Debugger::fromJSObject(&obj) != nullptr;
    +    if (!vector.reserve(vector.length() + dbg->debuggees.count())) {
    +        JS_ReportOutOfMemory(cx);
    +        return false;
    +    }
    +
    +    for (WeakGlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront())
    +        vector.infallibleAppend(static_cast(r.front()));
    +
    +    return true;
     }
     
     
    diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
    index a9e664402ca3..1a9af15ad0df 100644
    --- a/js/src/vm/Debugger.h
    +++ b/js/src/vm/Debugger.h
    @@ -188,7 +188,8 @@ class Debugger : private mozilla::LinkedListElement
         friend class SavedStacks;
         friend class mozilla::LinkedListElement;
         friend bool (::JS_DefineDebuggerObject)(JSContext* cx, JS::HandleObject obj);
    -    friend bool (::JS::dbg::IsDebugger)(JS::Value val);
    +    friend bool (::JS::dbg::IsDebugger)(const JSObject&);
    +    friend bool (::JS::dbg::GetDebuggeeGlobals)(JSContext*, const JSObject&, AutoObjectVector&);
         friend JSObject* SavedStacksMetadataCallback(JSContext* cx);
         friend void JS::dbg::onNewPromise(JSContext* cx, HandleObject promise);
         friend void JS::dbg::onPromiseSettled(JSContext* cx, HandleObject promise);
    @@ -597,7 +598,7 @@ class Debugger : private mozilla::LinkedListElement
         bool init(JSContext* cx);
         inline const js::HeapPtrNativeObject& toJSObject() const;
         inline js::HeapPtrNativeObject& toJSObjectRef();
    -    static inline Debugger* fromJSObject(JSObject* obj);
    +    static inline Debugger* fromJSObject(const JSObject* obj);
         static Debugger* fromChildJSObject(JSObject* obj);
     
         bool hasMemory() const;
    diff --git a/js/src/vm/DebuggerMemory.cpp b/js/src/vm/DebuggerMemory.cpp
    index 5d5a59a4a4c4..b459546def0d 100644
    --- a/js/src/vm/DebuggerMemory.cpp
    +++ b/js/src/vm/DebuggerMemory.cpp
    @@ -319,11 +319,18 @@ DebuggerMemory::setOnGarbageCollection(JSContext* cx, unsigned argc, Value* vp)
     
     /* Debugger.Memory.prototype.takeCensus */
     
    -void
    -JS::dbg::SetDebuggerMallocSizeOf(JSRuntime* rt, mozilla::MallocSizeOf mallocSizeOf) {
    +JS_PUBLIC_API(void)
    +JS::dbg::SetDebuggerMallocSizeOf(JSRuntime* rt, mozilla::MallocSizeOf mallocSizeOf)
    +{
         rt->debuggerMallocSizeOf = mallocSizeOf;
     }
     
    +JS_PUBLIC_API(mozilla::MallocSizeOf)
    +JS::dbg::GetDebuggerMallocSizeOf(JSRuntime *rt)
    +{
    +    return rt->debuggerMallocSizeOf;
    +}
    +
     namespace js {
     namespace dbg {
     
    diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp
    index 576e9be08a7c..d42b985d2de2 100644
    --- a/js/src/vm/UbiNode.cpp
    +++ b/js/src/vm/UbiNode.cpp
    @@ -319,8 +319,8 @@ RootList::init(ZoneSet& debuggees)
     bool
     RootList::init(HandleObject debuggees)
     {
    -    MOZ_ASSERT(debuggees && JS::dbg::IsDebugger(ObjectValue(*debuggees)));
    -    js::Debugger* dbg = js::Debugger::fromJSObject(debuggees);
    +    MOZ_ASSERT(debuggees && JS::dbg::IsDebugger(*debuggees));
    +    js::Debugger* dbg = js::Debugger::fromJSObject(debuggees.get());
     
         ZoneSet debuggeeZones;
         if (!debuggeeZones.init())
    @@ -362,26 +362,6 @@ RootList::addRoot(Node node, const char16_t* edgeName)
         return edges.append(mozilla::Move(SimpleEdge(name.release(), node)));
     }
     
    -// An EdgeRange concrete class that holds a pre-existing vector of SimpleEdges.
    -class PreComputedEdgeRange : public EdgeRange {
    -    SimpleEdgeVector& edges;
    -    size_t           i;
    -
    -    void settle() {
    -        front_ = i < edges.length() ? &edges[i] : nullptr;
    -    }
    -
    -  public:
    -    explicit PreComputedEdgeRange(JSContext* cx, SimpleEdgeVector& edges)
    -      : edges(edges),
    -        i(0)
    -    {
    -        settle();
    -    }
    -
    -    void popFront() override { i++; settle(); }
    -};
    -
     const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("RootList");
     
     UniquePtr
    diff --git a/toolkit/devtools/server/ChromeUtils.cpp b/toolkit/devtools/server/ChromeUtils.cpp
    new file mode 100644
    index 000000000000..7d13abd015ae
    --- /dev/null
    +++ b/toolkit/devtools/server/ChromeUtils.cpp
    @@ -0,0 +1,386 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +#include "ChromeUtils.h"
    +
    +#include 
    +#include 
    +
    +#include "mozilla/devtools/HeapSnapshot.h"
    +#include "mozilla/devtools/ZeroCopyNSIOutputStream.h"
    +#include "mozilla/Attributes.h"
    +#include "mozilla/UniquePtr.h"
    +
    +#include "nsCRTGlue.h"
    +#include "nsIOutputStream.h"
    +#include "nsNetUtil.h"
    +#include "prerror.h"
    +#include "prio.h"
    +#include "prtypes.h"
    +
    +#include "js/Debug.h"
    +#include "js/UbiNodeTraverse.h"
    +
    +namespace mozilla {
    +namespace devtools {
    +
    +using namespace JS;
    +using namespace dom;
    +
    +
    +// If we are only taking a snapshot of the heap affected by the given set of
    +// globals, find the set of zones the globals are allocated within. Returns
    +// false on OOM failure.
    +static bool
    +PopulateZonesWithGlobals(ZoneSet &zones, AutoObjectVector &globals)
    +{
    +  if (!zones.init())
    +    return false;
    +
    +  unsigned length = globals.length();
    +  for (unsigned i = 0; i < length; i++) {
    +    if (!zones.put(GetTenuredGCThingZone(globals[i])))
    +      return false;
    +  }
    +
    +  return true;
    +}
    +
    +// Add the given set of globals as explicit roots in the given roots
    +// list. Returns false on OOM failure.
    +static bool
    +AddGlobalsAsRoots(AutoObjectVector &globals, ubi::RootList &roots)
    +{
    +  unsigned length = globals.length();
    +  for (unsigned i = 0; i < length; i++) {
    +    if (!roots.addRoot(ubi::Node(globals[i].get()),
    +                       MOZ_UTF16("heap snapshot global")))
    +    {
    +      return false;
    +    }
    +  }
    +  return true;
    +}
    +
    +// Choose roots and limits for a traversal, given `boundaries`. Set `roots` to
    +// the set of nodes within the boundaries that are referred to by nodes
    +// outside. If `boundaries` does not include all JS zones, initialize `zones` to
    +// the set of included zones; otherwise, leave `zones` uninitialized. (You can
    +// use zones.initialized() to check.)
    +//
    +// If `boundaries` is incoherent, or we encounter an error while trying to
    +// handle it, or we run out of memory, set `rv` appropriately and return
    +// `false`.
    +static bool
    +EstablishBoundaries(JSContext *cx,
    +                    ErrorResult &rv,
    +                    const HeapSnapshotBoundaries &boundaries,
    +                    ubi::RootList &roots,
    +                    ZoneSet &zones)
    +{
    +  MOZ_ASSERT(!roots.initialized());
    +  MOZ_ASSERT(!zones.initialized());
    +
    +  bool foundBoundaryProperty = false;
    +
    +  if (boundaries.mRuntime.WasPassed()) {
    +    foundBoundaryProperty = true;
    +
    +    if (!boundaries.mRuntime.Value()) {
    +      rv.Throw(NS_ERROR_INVALID_ARG);
    +      return false;
    +    }
    +
    +    if (!roots.init()) {
    +      rv.Throw(NS_ERROR_OUT_OF_MEMORY);
    +      return false;
    +    }
    +  }
    +
    +  if (boundaries.mDebugger.WasPassed()) {
    +    if (foundBoundaryProperty) {
    +      rv.Throw(NS_ERROR_INVALID_ARG);
    +      return false;
    +    }
    +    foundBoundaryProperty = true;
    +
    +    JSObject *dbgObj = boundaries.mDebugger.Value();
    +    if (!dbgObj || !dbg::IsDebugger(*dbgObj)) {
    +      rv.Throw(NS_ERROR_INVALID_ARG);
    +      return false;
    +    }
    +
    +    AutoObjectVector globals(cx);
    +    if (!dbg::GetDebuggeeGlobals(cx, *dbgObj, globals) ||
    +        !PopulateZonesWithGlobals(zones, globals) ||
    +        !roots.init(zones) ||
    +        !AddGlobalsAsRoots(globals, roots))
    +    {
    +      rv.Throw(NS_ERROR_OUT_OF_MEMORY);
    +      return false;
    +    }
    +  }
    +
    +  if (boundaries.mGlobals.WasPassed()) {
    +    if (foundBoundaryProperty) {
    +      rv.Throw(NS_ERROR_INVALID_ARG);
    +      return false;
    +    }
    +    foundBoundaryProperty = true;
    +
    +    uint32_t length = boundaries.mGlobals.Value().Length();
    +    if (length == 0) {
    +      rv.Throw(NS_ERROR_INVALID_ARG);
    +      return false;
    +    }
    +
    +    AutoObjectVector globals(cx);
    +    for (uint32_t i = 0; i < length; i++) {
    +      JSObject *global = boundaries.mGlobals.Value().ElementAt(i);
    +      if (!JS_IsGlobalObject(global)) {
    +        rv.Throw(NS_ERROR_INVALID_ARG);
    +        return false;
    +      }
    +      if (!globals.append(global)) {
    +        rv.Throw(NS_ERROR_OUT_OF_MEMORY);
    +        return false;
    +      }
    +    }
    +
    +    if (!PopulateZonesWithGlobals(zones, globals) ||
    +        !roots.init(zones) ||
    +        !AddGlobalsAsRoots(globals, roots))
    +    {
    +      rv.Throw(NS_ERROR_OUT_OF_MEMORY);
    +      return false;
    +    }
    +  }
    +
    +  if (!foundBoundaryProperty) {
    +    rv.Throw(NS_ERROR_INVALID_ARG);
    +    return false;
    +  }
    +
    +  MOZ_ASSERT(roots.initialized());
    +  MOZ_ASSERT_IF(boundaries.mDebugger.WasPassed(), zones.initialized());
    +  MOZ_ASSERT_IF(boundaries.mGlobals.WasPassed(), zones.initialized());
    +  return true;
    +}
    +
    +
    +// A `CoreDumpWriter` that serializes nodes to protobufs and writes them to
    +// the given `CodedOutputStream`.
    +class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter
    +{
    +  JSContext *cx;
    +  bool      wantNames;
    +
    +  ::google::protobuf::io::ZeroCopyOutputStream &stream;
    +
    +  bool writeMessage(const ::google::protobuf::MessageLite &message) {
    +    // We have to create a new CodedOutputStream when writing each message so
    +    // that the 64MB size limit used by Coded{Output,Input}Stream to prevent
    +    // integer overflow is enforced per message rather than on the whole stream.
    +    ::google::protobuf::io::CodedOutputStream codedStream(&stream);
    +    codedStream.WriteVarint32(message.ByteSize());
    +    message.SerializeWithCachedSizes(&codedStream);
    +    return !codedStream.HadError();
    +  }
    +
    +public:
    +  StreamWriter(JSContext *cx,
    +               ::google::protobuf::io::ZeroCopyOutputStream &stream,
    +               bool wantNames)
    +    : cx(cx)
    +    , wantNames(wantNames)
    +    , stream(stream)
    +  { }
    +
    +  ~StreamWriter() override { }
    +
    +  virtual bool writeMetadata(uint64_t timestamp) override {
    +    protobuf::Metadata metadata;
    +    metadata.set_timestamp(timestamp);
    +    return writeMessage(metadata);
    +  }
    +
    +  virtual bool writeNode(const JS::ubi::Node &ubiNode,
    +                         EdgePolicy includeEdges) override {
    +    protobuf::Node protobufNode;
    +    protobufNode.set_id(ubiNode.identifier());
    +
    +    const char16_t *typeName = ubiNode.typeName();
    +    size_t length = NS_strlen(typeName) * sizeof(char16_t);
    +    protobufNode.set_typename_(typeName, length);
    +
    +    JSRuntime *rt = JS_GetRuntime(cx);
    +    mozilla::MallocSizeOf mallocSizeOf = dbg::GetDebuggerMallocSizeOf(rt);
    +    MOZ_ASSERT(mallocSizeOf);
    +    protobufNode.set_size(ubiNode.size(mallocSizeOf));
    +
    +    if (includeEdges) {
    +      auto edges = ubiNode.edges(cx, wantNames);
    +      if (NS_WARN_IF(!edges))
    +        return false;
    +
    +      for ( ; !edges->empty(); edges->popFront()) {
    +        const ubi::Edge &ubiEdge = edges->front();
    +
    +        protobuf::Edge *protobufEdge = protobufNode.add_edges();
    +        if (NS_WARN_IF(!protobufEdge)) {
    +          return false;
    +        }
    +
    +        protobufEdge->set_referent(ubiEdge.referent.identifier());
    +
    +        if (wantNames && ubiEdge.name) {
    +          size_t length = NS_strlen(ubiEdge.name) * sizeof(char16_t);
    +          protobufEdge->set_name(ubiEdge.name, length);
    +        }
    +      }
    +    }
    +
    +    return writeMessage(protobufNode);
    +  }
    +};
    +
    +// A JS::ubi::BreadthFirst handler that serializes a snapshot of the heap into a
    +// core dump.
    +class MOZ_STACK_CLASS HeapSnapshotHandler {
    +  CoreDumpWriter& writer;
    +  JS::ZoneSet*   zones;
    +
    +public:
    +  HeapSnapshotHandler(CoreDumpWriter& writer,
    +                      JS::ZoneSet* zones)
    +    : writer(writer),
    +      zones(zones)
    +  { }
    +
    +  // JS::ubi::BreadthFirst handler interface.
    +
    +  class NodeData { };
    +  typedef JS::ubi::BreadthFirst Traversal;
    +  bool operator() (Traversal &traversal,
    +                   JS::ubi::Node origin,
    +                   const JS::ubi::Edge &edge,
    +                   NodeData *,
    +                   bool first)
    +  {
    +    // We're only interested in the first time we reach edge.referent, not in
    +    // every edge arriving at that node. "But, don't we want to serialize every
    +    // edge in the heap graph?" you ask. Don't worry! This edge is still
    +    // serialized into the core dump. Serializing a node also serializes each of
    +    // its edges, and if we are traversing a given edge, we must have already
    +    // visited and serialized the origin node and its edges.
    +    if (!first)
    +      return true;
    +
    +    const JS::ubi::Node &referent = edge.referent;
    +
    +    if (!zones)
    +      // We aren't targeting a particular set of zones, so serialize all the
    +      // things!
    +      return writer.writeNode(referent, CoreDumpWriter::INCLUDE_EDGES);
    +
    +    // We are targeting a particular set of zones. If this node is in our target
    +    // set, serialize it and all of its edges. If this node is _not_ in our
    +    // target set, we also serialize under the assumption that it is a shared
    +    // resource being used by something in our target zones since we reached it
    +    // by traversing the heap graph. However, we do not serialize its outgoing
    +    // edges and we abandon further traversal from this node.
    +
    +    JS::Zone *zone = referent.zone();
    +
    +    if (zones->has(zone))
    +      return writer.writeNode(referent, CoreDumpWriter::INCLUDE_EDGES);
    +
    +    traversal.abandonReferent();
    +    return writer.writeNode(referent, CoreDumpWriter::EXCLUDE_EDGES);
    +  }
    +};
    +
    +
    +bool
    +WriteHeapGraph(JSContext *cx,
    +               const JS::ubi::Node &node,
    +               CoreDumpWriter &writer,
    +               bool wantNames,
    +               JS::ZoneSet *zones,
    +               JS::AutoCheckCannotGC &noGC)
    +{
    +  // Serialize the starting node to the core dump.
    +
    +  if (NS_WARN_IF(!writer.writeNode(node, CoreDumpWriter::INCLUDE_EDGES))) {
    +    return false;
    +  }
    +
    +  // Walk the heap graph starting from the given node and serialize it into the
    +  // core dump.
    +
    +  HeapSnapshotHandler handler(writer, zones);
    +  HeapSnapshotHandler::Traversal traversal(cx, handler, noGC);
    +  if (!traversal.init())
    +    return false;
    +  traversal.wantNames = wantNames;
    +
    +  return traversal.addStartVisited(node) &&
    +    traversal.traverse();
    +}
    +
    +/* static */ void
    +ChromeUtils::SaveHeapSnapshot(GlobalObject &global,
    +                              JSContext *cx,
    +                              const nsAString &filePath,
    +                              const HeapSnapshotBoundaries &boundaries,
    +                              ErrorResult& rv)
    +{
    +  bool wantNames = true;
    +  ZoneSet zones;
    +  Maybe maybeNoGC;
    +  ubi::RootList rootList(cx, maybeNoGC, wantNames);
    +  if (!EstablishBoundaries(cx, rv, boundaries, rootList, zones))
    +    return;
    +
    +  MOZ_ASSERT(maybeNoGC.isSome());
    +  ubi::Node roots(&rootList);
    +
    +  nsCOMPtr file;
    +  rv = NS_NewLocalFile(filePath, false, getter_AddRefs(file));
    +  if (NS_WARN_IF(rv.Failed()))
    +    return;
    +
    +  nsCOMPtr outputStream;
    +  rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), file,
    +                                   PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
    +                                   -1, 0);
    +  if (NS_WARN_IF(rv.Failed()))
    +    return;
    +
    +  ZeroCopyNSIOutputStream zeroCopyStream(outputStream);
    +  ::google::protobuf::io::GzipOutputStream gzipStream(&zeroCopyStream);
    +
    +  StreamWriter writer(cx, gzipStream, wantNames);
    +
    +  // Serialize the initial heap snapshot metadata to the core dump.
    +  if (!writer.writeMetadata(PR_Now()) ||
    +      // Serialize the heap graph to the core dump, starting from our list of
    +      // roots.
    +      !WriteHeapGraph(cx,
    +                      roots,
    +                      writer,
    +                      wantNames,
    +                      zones.initialized() ? &zones : nullptr,
    +                      maybeNoGC.ref()))
    +    {
    +      rv.Throw(zeroCopyStream.failed()
    +               ? zeroCopyStream.result()
    +               : NS_ERROR_UNEXPECTED);
    +      return;
    +    }
    +}
    +
    +}
    +}
    diff --git a/toolkit/devtools/server/ChromeUtils.h b/toolkit/devtools/server/ChromeUtils.h
    new file mode 100644
    index 000000000000..211e755872f4
    --- /dev/null
    +++ b/toolkit/devtools/server/ChromeUtils.h
    @@ -0,0 +1,72 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +#ifndef mozilla_devtools_ChromeUtils__
    +#define mozilla_devtools_ChromeUtils__
    +
    +#include "CoreDump.pb.h"
    +#include "jsapi.h"
    +#include "jsfriendapi.h"
    +
    +#include "js/UbiNode.h"
    +#include "js/UbiNodeTraverse.h"
    +#include "mozilla/ErrorResult.h"
    +#include "mozilla/dom/BindingDeclarations.h"
    +#include "mozilla/dom/ChromeUtilsBinding.h"
    +
    +namespace mozilla {
    +namespace devtools {
    +
    +// A `CoreDumpWriter` is given the data we wish to save in a core dump and
    +// serializes it to disk, or memory, or a socket, etc.
    +class CoreDumpWriter
    +{
    +public:
    +  virtual ~CoreDumpWriter() { };
    +
    +  // Write the given bits of metadata we would like to associate with this core
    +  // dump.
    +  virtual bool writeMetadata(uint64_t timestamp) = 0;
    +
    +  enum EdgePolicy : bool {
    +    INCLUDE_EDGES = true,
    +    EXCLUDE_EDGES = false
    +  };
    +
    +  // Write the given `JS::ubi::Node` to the core dump. The given `EdgePolicy`
    +  // dictates whether its outgoing edges should also be written to the core
    +  // dump, or excluded.
    +  virtual bool writeNode(const JS::ubi::Node &node,
    +                         EdgePolicy includeEdges) = 0;
    +};
    +
    +
    +// Serialize the heap graph as seen from `node` with the given
    +// `CoreDumpWriter`. If `wantNames` is true, capture edge names. If `zones` is
    +// non-null, only capture the sub-graph within the zone set, otherwise capture
    +// the whole heap graph. Returns false on failure.
    +bool
    +WriteHeapGraph(JSContext *cx,
    +               const JS::ubi::Node &node,
    +               CoreDumpWriter &writer,
    +               bool wantNames,
    +               JS::ZoneSet *zones,
    +               JS::AutoCheckCannotGC &noGC);
    +
    +
    +class ChromeUtils
    +{
    +public:
    +  static void SaveHeapSnapshot(dom::GlobalObject &global,
    +                               JSContext *cx,
    +                               const nsAString &filePath,
    +                               const dom::HeapSnapshotBoundaries &boundaries,
    +                               ErrorResult &rv);
    +};
    +
    +} // namespace devtools
    +} // namespace mozilla
    +
    +#endif // mozilla_devtools_ChromeUtils__
    diff --git a/toolkit/devtools/server/CoreDump.pb.cc b/toolkit/devtools/server/CoreDump.pb.cc
    new file mode 100644
    index 000000000000..c82037f3eeb4
    --- /dev/null
    +++ b/toolkit/devtools/server/CoreDump.pb.cc
    @@ -0,0 +1,1005 @@
    +// Generated by the protocol buffer compiler.  DO NOT EDIT!
    +// source: CoreDump.proto
    +
    +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
    +#include "CoreDump.pb.h"
    +
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +// @@protoc_insertion_point(includes)
    +
    +namespace mozilla {
    +namespace devtools {
    +namespace protobuf {
    +
    +namespace {
    +
    +const ::google::protobuf::Descriptor* Metadata_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  Metadata_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* Node_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  Node_reflection_ = NULL;
    +const ::google::protobuf::Descriptor* Edge_descriptor_ = NULL;
    +const ::google::protobuf::internal::GeneratedMessageReflection*
    +  Edge_reflection_ = NULL;
    +
    +}  // namespace
    +
    +
    +void protobuf_AssignDesc_CoreDump_2eproto() {
    +  protobuf_AddDesc_CoreDump_2eproto();
    +  const ::google::protobuf::FileDescriptor* file =
    +    ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
    +      "CoreDump.proto");
    +  GOOGLE_CHECK(file != NULL);
    +  Metadata_descriptor_ = file->message_type(0);
    +  static const int Metadata_offsets_[1] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metadata, timestamp_),
    +  };
    +  Metadata_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      Metadata_descriptor_,
    +      Metadata::default_instance_,
    +      Metadata_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metadata, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metadata, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(Metadata));
    +  Node_descriptor_ = file->message_type(1);
    +  static const int Node_offsets_[4] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, id_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, typename__),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, size_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, edges_),
    +  };
    +  Node_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      Node_descriptor_,
    +      Node::default_instance_,
    +      Node_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(Node));
    +  Edge_descriptor_ = file->message_type(2);
    +  static const int Edge_offsets_[2] = {
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, referent_),
    +    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, name_),
    +  };
    +  Edge_reflection_ =
    +    new ::google::protobuf::internal::GeneratedMessageReflection(
    +      Edge_descriptor_,
    +      Edge::default_instance_,
    +      Edge_offsets_,
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _has_bits_[0]),
    +      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _unknown_fields_),
    +      -1,
    +      ::google::protobuf::DescriptorPool::generated_pool(),
    +      ::google::protobuf::MessageFactory::generated_factory(),
    +      sizeof(Edge));
    +}
    +
    +namespace {
    +
    +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
    +inline void protobuf_AssignDescriptorsOnce() {
    +  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
    +                 &protobuf_AssignDesc_CoreDump_2eproto);
    +}
    +
    +void protobuf_RegisterTypes(const ::std::string&) {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    Metadata_descriptor_, &Metadata::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    Node_descriptor_, &Node::default_instance());
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    +    Edge_descriptor_, &Edge::default_instance());
    +}
    +
    +}  // namespace
    +
    +void protobuf_ShutdownFile_CoreDump_2eproto() {
    +  delete Metadata::default_instance_;
    +  delete Metadata_reflection_;
    +  delete Node::default_instance_;
    +  delete Node_reflection_;
    +  delete Edge::default_instance_;
    +  delete Edge_reflection_;
    +}
    +
    +void protobuf_AddDesc_CoreDump_2eproto() {
    +  static bool already_here = false;
    +  if (already_here) return;
    +  already_here = true;
    +  GOOGLE_PROTOBUF_VERIFY_VERSION;
    +
    +  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
    +    "\n\016CoreDump.proto\022\031mozilla.devtools.proto"
    +    "buf\"\035\n\010Metadata\022\021\n\ttimeStamp\030\001 \001(\004\"b\n\004No"
    +    "de\022\n\n\002id\030\001 \001(\004\022\020\n\010typeName\030\002 \001(\014\022\014\n\004size"
    +    "\030\003 \001(\004\022.\n\005edges\030\004 \003(\0132\037.mozilla.devtools"
    +    ".protobuf.Edge\"&\n\004Edge\022\020\n\010referent\030\001 \001(\004"
    +    "\022\014\n\004name\030\002 \001(\014", 214);
    +  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    +    "CoreDump.proto", &protobuf_RegisterTypes);
    +  Metadata::default_instance_ = new Metadata();
    +  Node::default_instance_ = new Node();
    +  Edge::default_instance_ = new Edge();
    +  Metadata::default_instance_->InitAsDefaultInstance();
    +  Node::default_instance_->InitAsDefaultInstance();
    +  Edge::default_instance_->InitAsDefaultInstance();
    +  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_CoreDump_2eproto);
    +}
    +
    +// Force AddDescriptors() to be called at static initialization time.
    +struct StaticDescriptorInitializer_CoreDump_2eproto {
    +  StaticDescriptorInitializer_CoreDump_2eproto() {
    +    protobuf_AddDesc_CoreDump_2eproto();
    +  }
    +} static_descriptor_initializer_CoreDump_2eproto_;
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int Metadata::kTimeStampFieldNumber;
    +#endif  // !_MSC_VER
    +
    +Metadata::Metadata()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Metadata)
    +}
    +
    +void Metadata::InitAsDefaultInstance() {
    +}
    +
    +Metadata::Metadata(const Metadata& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Metadata)
    +}
    +
    +void Metadata::SharedCtor() {
    +  _cached_size_ = 0;
    +  timestamp_ = GOOGLE_ULONGLONG(0);
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +Metadata::~Metadata() {
    +  // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Metadata)
    +  SharedDtor();
    +}
    +
    +void Metadata::SharedDtor() {
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void Metadata::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* Metadata::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return Metadata_descriptor_;
    +}
    +
    +const Metadata& Metadata::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
    +  return *default_instance_;
    +}
    +
    +Metadata* Metadata::default_instance_ = NULL;
    +
    +Metadata* Metadata::New() const {
    +  return new Metadata;
    +}
    +
    +void Metadata::Clear() {
    +  timestamp_ = GOOGLE_ULONGLONG(0);
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool Metadata::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.Metadata)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional uint64 timeStamp = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
    +                 input, ×tamp_)));
    +          set_has_timestamp();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.Metadata)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.Metadata)
    +  return false;
    +#undef DO_
    +}
    +
    +void Metadata::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.Metadata)
    +  // optional uint64 timeStamp = 1;
    +  if (has_timestamp()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->timestamp(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Metadata)
    +}
    +
    +::google::protobuf::uint8* Metadata::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.Metadata)
    +  // optional uint64 timeStamp = 1;
    +  if (has_timestamp()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->timestamp(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Metadata)
    +  return target;
    +}
    +
    +int Metadata::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional uint64 timeStamp = 1;
    +    if (has_timestamp()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt64Size(
    +          this->timestamp());
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void Metadata::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const Metadata* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void Metadata::MergeFrom(const Metadata& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_timestamp()) {
    +      set_timestamp(from.timestamp());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void Metadata::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void Metadata::CopyFrom(const Metadata& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool Metadata::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void Metadata::Swap(Metadata* other) {
    +  if (other != this) {
    +    std::swap(timestamp_, other->timestamp_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata Metadata::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = Metadata_descriptor_;
    +  metadata.reflection = Metadata_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int Node::kIdFieldNumber;
    +const int Node::kTypeNameFieldNumber;
    +const int Node::kSizeFieldNumber;
    +const int Node::kEdgesFieldNumber;
    +#endif  // !_MSC_VER
    +
    +Node::Node()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Node)
    +}
    +
    +void Node::InitAsDefaultInstance() {
    +}
    +
    +Node::Node(const Node& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Node)
    +}
    +
    +void Node::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  id_ = GOOGLE_ULONGLONG(0);
    +  typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  size_ = GOOGLE_ULONGLONG(0);
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +Node::~Node() {
    +  // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Node)
    +  SharedDtor();
    +}
    +
    +void Node::SharedDtor() {
    +  if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete typename__;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void Node::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* Node::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return Node_descriptor_;
    +}
    +
    +const Node& Node::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
    +  return *default_instance_;
    +}
    +
    +Node* Node::default_instance_ = NULL;
    +
    +Node* Node::New() const {
    +  return new Node;
    +}
    +
    +void Node::Clear() {
    +  if (_has_bits_[0 / 32] & 7) {
    +    id_ = GOOGLE_ULONGLONG(0);
    +    if (has_typename_()) {
    +      if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        typename__->clear();
    +      }
    +    }
    +    size_ = GOOGLE_ULONGLONG(0);
    +  }
    +  edges_.Clear();
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool Node::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.Node)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional uint64 id = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
    +                 input, &id_)));
    +          set_has_id();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_typeName;
    +        break;
    +      }
    +
    +      // optional bytes typeName = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_typeName:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
    +                input, this->mutable_typename_()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(24)) goto parse_size;
    +        break;
    +      }
    +
    +      // optional uint64 size = 3;
    +      case 3: {
    +        if (tag == 24) {
    +         parse_size:
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
    +                 input, &size_)));
    +          set_has_size();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_edges;
    +        break;
    +      }
    +
    +      // repeated .mozilla.devtools.protobuf.Edge edges = 4;
    +      case 4: {
    +        if (tag == 34) {
    +         parse_edges:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
    +                input, add_edges()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(34)) goto parse_edges;
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.Node)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.Node)
    +  return false;
    +#undef DO_
    +}
    +
    +void Node::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.Node)
    +  // optional uint64 id = 1;
    +  if (has_id()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->id(), output);
    +  }
    +
    +  // optional bytes typeName = 2;
    +  if (has_typename_()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
    +      2, this->typename_(), output);
    +  }
    +
    +  // optional uint64 size = 3;
    +  if (has_size()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->size(), output);
    +  }
    +
    +  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
    +  for (int i = 0; i < this->edges_size(); i++) {
    +    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
    +      4, this->edges(i), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Node)
    +}
    +
    +::google::protobuf::uint8* Node::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.Node)
    +  // optional uint64 id = 1;
    +  if (has_id()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->id(), target);
    +  }
    +
    +  // optional bytes typeName = 2;
    +  if (has_typename_()) {
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
    +        2, this->typename_(), target);
    +  }
    +
    +  // optional uint64 size = 3;
    +  if (has_size()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->size(), target);
    +  }
    +
    +  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
    +  for (int i = 0; i < this->edges_size(); i++) {
    +    target = ::google::protobuf::internal::WireFormatLite::
    +      WriteMessageNoVirtualToArray(
    +        4, this->edges(i), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Node)
    +  return target;
    +}
    +
    +int Node::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional uint64 id = 1;
    +    if (has_id()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt64Size(
    +          this->id());
    +    }
    +
    +    // optional bytes typeName = 2;
    +    if (has_typename_()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::BytesSize(
    +          this->typename_());
    +    }
    +
    +    // optional uint64 size = 3;
    +    if (has_size()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt64Size(
    +          this->size());
    +    }
    +
    +  }
    +  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
    +  total_size += 1 * this->edges_size();
    +  for (int i = 0; i < this->edges_size(); i++) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
    +        this->edges(i));
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void Node::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const Node* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void Node::MergeFrom(const Node& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  edges_.MergeFrom(from.edges_);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_id()) {
    +      set_id(from.id());
    +    }
    +    if (from.has_typename_()) {
    +      set_typename_(from.typename_());
    +    }
    +    if (from.has_size()) {
    +      set_size(from.size());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void Node::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void Node::CopyFrom(const Node& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool Node::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void Node::Swap(Node* other) {
    +  if (other != this) {
    +    std::swap(id_, other->id_);
    +    std::swap(typename__, other->typename__);
    +    std::swap(size_, other->size_);
    +    edges_.Swap(&other->edges_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata Node::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = Node_descriptor_;
    +  metadata.reflection = Node_reflection_;
    +  return metadata;
    +}
    +
    +
    +// ===================================================================
    +
    +#ifndef _MSC_VER
    +const int Edge::kReferentFieldNumber;
    +const int Edge::kNameFieldNumber;
    +#endif  // !_MSC_VER
    +
    +Edge::Edge()
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  // @@protoc_insertion_point(constructor:mozilla.devtools.protobuf.Edge)
    +}
    +
    +void Edge::InitAsDefaultInstance() {
    +}
    +
    +Edge::Edge(const Edge& from)
    +  : ::google::protobuf::Message() {
    +  SharedCtor();
    +  MergeFrom(from);
    +  // @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Edge)
    +}
    +
    +void Edge::SharedCtor() {
    +  ::google::protobuf::internal::GetEmptyString();
    +  _cached_size_ = 0;
    +  referent_ = GOOGLE_ULONGLONG(0);
    +  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +}
    +
    +Edge::~Edge() {
    +  // @@protoc_insertion_point(destructor:mozilla.devtools.protobuf.Edge)
    +  SharedDtor();
    +}
    +
    +void Edge::SharedDtor() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (this != default_instance_) {
    +  }
    +}
    +
    +void Edge::SetCachedSize(int size) const {
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +}
    +const ::google::protobuf::Descriptor* Edge::descriptor() {
    +  protobuf_AssignDescriptorsOnce();
    +  return Edge_descriptor_;
    +}
    +
    +const Edge& Edge::default_instance() {
    +  if (default_instance_ == NULL) protobuf_AddDesc_CoreDump_2eproto();
    +  return *default_instance_;
    +}
    +
    +Edge* Edge::default_instance_ = NULL;
    +
    +Edge* Edge::New() const {
    +  return new Edge;
    +}
    +
    +void Edge::Clear() {
    +  if (_has_bits_[0 / 32] & 3) {
    +    referent_ = GOOGLE_ULONGLONG(0);
    +    if (has_name()) {
    +      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +        name_->clear();
    +      }
    +    }
    +  }
    +  ::memset(_has_bits_, 0, sizeof(_has_bits_));
    +  mutable_unknown_fields()->Clear();
    +}
    +
    +bool Edge::MergePartialFromCodedStream(
    +    ::google::protobuf::io::CodedInputStream* input) {
    +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
    +  ::google::protobuf::uint32 tag;
    +  // @@protoc_insertion_point(parse_start:mozilla.devtools.protobuf.Edge)
    +  for (;;) {
    +    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    +    tag = p.first;
    +    if (!p.second) goto handle_unusual;
    +    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
    +      // optional uint64 referent = 1;
    +      case 1: {
    +        if (tag == 8) {
    +          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
    +                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
    +                 input, &referent_)));
    +          set_has_referent();
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectTag(18)) goto parse_name;
    +        break;
    +      }
    +
    +      // optional bytes name = 2;
    +      case 2: {
    +        if (tag == 18) {
    +         parse_name:
    +          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
    +                input, this->mutable_name()));
    +        } else {
    +          goto handle_unusual;
    +        }
    +        if (input->ExpectAtEnd()) goto success;
    +        break;
    +      }
    +
    +      default: {
    +      handle_unusual:
    +        if (tag == 0 ||
    +            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
    +            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
    +          goto success;
    +        }
    +        DO_(::google::protobuf::internal::WireFormat::SkipField(
    +              input, tag, mutable_unknown_fields()));
    +        break;
    +      }
    +    }
    +  }
    +success:
    +  // @@protoc_insertion_point(parse_success:mozilla.devtools.protobuf.Edge)
    +  return true;
    +failure:
    +  // @@protoc_insertion_point(parse_failure:mozilla.devtools.protobuf.Edge)
    +  return false;
    +#undef DO_
    +}
    +
    +void Edge::SerializeWithCachedSizes(
    +    ::google::protobuf::io::CodedOutputStream* output) const {
    +  // @@protoc_insertion_point(serialize_start:mozilla.devtools.protobuf.Edge)
    +  // optional uint64 referent = 1;
    +  if (has_referent()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->referent(), output);
    +  }
    +
    +  // optional bytes name = 2;
    +  if (has_name()) {
    +    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
    +      2, this->name(), output);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
    +        unknown_fields(), output);
    +  }
    +  // @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Edge)
    +}
    +
    +::google::protobuf::uint8* Edge::SerializeWithCachedSizesToArray(
    +    ::google::protobuf::uint8* target) const {
    +  // @@protoc_insertion_point(serialize_to_array_start:mozilla.devtools.protobuf.Edge)
    +  // optional uint64 referent = 1;
    +  if (has_referent()) {
    +    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->referent(), target);
    +  }
    +
    +  // optional bytes name = 2;
    +  if (has_name()) {
    +    target =
    +      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
    +        2, this->name(), target);
    +  }
    +
    +  if (!unknown_fields().empty()) {
    +    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
    +        unknown_fields(), target);
    +  }
    +  // @@protoc_insertion_point(serialize_to_array_end:mozilla.devtools.protobuf.Edge)
    +  return target;
    +}
    +
    +int Edge::ByteSize() const {
    +  int total_size = 0;
    +
    +  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    // optional uint64 referent = 1;
    +    if (has_referent()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::UInt64Size(
    +          this->referent());
    +    }
    +
    +    // optional bytes name = 2;
    +    if (has_name()) {
    +      total_size += 1 +
    +        ::google::protobuf::internal::WireFormatLite::BytesSize(
    +          this->name());
    +    }
    +
    +  }
    +  if (!unknown_fields().empty()) {
    +    total_size +=
    +      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
    +        unknown_fields());
    +  }
    +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    +  _cached_size_ = total_size;
    +  GOOGLE_SAFE_CONCURRENT_WRITES_END();
    +  return total_size;
    +}
    +
    +void Edge::MergeFrom(const ::google::protobuf::Message& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  const Edge* source =
    +    ::google::protobuf::internal::dynamic_cast_if_available(
    +      &from);
    +  if (source == NULL) {
    +    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
    +  } else {
    +    MergeFrom(*source);
    +  }
    +}
    +
    +void Edge::MergeFrom(const Edge& from) {
    +  GOOGLE_CHECK_NE(&from, this);
    +  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    +    if (from.has_referent()) {
    +      set_referent(from.referent());
    +    }
    +    if (from.has_name()) {
    +      set_name(from.name());
    +    }
    +  }
    +  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
    +}
    +
    +void Edge::CopyFrom(const ::google::protobuf::Message& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +void Edge::CopyFrom(const Edge& from) {
    +  if (&from == this) return;
    +  Clear();
    +  MergeFrom(from);
    +}
    +
    +bool Edge::IsInitialized() const {
    +
    +  return true;
    +}
    +
    +void Edge::Swap(Edge* other) {
    +  if (other != this) {
    +    std::swap(referent_, other->referent_);
    +    std::swap(name_, other->name_);
    +    std::swap(_has_bits_[0], other->_has_bits_[0]);
    +    _unknown_fields_.Swap(&other->_unknown_fields_);
    +    std::swap(_cached_size_, other->_cached_size_);
    +  }
    +}
    +
    +::google::protobuf::Metadata Edge::GetMetadata() const {
    +  protobuf_AssignDescriptorsOnce();
    +  ::google::protobuf::Metadata metadata;
    +  metadata.descriptor = Edge_descriptor_;
    +  metadata.reflection = Edge_reflection_;
    +  return metadata;
    +}
    +
    +
    +// @@protoc_insertion_point(namespace_scope)
    +
    +}  // namespace protobuf
    +}  // namespace devtools
    +}  // namespace mozilla
    +
    +// @@protoc_insertion_point(global_scope)
    diff --git a/toolkit/devtools/server/CoreDump.pb.h b/toolkit/devtools/server/CoreDump.pb.h
    new file mode 100644
    index 000000000000..8420a2415777
    --- /dev/null
    +++ b/toolkit/devtools/server/CoreDump.pb.h
    @@ -0,0 +1,643 @@
    +// Generated by the protocol buffer compiler.  DO NOT EDIT!
    +// source: CoreDump.proto
    +
    +#ifndef PROTOBUF_CoreDump_2eproto__INCLUDED
    +#define PROTOBUF_CoreDump_2eproto__INCLUDED
    +
    +#include 
    +
    +#include 
    +
    +#if GOOGLE_PROTOBUF_VERSION < 2006000
    +#error This file was generated by a newer version of protoc which is
    +#error incompatible with your Protocol Buffer headers.  Please update
    +#error your headers.
    +#endif
    +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
    +#error This file was generated by an older version of protoc which is
    +#error incompatible with your Protocol Buffer headers.  Please
    +#error regenerate this file with a newer version of protoc.
    +#endif
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +// @@protoc_insertion_point(includes)
    +
    +namespace mozilla {
    +namespace devtools {
    +namespace protobuf {
    +
    +// Internal implementation detail -- do not call these.
    +void  protobuf_AddDesc_CoreDump_2eproto();
    +void protobuf_AssignDesc_CoreDump_2eproto();
    +void protobuf_ShutdownFile_CoreDump_2eproto();
    +
    +class Metadata;
    +class Node;
    +class Edge;
    +
    +// ===================================================================
    +
    +class Metadata : public ::google::protobuf::Message {
    + public:
    +  Metadata();
    +  virtual ~Metadata();
    +
    +  Metadata(const Metadata& from);
    +
    +  inline Metadata& operator=(const Metadata& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const Metadata& default_instance();
    +
    +  void Swap(Metadata* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  Metadata* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const Metadata& from);
    +  void MergeFrom(const Metadata& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional uint64 timeStamp = 1;
    +  inline bool has_timestamp() const;
    +  inline void clear_timestamp();
    +  static const int kTimeStampFieldNumber = 1;
    +  inline ::google::protobuf::uint64 timestamp() const;
    +  inline void set_timestamp(::google::protobuf::uint64 value);
    +
    +  // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Metadata)
    + private:
    +  inline void set_has_timestamp();
    +  inline void clear_has_timestamp();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::uint64 timestamp_;
    +  friend void  protobuf_AddDesc_CoreDump_2eproto();
    +  friend void protobuf_AssignDesc_CoreDump_2eproto();
    +  friend void protobuf_ShutdownFile_CoreDump_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static Metadata* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class Node : public ::google::protobuf::Message {
    + public:
    +  Node();
    +  virtual ~Node();
    +
    +  Node(const Node& from);
    +
    +  inline Node& operator=(const Node& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const Node& default_instance();
    +
    +  void Swap(Node* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  Node* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const Node& from);
    +  void MergeFrom(const Node& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional uint64 id = 1;
    +  inline bool has_id() const;
    +  inline void clear_id();
    +  static const int kIdFieldNumber = 1;
    +  inline ::google::protobuf::uint64 id() const;
    +  inline void set_id(::google::protobuf::uint64 value);
    +
    +  // optional bytes typeName = 2;
    +  inline bool has_typename_() const;
    +  inline void clear_typename_();
    +  static const int kTypeNameFieldNumber = 2;
    +  inline const ::std::string& typename_() const;
    +  inline void set_typename_(const ::std::string& value);
    +  inline void set_typename_(const char* value);
    +  inline void set_typename_(const void* value, size_t size);
    +  inline ::std::string* mutable_typename_();
    +  inline ::std::string* release_typename_();
    +  inline void set_allocated_typename_(::std::string* typename_);
    +
    +  // optional uint64 size = 3;
    +  inline bool has_size() const;
    +  inline void clear_size();
    +  static const int kSizeFieldNumber = 3;
    +  inline ::google::protobuf::uint64 size() const;
    +  inline void set_size(::google::protobuf::uint64 value);
    +
    +  // repeated .mozilla.devtools.protobuf.Edge edges = 4;
    +  inline int edges_size() const;
    +  inline void clear_edges();
    +  static const int kEdgesFieldNumber = 4;
    +  inline const ::mozilla::devtools::protobuf::Edge& edges(int index) const;
    +  inline ::mozilla::devtools::protobuf::Edge* mutable_edges(int index);
    +  inline ::mozilla::devtools::protobuf::Edge* add_edges();
    +  inline const ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >&
    +      edges() const;
    +  inline ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >*
    +      mutable_edges();
    +
    +  // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Node)
    + private:
    +  inline void set_has_id();
    +  inline void clear_has_id();
    +  inline void set_has_typename_();
    +  inline void clear_has_typename_();
    +  inline void set_has_size();
    +  inline void clear_has_size();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::uint64 id_;
    +  ::std::string* typename__;
    +  ::google::protobuf::uint64 size_;
    +  ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge > edges_;
    +  friend void  protobuf_AddDesc_CoreDump_2eproto();
    +  friend void protobuf_AssignDesc_CoreDump_2eproto();
    +  friend void protobuf_ShutdownFile_CoreDump_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static Node* default_instance_;
    +};
    +// -------------------------------------------------------------------
    +
    +class Edge : public ::google::protobuf::Message {
    + public:
    +  Edge();
    +  virtual ~Edge();
    +
    +  Edge(const Edge& from);
    +
    +  inline Edge& operator=(const Edge& from) {
    +    CopyFrom(from);
    +    return *this;
    +  }
    +
    +  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    +    return _unknown_fields_;
    +  }
    +
    +  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    +    return &_unknown_fields_;
    +  }
    +
    +  static const ::google::protobuf::Descriptor* descriptor();
    +  static const Edge& default_instance();
    +
    +  void Swap(Edge* other);
    +
    +  // implements Message ----------------------------------------------
    +
    +  Edge* New() const;
    +  void CopyFrom(const ::google::protobuf::Message& from);
    +  void MergeFrom(const ::google::protobuf::Message& from);
    +  void CopyFrom(const Edge& from);
    +  void MergeFrom(const Edge& from);
    +  void Clear();
    +  bool IsInitialized() const;
    +
    +  int ByteSize() const;
    +  bool MergePartialFromCodedStream(
    +      ::google::protobuf::io::CodedInputStream* input);
    +  void SerializeWithCachedSizes(
    +      ::google::protobuf::io::CodedOutputStream* output) const;
    +  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
    +  int GetCachedSize() const { return _cached_size_; }
    +  private:
    +  void SharedCtor();
    +  void SharedDtor();
    +  void SetCachedSize(int size) const;
    +  public:
    +  ::google::protobuf::Metadata GetMetadata() const;
    +
    +  // nested types ----------------------------------------------------
    +
    +  // accessors -------------------------------------------------------
    +
    +  // optional uint64 referent = 1;
    +  inline bool has_referent() const;
    +  inline void clear_referent();
    +  static const int kReferentFieldNumber = 1;
    +  inline ::google::protobuf::uint64 referent() const;
    +  inline void set_referent(::google::protobuf::uint64 value);
    +
    +  // optional bytes name = 2;
    +  inline bool has_name() const;
    +  inline void clear_name();
    +  static const int kNameFieldNumber = 2;
    +  inline const ::std::string& name() const;
    +  inline void set_name(const ::std::string& value);
    +  inline void set_name(const char* value);
    +  inline void set_name(const void* value, size_t size);
    +  inline ::std::string* mutable_name();
    +  inline ::std::string* release_name();
    +  inline void set_allocated_name(::std::string* name);
    +
    +  // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Edge)
    + private:
    +  inline void set_has_referent();
    +  inline void clear_has_referent();
    +  inline void set_has_name();
    +  inline void clear_has_name();
    +
    +  ::google::protobuf::UnknownFieldSet _unknown_fields_;
    +
    +  ::google::protobuf::uint32 _has_bits_[1];
    +  mutable int _cached_size_;
    +  ::google::protobuf::uint64 referent_;
    +  ::std::string* name_;
    +  friend void  protobuf_AddDesc_CoreDump_2eproto();
    +  friend void protobuf_AssignDesc_CoreDump_2eproto();
    +  friend void protobuf_ShutdownFile_CoreDump_2eproto();
    +
    +  void InitAsDefaultInstance();
    +  static Edge* default_instance_;
    +};
    +// ===================================================================
    +
    +
    +// ===================================================================
    +
    +// Metadata
    +
    +// optional uint64 timeStamp = 1;
    +inline bool Metadata::has_timestamp() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void Metadata::set_has_timestamp() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void Metadata::clear_has_timestamp() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void Metadata::clear_timestamp() {
    +  timestamp_ = GOOGLE_ULONGLONG(0);
    +  clear_has_timestamp();
    +}
    +inline ::google::protobuf::uint64 Metadata::timestamp() const {
    +  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Metadata.timeStamp)
    +  return timestamp_;
    +}
    +inline void Metadata::set_timestamp(::google::protobuf::uint64 value) {
    +  set_has_timestamp();
    +  timestamp_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Metadata.timeStamp)
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// Node
    +
    +// optional uint64 id = 1;
    +inline bool Node::has_id() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void Node::set_has_id() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void Node::clear_has_id() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void Node::clear_id() {
    +  id_ = GOOGLE_ULONGLONG(0);
    +  clear_has_id();
    +}
    +inline ::google::protobuf::uint64 Node::id() const {
    +  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.id)
    +  return id_;
    +}
    +inline void Node::set_id(::google::protobuf::uint64 value) {
    +  set_has_id();
    +  id_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.id)
    +}
    +
    +// optional bytes typeName = 2;
    +inline bool Node::has_typename_() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void Node::set_has_typename_() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void Node::clear_has_typename_() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void Node::clear_typename_() {
    +  if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    typename__->clear();
    +  }
    +  clear_has_typename_();
    +}
    +inline const ::std::string& Node::typename_() const {
    +  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.typeName)
    +  return *typename__;
    +}
    +inline void Node::set_typename_(const ::std::string& value) {
    +  set_has_typename_();
    +  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    typename__ = new ::std::string;
    +  }
    +  typename__->assign(value);
    +  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.typeName)
    +}
    +inline void Node::set_typename_(const char* value) {
    +  set_has_typename_();
    +  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    typename__ = new ::std::string;
    +  }
    +  typename__->assign(value);
    +  // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Node.typeName)
    +}
    +inline void Node::set_typename_(const void* value, size_t size) {
    +  set_has_typename_();
    +  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    typename__ = new ::std::string;
    +  }
    +  typename__->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Node.typeName)
    +}
    +inline ::std::string* Node::mutable_typename_() {
    +  set_has_typename_();
    +  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    typename__ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.typeName)
    +  return typename__;
    +}
    +inline ::std::string* Node::release_typename_() {
    +  clear_has_typename_();
    +  if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = typename__;
    +    typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void Node::set_allocated_typename_(::std::string* typename_) {
    +  if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete typename__;
    +  }
    +  if (typename_) {
    +    set_has_typename_();
    +    typename__ = typename_;
    +  } else {
    +    clear_has_typename_();
    +    typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.typeName)
    +}
    +
    +// optional uint64 size = 3;
    +inline bool Node::has_size() const {
    +  return (_has_bits_[0] & 0x00000004u) != 0;
    +}
    +inline void Node::set_has_size() {
    +  _has_bits_[0] |= 0x00000004u;
    +}
    +inline void Node::clear_has_size() {
    +  _has_bits_[0] &= ~0x00000004u;
    +}
    +inline void Node::clear_size() {
    +  size_ = GOOGLE_ULONGLONG(0);
    +  clear_has_size();
    +}
    +inline ::google::protobuf::uint64 Node::size() const {
    +  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.size)
    +  return size_;
    +}
    +inline void Node::set_size(::google::protobuf::uint64 value) {
    +  set_has_size();
    +  size_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.size)
    +}
    +
    +// repeated .mozilla.devtools.protobuf.Edge edges = 4;
    +inline int Node::edges_size() const {
    +  return edges_.size();
    +}
    +inline void Node::clear_edges() {
    +  edges_.Clear();
    +}
    +inline const ::mozilla::devtools::protobuf::Edge& Node::edges(int index) const {
    +  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.edges)
    +  return edges_.Get(index);
    +}
    +inline ::mozilla::devtools::protobuf::Edge* Node::mutable_edges(int index) {
    +  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.edges)
    +  return edges_.Mutable(index);
    +}
    +inline ::mozilla::devtools::protobuf::Edge* Node::add_edges() {
    +  // @@protoc_insertion_point(field_add:mozilla.devtools.protobuf.Node.edges)
    +  return edges_.Add();
    +}
    +inline const ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >&
    +Node::edges() const {
    +  // @@protoc_insertion_point(field_list:mozilla.devtools.protobuf.Node.edges)
    +  return edges_;
    +}
    +inline ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >*
    +Node::mutable_edges() {
    +  // @@protoc_insertion_point(field_mutable_list:mozilla.devtools.protobuf.Node.edges)
    +  return &edges_;
    +}
    +
    +// -------------------------------------------------------------------
    +
    +// Edge
    +
    +// optional uint64 referent = 1;
    +inline bool Edge::has_referent() const {
    +  return (_has_bits_[0] & 0x00000001u) != 0;
    +}
    +inline void Edge::set_has_referent() {
    +  _has_bits_[0] |= 0x00000001u;
    +}
    +inline void Edge::clear_has_referent() {
    +  _has_bits_[0] &= ~0x00000001u;
    +}
    +inline void Edge::clear_referent() {
    +  referent_ = GOOGLE_ULONGLONG(0);
    +  clear_has_referent();
    +}
    +inline ::google::protobuf::uint64 Edge::referent() const {
    +  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Edge.referent)
    +  return referent_;
    +}
    +inline void Edge::set_referent(::google::protobuf::uint64 value) {
    +  set_has_referent();
    +  referent_ = value;
    +  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Edge.referent)
    +}
    +
    +// optional bytes name = 2;
    +inline bool Edge::has_name() const {
    +  return (_has_bits_[0] & 0x00000002u) != 0;
    +}
    +inline void Edge::set_has_name() {
    +  _has_bits_[0] |= 0x00000002u;
    +}
    +inline void Edge::clear_has_name() {
    +  _has_bits_[0] &= ~0x00000002u;
    +}
    +inline void Edge::clear_name() {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_->clear();
    +  }
    +  clear_has_name();
    +}
    +inline const ::std::string& Edge::name() const {
    +  // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Edge.name)
    +  return *name_;
    +}
    +inline void Edge::set_name(const ::std::string& value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Edge.name)
    +}
    +inline void Edge::set_name(const char* value) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(value);
    +  // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Edge.name)
    +}
    +inline void Edge::set_name(const void* value, size_t size) {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  name_->assign(reinterpret_cast(value), size);
    +  // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Edge.name)
    +}
    +inline ::std::string* Edge::mutable_name() {
    +  set_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    name_ = new ::std::string;
    +  }
    +  // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Edge.name)
    +  return name_;
    +}
    +inline ::std::string* Edge::release_name() {
    +  clear_has_name();
    +  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    return NULL;
    +  } else {
    +    ::std::string* temp = name_;
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +    return temp;
    +  }
    +}
    +inline void Edge::set_allocated_name(::std::string* name) {
    +  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    +    delete name_;
    +  }
    +  if (name) {
    +    set_has_name();
    +    name_ = name;
    +  } else {
    +    clear_has_name();
    +    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    +  }
    +  // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Edge.name)
    +}
    +
    +
    +// @@protoc_insertion_point(namespace_scope)
    +
    +}  // namespace protobuf
    +}  // namespace devtools
    +}  // namespace mozilla
    +
    +#ifndef SWIG
    +namespace google {
    +namespace protobuf {
    +
    +
    +}  // namespace google
    +}  // namespace protobuf
    +#endif  // SWIG
    +
    +// @@protoc_insertion_point(global_scope)
    +
    +#endif  // PROTOBUF_CoreDump_2eproto__INCLUDED
    diff --git a/toolkit/devtools/server/CoreDump.proto b/toolkit/devtools/server/CoreDump.proto
    new file mode 100644
    index 000000000000..2424cc7248ed
    --- /dev/null
    +++ b/toolkit/devtools/server/CoreDump.proto
    @@ -0,0 +1,69 @@
    +/* -*- Mode: protobuf; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
    + * vim: set ts=8 sts=4 et sw=4 tw=99:
    + * This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +// # Core Dumps
    +//
    +// A core dump is a serialized snapshot of the heap graph. We serialize the heap
    +// as a series of protobuf messages with each message prefixed by its Varint32
    +// byte size so we can delimit individual protobuf messages (protobuf parsers
    +// cannot determine where a message ends on their own).
    +//
    +// The first protobuf message is an instance of the `Metadata` message. All
    +// subsequent messages will be instances of the `Node` message. The first of
    +// these `Node` messages is the root node of the serialized heap graph. Here is
    +// a diagram of our core dump format:
    +//
    +//     +-----------------------------------------------------------------------+
    +//     | Varint32: The size of following `Metadata` message.                   |
    +//     +-----------------------------------------------------------------------+
    +//     | message: The core dump `Metadata` message.                            |
    +//     +-----------------------------------------------------------------------+
    +//     | Varint32: The size of the following `Node` message.                   |
    +//     +-----------------------------------------------------------------------+
    +//     | message: The first `Node` message. This is the root node.             |
    +//     +-----------------------------------------------------------------------+
    +//     | Varint32: The size of the following `Node` message.                   |
    +//     +-----------------------------------------------------------------------+
    +//     | message: A `Node` message.                                            |
    +//     +-----------------------------------------------------------------------+
    +//     | Varint32: The size of the following `Node` message.                   |
    +//     +-----------------------------------------------------------------------+
    +//     | message: A `Node` message.                                            |
    +//     +-----------------------------------------------------------------------+
    +//     | .                                                                     |
    +//     | .                                                                     |
    +//     | .                                                                     |
    +//     +-----------------------------------------------------------------------+
    +//
    +// In practice, certain message fields have a lot of duplication (such as type
    +// or edge name strings). Rather than try and de-duplicate this information at
    +// the protobuf message and field level, core dumps should be written with
    +// `google::protobuf::io::GzipOutputStream` and read from
    +// `google::protobuf::io::GzipInputStream`.
    +
    +package mozilla.devtools.protobuf;
    +
    +// A collection of metadata about this core dump.
    +message Metadata {
    +    // Number of microseconds since midnight (00:00:00) 1 January 1970 UTC.
    +    optional uint64 timeStamp = 1;
    +}
    +
    +// A serialized version of `JS::ubi::Node` and its outgoing edges.
    +message Node {
    +    optional uint64 id       = 1;
    +    // char16_t[]
    +    optional bytes  typeName = 2;
    +    optional uint64 size     = 3;
    +    repeated Edge   edges    = 4;
    +}
    +
    +// A serialized edge from the heap graph.
    +message Edge {
    +    optional uint64 referent = 1;
    +    // char16_t[]
    +    optional bytes  name     = 2;
    +}
    \ No newline at end of file
    diff --git a/toolkit/devtools/server/generate-core-dump-sources.sh b/toolkit/devtools/server/generate-core-dump-sources.sh
    new file mode 100755
    index 000000000000..05abde2ca867
    --- /dev/null
    +++ b/toolkit/devtools/server/generate-core-dump-sources.sh
    @@ -0,0 +1,26 @@
    +#!/usr/bin/env bash
    +
    +# A script to generate toolkit/devtools/server/CoreDump.pb.{h,cc} from
    +# toolkit/devtools/server/CoreDump.proto. This script assumes you have
    +# downloaded and installed the protocol buffer compiler, and that it is either
    +# on your $PATH or located at $PROTOC_PATH.
    +#
    +# These files were last compiled with libprotoc 2.4.1.
    +
    +set -e
    +
    +cd $(dirname $0)
    +
    +if [ -n $PROTOC_PATH ]; then
    +    PROTOC_PATH=`which protoc`
    +fi
    +
    +if [ ! -e $PROTOC_PATH ]; then
    +    echo You must install the protocol compiler from
    +    echo https://code.google.com/p/protobuf/downloads/list
    +    exit 1
    +fi
    +
    +echo Using $PROTOC_PATH as the protocol compiler
    +
    +$PROTOC_PATH --cpp_out="." CoreDump.proto
    diff --git a/toolkit/devtools/server/moz.build b/toolkit/devtools/server/moz.build
    index 5ccde2952b8b..22b67b20dde9 100644
    --- a/toolkit/devtools/server/moz.build
    +++ b/toolkit/devtools/server/moz.build
    @@ -15,14 +15,21 @@ XPIDL_SOURCES += [
     XPIDL_MODULE = 'jsinspector'
     
     EXPORTS.mozilla.devtools += [
    +    'ChromeUtils.h',
    +    'CoreDump.pb.h',
         'ZeroCopyNSIOutputStream.h',
     ]
     
     SOURCES += [
    +    'ChromeUtils.cpp',
    +    'CoreDump.pb.cc',
         'nsJSInspector.cpp',
         'ZeroCopyNSIOutputStream.cpp',
     ]
     
    +# Disable RTTI in google protocol buffer
    +DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
    +
     FINAL_LIBRARY = 'xul'
     
     EXTRA_JS_MODULES.devtools += [
    
    From 6b7167b4d6bb0afe463b88c9a114192d01952a44 Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:54 -0700
    Subject: [PATCH 216/241] Bug 1024774 - Part 4: Add an xpcshell test for saving
     heap snapshots. r=jimb
    
    ---
     .../devtools/server/tests/unit/head_dbg.js    | 12 ++-
     .../tests/unit/test_SaveHeapSnapshot.js       | 98 +++++++++++++++++++
     .../devtools/server/tests/unit/xpcshell.ini   |  1 +
     3 files changed, 109 insertions(+), 2 deletions(-)
     create mode 100644 toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js
    
    diff --git a/toolkit/devtools/server/tests/unit/head_dbg.js b/toolkit/devtools/server/tests/unit/head_dbg.js
    index 85159b3d1888..9a3e2e16c43b 100644
    --- a/toolkit/devtools/server/tests/unit/head_dbg.js
    +++ b/toolkit/devtools/server/tests/unit/head_dbg.js
    @@ -6,6 +6,7 @@ const Cc = Components.classes;
     const Ci = Components.interfaces;
     const Cu = Components.utils;
     const Cr = Components.results;
    +const CC = Components.Constructor;
     
     const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
     const { worker } = Cu.import("resource://gre/modules/devtools/worker-loader.js", {})
    @@ -349,7 +350,7 @@ function getFileUrl(aName, aAllowMissing=false) {
      * Returns the full path of the file with the specified name in a
      * platform-independent and URL-like form.
      */
    -function getFilePath(aName, aAllowMissing=false)
    +function getFilePath(aName, aAllowMissing=false, aUsePlatformPathSeparator=false)
     {
       let file = do_get_file(aName, aAllowMissing);
       let path = Services.io.newFileURI(file).spec;
    @@ -358,7 +359,14 @@ function getFilePath(aName, aAllowMissing=false)
           file instanceof Ci.nsILocalFileWin) {
         filePrePath += "/";
       }
    -  return path.slice(filePrePath.length);
    +
    +  path = path.slice(filePrePath.length);
    +
    +  if (aUsePlatformPathSeparator && path.match(/^\w:/)) {
    +    path = path.replace(/\//g, "\\");
    +  }
    +
    +  return path;
     }
     
     Cu.import("resource://gre/modules/NetUtil.jsm");
    diff --git a/toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js b/toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js
    new file mode 100644
    index 000000000000..ef37383ac3d7
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js
    @@ -0,0 +1,98 @@
    +/* Any copyright is dedicated to the Public Domain.
    +   http://creativecommons.org/publicdomain/zero/1.0/ */
    +
    +// Test the ChromeUtils interface.
    +
    +const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {});
    +var Debugger;
    +addDebuggerToGlobal(this);
    +
    +function run_test() {
    +  ok(ChromeUtils, "Should be able to get the ChromeUtils interface");
    +
    +  let filePath = getFilePath("core-dump.tmp", true, true);
    +  ok(filePath, "Should get a file path");
    +
    +  testBadParameters(filePath);
    +  testGoodParameters(filePath);
    +
    +  do_test_finished();
    +}
    +
    +function testBadParameters(filePath) {
    +  throws(() => ChromeUtils.saveHeapSnapshot(),
    +         "Should throw if arguments aren't passed in.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(Object.create(null),
    +                                            { runtime: true }),
    +         "Should throw if the filePath is not coercible to string.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            null),
    +         "Should throw if boundaries isn't an object.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            {}),
    +         "Should throw if the boundaries object doesn't have any properties.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { runtime: true,
    +                                              globals: [this] }),
    +         "Should throw if the boundaries object has more than one property.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { debugger: {} }),
    +         "Should throw if the debuggees object is not a Debugger object");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { globals: [{}] }),
    +         "Should throw if the globals array contains non-global objects.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { runtime: false }),
    +         "Should throw if runtime is supplied and is not true.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { globals: null }),
    +         "Should throw if globals is not an object.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { globals: {} }),
    +         "Should throw if globals is not an array.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { debugger: Debugger.prototype }),
    +         "Should throw if debugger is the Debugger.prototype object.");
    +
    +  throws(() => ChromeUtils.saveHeapSnapshot(filePath,
    +                                            { get globals() { return [this]; } }),
    +         "Should throw if boundaries property is a getter.");
    +}
    +
    +const makeNewSandbox = () =>
    +  Cu.Sandbox(CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')());
    +
    +function testGoodParameters(filePath) {
    +  let sandbox = makeNewSandbox();
    +  let dbg = new Debugger(sandbox);
    +
    +  ChromeUtils.saveHeapSnapshot(filePath, { debugger: dbg });
    +  ok(true, "Should be able to save a snapshot for a debuggee global.");
    +
    +  dbg = new Debugger;
    +  let sandboxes = Array(10).fill(null).map(makeNewSandbox);
    +  sandboxes.forEach(sb => dbg.addDebuggee(sb));
    +
    +  ChromeUtils.saveHeapSnapshot(filePath, { debugger: dbg });
    +  ok(true, "Should be able to save a snapshot for many debuggee globals.");
    +
    +  dbg = new Debugger;
    +  ChromeUtils.saveHeapSnapshot(filePath, { debugger: dbg });
    +  ok(true, "Should be able to save a snapshot with no debuggee globals.");
    +
    +  ChromeUtils.saveHeapSnapshot(filePath, { globals: [this] });
    +  ok(true, "Should be able to save a snapshot for a specific global.");
    +
    +  ChromeUtils.saveHeapSnapshot(filePath, { runtime: true });
    +  ok(true, "Should be able to save a snapshot of the full runtime.");
    +}
    diff --git a/toolkit/devtools/server/tests/unit/xpcshell.ini b/toolkit/devtools/server/tests/unit/xpcshell.ini
    index 088089700b8a..90753c9f88f5 100644
    --- a/toolkit/devtools/server/tests/unit/xpcshell.ini
    +++ b/toolkit/devtools/server/tests/unit/xpcshell.ini
    @@ -40,6 +40,7 @@ support-files =
     [test_forwardingprefix.js]
     [test_getyoungestframe.js]
     [test_nsjsinspector.js]
    +[test_SaveHeapSnapshot.js]
     [test_dbgactor.js]
     [test_dbgglobal.js]
     [test_dbgclient_debuggerstatement.js]
    
    From a4bd0682884d767dd01c73e7776fcaec762ef12f Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:54 -0700
    Subject: [PATCH 217/241] Bug 1024774 - Part 5: Add GTests for core dump
     serialization. r=jimb
    
    ---
     toolkit/devtools/server/moz.build             |   3 +
     .../devtools/server/tests/gtest/DevTools.h    | 289 ++++++++++++++++++
     .../tests/gtest/DoesCrossZoneBoundaries.cpp   |  70 +++++
     .../tests/gtest/DoesntCrossZoneBoundaries.cpp |  62 ++++
     .../tests/gtest/SerializesEdgeNames.cpp       |  53 ++++
     .../SerializesEverythingInHeapGraphOnce.cpp   |  37 +++
     .../tests/gtest/SerializesTypeNames.cpp       |  30 ++
     toolkit/devtools/server/tests/gtest/moz.build |  21 ++
     8 files changed, 565 insertions(+)
     create mode 100644 toolkit/devtools/server/tests/gtest/DevTools.h
     create mode 100644 toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp
     create mode 100644 toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp
     create mode 100644 toolkit/devtools/server/tests/gtest/SerializesEdgeNames.cpp
     create mode 100644 toolkit/devtools/server/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp
     create mode 100644 toolkit/devtools/server/tests/gtest/SerializesTypeNames.cpp
     create mode 100644 toolkit/devtools/server/tests/gtest/moz.build
    
    diff --git a/toolkit/devtools/server/moz.build b/toolkit/devtools/server/moz.build
    index 22b67b20dde9..b4fcdca05b26 100644
    --- a/toolkit/devtools/server/moz.build
    +++ b/toolkit/devtools/server/moz.build
    @@ -8,6 +8,9 @@ BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
     MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
     XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
     
    +if CONFIG['ENABLE_TESTS']:
    +    DIRS += ['tests/gtest']
    +
     XPIDL_SOURCES += [
         'nsIJSInspector.idl',
     ]
    diff --git a/toolkit/devtools/server/tests/gtest/DevTools.h b/toolkit/devtools/server/tests/gtest/DevTools.h
    new file mode 100644
    index 000000000000..0c52f80e3a67
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/gtest/DevTools.h
    @@ -0,0 +1,289 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +#ifndef mozilla_devtools_gtest_DevTools__
    +#define mozilla_devtools_gtest_DevTools__
    +
    +#include "CoreDump.pb.h"
    +#include "jsapi.h"
    +#include "jspubtd.h"
    +#include "nsCRTGlue.h"
    +
    +#include "gtest/gtest.h"
    +#include "gmock/gmock.h"
    +#include "mozilla/devtools/ChromeUtils.h"
    +#include "mozilla/CycleCollectedJSRuntime.h"
    +#include "mozilla/Move.h"
    +#include "mozilla/UniquePtr.h"
    +#include "js/UbiNode.h"
    +
    +using namespace mozilla;
    +using namespace mozilla::devtools;
    +using namespace testing;
    +
    +// GTest fixture class that all of our tests derive from.
    +struct DevTools : public ::testing::Test {
    +  bool                       _initialized;
    +  JSRuntime                  *rt;
    +  JSContext                  *cx;
    +  JSCompartment              *compartment;
    +  JS::Zone                   *zone;
    +  JS::PersistentRootedObject global;
    +
    +  DevTools()
    +    : _initialized(false),
    +      rt(nullptr),
    +      cx(nullptr)
    +  { }
    +
    +  virtual void SetUp() {
    +    MOZ_ASSERT(!_initialized);
    +
    +    rt = getRuntime();
    +    if (!rt)
    +      return;
    +
    +    cx = createContext();
    +    if (!cx)
    +      return;
    +    JS_BeginRequest(cx);
    +
    +    global.init(rt, createGlobal());
    +    if (!global)
    +      return;
    +    JS_EnterCompartment(cx, global);
    +
    +    compartment = js::GetContextCompartment(cx);
    +    zone = js::GetContextZone(cx);
    +
    +    _initialized = true;
    +  }
    +
    +  JSRuntime* getRuntime() {
    +    return CycleCollectedJSRuntime::Get()->Runtime();
    +  }
    +
    +  static void setNativeStackQuota(JSRuntime *rt)
    +  {
    +    const size_t MAX_STACK_SIZE =
    +      /* Assume we can't use more than 5e5 bytes of C stack by default. */
    +#if (defined(DEBUG) && defined(__SUNPRO_CC))  || defined(JS_CPU_SPARC)
    +      /*
    +       * Sun compiler uses a larger stack space for js::Interpret() with
    +       * debug.  Use a bigger gMaxStackSize to make "make check" happy.
    +       */
    +      5000000
    +#else
    +      500000
    +#endif
    +      ;
    +
    +    JS_SetNativeStackQuota(rt, MAX_STACK_SIZE);
    +  }
    +
    +  static void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
    +    fprintf(stderr, "%s:%u:%s\n",
    +            report->filename ? report->filename : "",
    +            (unsigned int) report->lineno,
    +            message);
    +  }
    +
    +  JSContext *createContext() {
    +    return JS_NewContext(rt, 8192);
    +  }
    +
    +  static const JSClass *getGlobalClass() {
    +    static const JSClass globalClass = {
    +      "global", JSCLASS_GLOBAL_FLAGS,
    +      nullptr, nullptr, nullptr, nullptr,
    +      nullptr, nullptr, nullptr, nullptr,
    +      nullptr, nullptr, nullptr,
    +      JS_GlobalObjectTraceHook
    +    };
    +    return &globalClass;
    +  }
    +
    +  JSObject *createGlobal()
    +  {
    +    /* Create the global object. */
    +    JS::RootedObject newGlobal(cx);
    +    JS::CompartmentOptions options;
    +    options.setVersion(JSVERSION_LATEST);
    +    newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
    +                                   JS::FireOnNewGlobalHook, options);
    +    if (!newGlobal)
    +      return nullptr;
    +
    +    JSAutoCompartment ac(cx, newGlobal);
    +
    +    /* Populate the global object with the standard globals, like Object and
    +       Array. */
    +    if (!JS_InitStandardClasses(cx, newGlobal))
    +      return nullptr;
    +
    +    return newGlobal;
    +  }
    +
    +  virtual void TearDown() {
    +    _initialized = false;
    +
    +    if (global) {
    +      JS_LeaveCompartment(cx, nullptr);
    +      global = nullptr;
    +    }
    +    if (cx) {
    +      JS_EndRequest(cx);
    +      JS_DestroyContext(cx);
    +      cx = nullptr;
    +    }
    +  }
    +};
    +
    +
    +// Helper to define a test and ensure that the fixture is initialized properly.
    +#define DEF_TEST(name, body)                    \
    +  TEST_F(DevTools, name) {                      \
    +    ASSERT_TRUE(_initialized);                  \
    +    body                                        \
    +  }
    +
    +
    +// Fake JS::ubi::Node implementation
    +
    +class MOZ_STACK_CLASS FakeNode
    +{
    +public:
    +  JS::ubi::SimpleEdgeVector edges;
    +  JSCompartment*            compartment;
    +  JS::Zone*                 zone;
    +  size_t                    size;
    +
    +  explicit FakeNode(JSContext* cx)
    +    : edges(cx),
    +    compartment(nullptr),
    +    zone(nullptr),
    +    size(1)
    +  { }
    +};
    +
    +namespace JS {
    +namespace ubi {
    +
    +using mozilla::UniquePtr;
    +
    +template<>
    +class Concrete : public Base
    +{
    +  const char16_t* typeName() const override {
    +    return concreteTypeName;
    +  }
    +
    +  UniquePtr edges(JSContext* cx, bool wantNames) const override {
    +    return UniquePtr(js_new(cx, get().edges));
    +  }
    +
    +  size_t size(mozilla::MallocSizeOf) const override {
    +    return get().size;
    +  }
    +
    +  JS::Zone* zone() const override {
    +    return get().zone;
    +  }
    +
    +  JSCompartment* compartment() const override {
    +    return get().compartment;
    +  }
    +
    +protected:
    +  explicit Concrete(FakeNode* ptr) : Base(ptr) { }
    +  FakeNode& get() const { return *static_cast(ptr); }
    +
    +public:
    +  static const char16_t concreteTypeName[];
    +  static void construct(void* storage, FakeNode* ptr) {
    +    new (storage) Concrete(ptr);
    +  }
    +};
    +
    +const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("FakeNode");
    +
    +} // namespace ubi
    +} // namespace JS
    +
    +void AddEdge(FakeNode &node, FakeNode &referent, const char16_t *edgeName = nullptr) {
    +  char16_t *ownedEdgeName = nullptr;
    +  if (edgeName) {
    +    ownedEdgeName = NS_strdup(edgeName);
    +    ASSERT_NE(ownedEdgeName, nullptr);
    +  }
    +
    +  JS::ubi::SimpleEdge edge(ownedEdgeName, &referent);
    +  ASSERT_TRUE(node.edges.append(mozilla::Move(edge)));
    +}
    +
    +
    +// Custom GMock Matchers
    +
    +// Use the testing namespace to avoid static analysis failures in the gmock
    +// matcher classes that get generated from MATCHER_P macros.
    +namespace testing {
    +
    +// Ensure that given node has the expected number of edges.
    +MATCHER_P2(EdgesLength, cx, expectedLength, "") {
    +  auto edges = arg.edges(cx);
    +  if (!edges)
    +    return false;
    +
    +  int actualLength = 0;
    +  for ( ; !edges->empty(); edges->popFront())
    +    actualLength++;
    +
    +  return Matcher(Eq(expectedLength))
    +    .MatchAndExplain(actualLength, result_listener);
    +}
    +
    +// Get the nth edge and match it with the given matcher.
    +MATCHER_P3(Edge, cx, n, matcher, "") {
    +  auto edges = arg.edges(cx);
    +  if (!edges)
    +    return false;
    +
    +  int i = 0;
    +  for ( ; !edges->empty(); edges->popFront()) {
    +    if (i == n) {
    +      return Matcher(matcher)
    +        .MatchAndExplain(edges->front(), result_listener);
    +    }
    +
    +    i++;
    +  }
    +
    +  return false;
    +}
    +
    +// Ensures that two char16_t* strings are equal.
    +MATCHER_P(UTF16StrEq, str, "") {
    +  return NS_strcmp(arg, str) == 0;
    +}
    +
    +} // namespace testing
    +
    +
    +// A mock `Writer` class to be used with testing `WriteHeapGraph`.
    +class MockWriter : public CoreDumpWriter
    +{
    +public:
    +  virtual ~MockWriter() override { }
    +  MOCK_METHOD2(writeNode, bool(const JS::ubi::Node &, CoreDumpWriter::EdgePolicy));
    +  MOCK_METHOD1(writeMetadata, bool(uint64_t));
    +};
    +
    +void ExpectWriteNode(MockWriter &writer, FakeNode &node) {
    +  EXPECT_CALL(writer, writeNode(Eq(JS::ubi::Node(&node)), _))
    +    .Times(1)
    +    .WillOnce(Return(true));
    +}
    +
    +#endif // mozilla_devtools_gtest_DevTools__
    diff --git a/toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp b/toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp
    new file mode 100644
    index 000000000000..9bc92fa33485
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp
    @@ -0,0 +1,70 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +// Test that heap snapshots cross zone boundaries when expected.
    +
    +#include "DevTools.h"
    +
    +DEF_TEST(DoesCrossZoneBoundaries, {
    +    // Create a new global to get a new zone.
    +    JS::RootedObject newGlobal(cx, JS_NewGlobalObject(cx,
    +                                                      getGlobalClass(),
    +                                                      nullptr,
    +                                                      JS::FireOnNewGlobalHook));
    +    ASSERT_TRUE(newGlobal);
    +    JS::Zone *newZone = nullptr;
    +    {
    +      JSAutoCompartment ac(cx, newGlobal);
    +      ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal));
    +      newZone = js::GetContextZone(cx);
    +    }
    +    ASSERT_TRUE(newZone);
    +    ASSERT_NE(newZone, zone);
    +
    +    // Our set of target zones is both the old and new zones.
    +    JS::ZoneSet targetZones;
    +    ASSERT_TRUE(targetZones.init());
    +    ASSERT_TRUE(targetZones.put(zone));
    +    ASSERT_TRUE(targetZones.put(newZone));
    +
    +    FakeNode nodeA(cx);
    +    FakeNode nodeB(cx);
    +    FakeNode nodeC(cx);
    +    FakeNode nodeD(cx);
    +
    +    nodeA.zone = zone;
    +    nodeB.zone = nullptr;
    +    nodeC.zone = newZone;
    +    nodeD.zone = nullptr;
    +
    +    AddEdge(nodeA, nodeB);
    +    AddEdge(nodeA, nodeC);
    +    AddEdge(nodeB, nodeD);
    +
    +    ::testing::NiceMock writer;
    +
    +    // Should serialize nodeA, because it is in one of our target zones.
    +    ExpectWriteNode(writer, nodeA);
    +
    +    // Should serialize nodeB, because it doesn't belong to a zone and is
    +    // therefore assumed to be shared.
    +    ExpectWriteNode(writer, nodeB);
    +
    +    // Should also serialize nodeC, which is in our target zones, but a
    +    // different zone than A.
    +    ExpectWriteNode(writer, nodeC);
    +
    +    // However, should not serialize nodeD because nodeB doesn't belong to one
    +    // of our target zones and so its edges are excluded from serialization.
    +
    +    JS::AutoCheckCannotGC noGC(rt);
    +
    +    ASSERT_TRUE(WriteHeapGraph(cx,
    +                               JS::ubi::Node(&nodeA),
    +                               writer,
    +                               /* wantNames = */ false,
    +                               &targetZones,
    +                               noGC));
    +  });
    diff --git a/toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp b/toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp
    new file mode 100644
    index 000000000000..cbfa9999e5f5
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp
    @@ -0,0 +1,62 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +// Test that heap snapshots walk the zone boundaries correctly.
    +
    +#include "DevTools.h"
    +
    +DEF_TEST(DoesntCrossZoneBoundaries, {
    +    // Create a new global to get a new zone.
    +    JS::RootedObject newGlobal(cx, JS_NewGlobalObject(cx,
    +                                                      getGlobalClass(),
    +                                                      nullptr,
    +                                                      JS::FireOnNewGlobalHook));
    +    ASSERT_TRUE(newGlobal);
    +    JS::Zone *newZone = nullptr;
    +    {
    +      JSAutoCompartment ac(cx, newGlobal);
    +      ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal));
    +      newZone = js::GetContextZone(cx);
    +    }
    +    ASSERT_TRUE(newZone);
    +    ASSERT_NE(newZone, zone);
    +
    +    // Our set of target zones is only the pre-existing zone and does not
    +    // include the new zone.
    +    JS::ZoneSet targetZones;
    +    ASSERT_TRUE(targetZones.init());
    +    ASSERT_TRUE(targetZones.put(zone));
    +
    +    FakeNode nodeA(cx);
    +    FakeNode nodeB(cx);
    +    FakeNode nodeC(cx);
    +
    +    nodeA.zone = zone;
    +    nodeB.zone = nullptr;
    +    nodeC.zone = newZone;
    +
    +    AddEdge(nodeA, nodeB);
    +    AddEdge(nodeB, nodeC);
    +
    +    ::testing::NiceMock writer;
    +
    +    // Should serialize nodeA, because it is in our target zones.
    +    ExpectWriteNode(writer, nodeA);
    +
    +    // Should serialize nodeB, because it doesn't belong to a zone and is
    +    // therefore assumed to be shared.
    +    ExpectWriteNode(writer, nodeB);
    +
    +    // But we shouldn't ever serialize nodeC.
    +
    +    JS::AutoCheckCannotGC noGC(rt);
    +
    +    ASSERT_TRUE(WriteHeapGraph(cx,
    +                               JS::ubi::Node(&nodeA),
    +                               writer,
    +                               /* wantNames = */ false,
    +                               &targetZones,
    +                               noGC));
    +  });
    diff --git a/toolkit/devtools/server/tests/gtest/SerializesEdgeNames.cpp b/toolkit/devtools/server/tests/gtest/SerializesEdgeNames.cpp
    new file mode 100644
    index 000000000000..1af78b81eb84
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/gtest/SerializesEdgeNames.cpp
    @@ -0,0 +1,53 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +// Test that edge names get serialized correctly.
    +
    +#include "DevTools.h"
    +
    +using testing::Field;
    +using testing::IsNull;
    +using testing::Property;
    +using testing::Return;
    +
    +DEF_TEST(SerializesEdgeNames, {
    +    FakeNode node(cx);
    +    FakeNode referent(cx);
    +
    +    const char16_t edgeName[] = MOZ_UTF16("edge name");
    +    const char16_t emptyStr[] = MOZ_UTF16("");
    +
    +    AddEdge(node, referent, edgeName);
    +    AddEdge(node, referent, emptyStr);
    +    AddEdge(node, referent, nullptr);
    +
    +    ::testing::NiceMock writer;
    +
    +    // Should get the node with edges once.
    +    EXPECT_CALL(
    +      writer,
    +      writeNode(AllOf(EdgesLength(cx, 3),
    +                      Edge(cx, 0, Field(&JS::ubi::Edge::name,
    +                                        UTF16StrEq(edgeName))),
    +                      Edge(cx, 1, Field(&JS::ubi::Edge::name,
    +                                        UTF16StrEq(emptyStr))),
    +                      Edge(cx, 2, Field(&JS::ubi::Edge::name,
    +                                        IsNull()))),
    +                _)
    +    )
    +      .Times(1)
    +      .WillOnce(Return(true));
    +
    +    // Should get the referent node that doesn't have any edges once.
    +    ExpectWriteNode(writer, referent);
    +
    +    JS::AutoCheckCannotGC noGC(rt);
    +    ASSERT_TRUE(WriteHeapGraph(cx,
    +                               JS::ubi::Node(&node),
    +                               writer,
    +                               /* wantNames = */ true,
    +                               /* zones = */ nullptr,
    +                               noGC));
    +  });
    diff --git a/toolkit/devtools/server/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp b/toolkit/devtools/server/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp
    new file mode 100644
    index 000000000000..f35f199c44d5
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp
    @@ -0,0 +1,37 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +// Test that everything in the heap graph gets serialized once, and only once.
    +
    +#include "DevTools.h"
    +
    +DEF_TEST(SerializesEverythingInHeapGraphOnce, {
    +    FakeNode nodeA(cx);
    +    FakeNode nodeB(cx);
    +    FakeNode nodeC(cx);
    +    FakeNode nodeD(cx);
    +
    +    AddEdge(nodeA, nodeB);
    +    AddEdge(nodeB, nodeC);
    +    AddEdge(nodeC, nodeD);
    +    AddEdge(nodeD, nodeA);
    +
    +    ::testing::NiceMock writer;
    +
    +    // Should serialize each node once.
    +    ExpectWriteNode(writer, nodeA);
    +    ExpectWriteNode(writer, nodeB);
    +    ExpectWriteNode(writer, nodeC);
    +    ExpectWriteNode(writer, nodeD);
    +
    +    JS::AutoCheckCannotGC noGC(rt);
    +
    +    ASSERT_TRUE(WriteHeapGraph(cx,
    +                               JS::ubi::Node(&nodeA),
    +                               writer,
    +                               /* wantNames = */ false,
    +                               /* zones = */ nullptr,
    +                               noGC));
    +  });
    diff --git a/toolkit/devtools/server/tests/gtest/SerializesTypeNames.cpp b/toolkit/devtools/server/tests/gtest/SerializesTypeNames.cpp
    new file mode 100644
    index 000000000000..250ffb527614
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/gtest/SerializesTypeNames.cpp
    @@ -0,0 +1,30 @@
    +/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    +
    +// Test that a ubi::Node's typeName gets properly serialized into a core dump.
    +
    +#include "DevTools.h"
    +
    +using testing::Property;
    +using testing::Return;
    +
    +DEF_TEST(SerializesTypeNames, {
    +    FakeNode node(cx);
    +
    +    ::testing::NiceMock writer;
    +    EXPECT_CALL(writer, writeNode(Property(&JS::ubi::Node::typeName,
    +                                           UTF16StrEq(MOZ_UTF16("FakeNode"))),
    +                                  _))
    +      .Times(1)
    +      .WillOnce(Return(true));
    +
    +    JS::AutoCheckCannotGC noGC(rt);
    +    ASSERT_TRUE(WriteHeapGraph(cx,
    +                               JS::ubi::Node(&node),
    +                               writer,
    +                               /* wantNames = */ true,
    +                               /* zones = */ nullptr,
    +                               noGC));
    +  });
    diff --git a/toolkit/devtools/server/tests/gtest/moz.build b/toolkit/devtools/server/tests/gtest/moz.build
    new file mode 100644
    index 000000000000..83005c0950aa
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/gtest/moz.build
    @@ -0,0 +1,21 @@
    +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
    +# vim: set filetype=python:
    +# This Source Code Form is subject to the terms of the Mozilla Public
    +# License, v. 2.0. If a copy of the MPL was not distributed with this
    +# file, you can obtain one at http://mozilla.org/MPL/2.0/.
    +
    +Library('devtoolstests')
    +
    +LOCAL_INCLUDES += [
    +    '/toolkit/devtools/server',
    +]
    +
    +UNIFIED_SOURCES = [
    +    'DoesCrossZoneBoundaries.cpp',
    +    'DoesntCrossZoneBoundaries.cpp',
    +    'SerializesEdgeNames.cpp',
    +    'SerializesEverythingInHeapGraphOnce.cpp',
    +    'SerializesTypeNames.cpp',
    +]
    +
    +FINAL_LIBRARY = 'xul-gtest'
    
    From c66579bc0682d41a2299db9a2a6be344260f6c3b Mon Sep 17 00:00:00 2001
    From: Nick Fitzgerald 
    Date: Wed, 22 Apr 2015 11:09:54 -0700
    Subject: [PATCH 218/241] Bug 1024774 - Part 6: Add a mochitest-chrome sanity
     check test. r=bholley
    
    ---
     .../server/tests/mochitest/chrome.ini         |  1 +
     .../mochitest/test_SaveHeapSnapshot.html      | 31 +++++++++++++++++++
     2 files changed, 32 insertions(+)
     create mode 100644 toolkit/devtools/server/tests/mochitest/test_SaveHeapSnapshot.html
    
    diff --git a/toolkit/devtools/server/tests/mochitest/chrome.ini b/toolkit/devtools/server/tests/mochitest/chrome.ini
    index 5215c5671925..65359664dd2c 100644
    --- a/toolkit/devtools/server/tests/mochitest/chrome.ini
    +++ b/toolkit/devtools/server/tests/mochitest/chrome.ini
    @@ -85,3 +85,4 @@ skip-if = buildapp == 'mulet'
     [test_director.html]
     [test_director_connectToChild.html]
     skip-if = buildapp == 'mulet'
    +[test_SaveHeapSnapshot.html]
    diff --git a/toolkit/devtools/server/tests/mochitest/test_SaveHeapSnapshot.html b/toolkit/devtools/server/tests/mochitest/test_SaveHeapSnapshot.html
    new file mode 100644
    index 000000000000..2b94851faecd
    --- /dev/null
    +++ b/toolkit/devtools/server/tests/mochitest/test_SaveHeapSnapshot.html
    @@ -0,0 +1,31 @@
    +
    +
    +
    +
    +  
    +  ChromeUtils.saveHeapSnapshot test
    +  
    +  
    +
    +
    +
    +
    +
    + + From a55c57cabcf1e411696570db444319e6710901ad Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:54 -0700 Subject: [PATCH 219/241] Bug 1024774 - Part 7: Add HeapSnapshot WebIDL interface; r=bholley --- dom/bindings/Bindings.conf | 6 +++++- dom/webidl/ChromeUtils.webidl | 8 ++++++++ dom/webidl/HeapSnapshot.webidl | 12 ++++++++++++ dom/webidl/moz.build | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 dom/webidl/HeapSnapshot.webidl diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 72415e1e3fbd..b1fd33e2d790 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -267,7 +267,7 @@ DOMInterfaces = { # collection of static methods, so we have this `concrete: False` hack. 'concrete': False, 'nativeType': 'mozilla::devtools::ChromeUtils', - 'implicitJSContext': ['saveHeapSnapshot'] + 'implicitJSContext': ['readHeapSnapshot', 'saveHeapSnapshot'] }, 'ChromeWindow': { @@ -501,6 +501,10 @@ DOMInterfaces = { 'headerFile': 'nsGeolocation.h' }, +'HeapSnapshot': { + 'nativeType': 'mozilla::devtools::HeapSnapshot' +}, + 'History': { 'headerFile': 'nsHistory.h', 'nativeType': 'nsHistory' diff --git a/dom/webidl/ChromeUtils.webidl b/dom/webidl/ChromeUtils.webidl index 43ab2b7dd9f4..db373fea98ae 100644 --- a/dom/webidl/ChromeUtils.webidl +++ b/dom/webidl/ChromeUtils.webidl @@ -20,6 +20,14 @@ interface ChromeUtils { [Throws] static void saveHeapSnapshot(DOMString filePath, optional HeapSnapshotBoundaries boundaries); + + /** + * Deserialize a core dump into a HeapSnapshot. + * + * @param filePath The file path to read the core dump from. + */ + [Throws, NewObject] + static HeapSnapshot readHeapSnapshot(DOMString filePath); }; /** diff --git a/dom/webidl/HeapSnapshot.webidl b/dom/webidl/HeapSnapshot.webidl new file mode 100644 index 000000000000..4b4068318c9f --- /dev/null +++ b/dom/webidl/HeapSnapshot.webidl @@ -0,0 +1,12 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/** + * A HeapSnapshot represents a snapshot of the heap graph + */ +[ChromeOnly, Exposed=(Window,System)] +interface HeapSnapshot { +}; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 5a4ff936dab3..18461badf8b4 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -158,6 +158,7 @@ WEBIDL_FILES = [ 'GetUserMediaRequest.webidl', 'HDMIInputPort.webidl', 'Headers.webidl', + 'HeapSnapshot.webidl', 'History.webidl', 'HTMLAllCollection.webidl', 'HTMLAnchorElement.webidl', From 0e6dcee57246a4d33c90b6e6eadd5fb3b90771f8 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:54 -0700 Subject: [PATCH 220/241] Bug 1024774 - Part 8: Add JS::ubi::Node::isLive; r=jimb --- js/public/UbiNode.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h index e17690e89fac..fc8b4855ced4 100644 --- a/js/public/UbiNode.h +++ b/js/public/UbiNode.h @@ -187,6 +187,11 @@ class Base { } bool operator!=(const Base& rhs) const { return !(*this == rhs); } + // Returns true if this node is pointing to something on the live heap, as + // opposed to something from a deserialized core dump. Returns false, + // otherwise. + virtual bool isLive() const { return true; }; + // Return a human-readable name for the referent's type. The result should // be statically allocated. (You can use MOZ_UTF16("strings") for this.) // @@ -321,6 +326,8 @@ class Node { return base()->ptr != nullptr; } + bool isLive() const { return base()->isLive(); } + template bool is() const { return base()->typeName() == Concrete::concreteTypeName; @@ -328,12 +335,14 @@ class Node { template T* as() const { + MOZ_ASSERT(isLive()); MOZ_ASSERT(is()); return static_cast(base()->ptr); } template T* asOrNull() const { + MOZ_ASSERT(isLive()); return is() ? static_cast(base()->ptr) : nullptr; } From 5689b01c3ab1dc7e5543de3ff7e0c749668fea32 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:54 -0700 Subject: [PATCH 221/241] Bug 1024774 - Part 9: Deserialize heap snapshots; r=jimb --- toolkit/devtools/server/ChromeUtils.cpp | 52 ++++- toolkit/devtools/server/ChromeUtils.h | 9 + toolkit/devtools/server/DeserializedNode.cpp | 109 +++++++++++ toolkit/devtools/server/DeserializedNode.h | 91 +++++++++ toolkit/devtools/server/HeapSnapshot.cpp | 194 +++++++++++++++++++ toolkit/devtools/server/HeapSnapshot.h | 133 +++++++++++++ toolkit/devtools/server/moz.build | 4 + xpcom/glue/nsCRTGlue.cpp | 18 ++ xpcom/glue/nsCRTGlue.h | 5 + 9 files changed, 612 insertions(+), 3 deletions(-) create mode 100644 toolkit/devtools/server/DeserializedNode.cpp create mode 100644 toolkit/devtools/server/DeserializedNode.h create mode 100644 toolkit/devtools/server/HeapSnapshot.cpp create mode 100644 toolkit/devtools/server/HeapSnapshot.h diff --git a/toolkit/devtools/server/ChromeUtils.cpp b/toolkit/devtools/server/ChromeUtils.cpp index 7d13abd015ae..db291198f61e 100644 --- a/toolkit/devtools/server/ChromeUtils.cpp +++ b/toolkit/devtools/server/ChromeUtils.cpp @@ -21,6 +21,7 @@ #include "prtypes.h" #include "js/Debug.h" +#include "js/TypeDecls.h" #include "js/UbiNodeTraverse.h" namespace mozilla { @@ -170,8 +171,8 @@ EstablishBoundaries(JSContext *cx, } -// A `CoreDumpWriter` that serializes nodes to protobufs and writes them to -// the given `CodedOutputStream`. +// A `CoreDumpWriter` that serializes nodes to protobufs and writes them to the +// given `ZeroCopyOutputStream`. class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter { JSContext *cx; @@ -382,5 +383,50 @@ ChromeUtils::SaveHeapSnapshot(GlobalObject &global, } } +/* static */ already_AddRefed +ChromeUtils::ReadHeapSnapshot(GlobalObject &global, + JSContext *cx, + const nsAString &filePath, + ErrorResult &rv) +{ + UniquePtr path(ToNewCString(filePath)); + if (!path) { + rv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + + PRFileInfo fileInfo; + if (PR_GetFileInfo(path.get(), &fileInfo) != PR_SUCCESS) { + rv.Throw(NS_ERROR_FILE_NOT_FOUND); + return nullptr; + } + + uint32_t size = fileInfo.size; + ScopedFreePtr buffer(static_cast(malloc(size))); + if (!buffer) { + rv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + + PRFileDesc *fd = PR_Open(path.get(), PR_RDONLY, 0); + if (!fd) { + rv.Throw(NS_ERROR_UNEXPECTED); + return nullptr; + } + + uint32_t bytesRead = 0; + while (bytesRead < size) { + uint32_t bytesLeft = size - bytesRead; + int32_t bytesReadThisTime = PR_Read(fd, buffer.get() + bytesRead, bytesLeft); + if (bytesReadThisTime < 1) { + rv.Throw(NS_ERROR_UNEXPECTED); + return nullptr; + } + bytesRead += bytesReadThisTime; + } + + return HeapSnapshot::Create(cx, global, buffer.get(), size, rv); } -} + +} // namespace devtools +} // namespace mozilla diff --git a/toolkit/devtools/server/ChromeUtils.h b/toolkit/devtools/server/ChromeUtils.h index 211e755872f4..efbed444c3f3 100644 --- a/toolkit/devtools/server/ChromeUtils.h +++ b/toolkit/devtools/server/ChromeUtils.h @@ -12,6 +12,7 @@ #include "js/UbiNode.h" #include "js/UbiNodeTraverse.h" +#include "mozilla/AlreadyAddRefed.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/ChromeUtilsBinding.h" @@ -56,6 +57,9 @@ WriteHeapGraph(JSContext *cx, JS::AutoCheckCannotGC &noGC); +class HeapSnapshot; + + class ChromeUtils { public: @@ -64,6 +68,11 @@ public: const nsAString &filePath, const dom::HeapSnapshotBoundaries &boundaries, ErrorResult &rv); + + static already_AddRefed ReadHeapSnapshot(dom::GlobalObject &global, + JSContext *cx, + const nsAString &filePath, + ErrorResult &rv); }; } // namespace devtools diff --git a/toolkit/devtools/server/DeserializedNode.cpp b/toolkit/devtools/server/DeserializedNode.cpp new file mode 100644 index 000000000000..db1515f414d8 --- /dev/null +++ b/toolkit/devtools/server/DeserializedNode.cpp @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/devtools/DeserializedNode.h" + +namespace mozilla { +namespace devtools { + +DeserializedEdge::DeserializedEdge() + : referent(0) + , name(nullptr) +{ } + +DeserializedEdge::DeserializedEdge(DeserializedEdge &&rhs) +{ + referent = rhs.referent; + name = rhs.name; +} + +DeserializedEdge &DeserializedEdge::operator=(DeserializedEdge &&rhs) +{ + MOZ_ASSERT(&rhs != this); + this->~DeserializedEdge(); + new(this) DeserializedEdge(Move(rhs)); + return *this; +} + +bool +DeserializedEdge::init(const protobuf::Edge &edge, HeapSnapshot &owner) +{ + // Although the referent property is optional in the protobuf format for + // future compatibility, we can't semantically have an edge to nowhere and + // require a referent here. + if (!edge.has_referent()) + return false; + referent = edge.referent(); + + if (edge.has_name()) { + const char16_t* duplicateEdgeName = reinterpret_cast(edge.name().c_str()); + name = owner.borrowUniqueString(duplicateEdgeName, edge.name().length() / sizeof(char16_t)); + if (!name) + return false; + } + + return true; +} + +/* static */ UniquePtr +DeserializedNode::Create(const protobuf::Node &node, HeapSnapshot &owner) +{ + if (!node.has_id()) + return nullptr; + NodeId id = node.id(); + + if (!node.has_typename_()) + return nullptr; + + const char16_t* duplicatedTypeName = reinterpret_cast(node.typename_().c_str()); + const char16_t* uniqueTypeName = owner.borrowUniqueString(duplicatedTypeName, + node.typename_().length() / sizeof(char16_t)); + if (!uniqueTypeName) + return nullptr; + + auto edgesLength = node.edges_size(); + EdgeVector edges; + if (!edges.reserve(edgesLength)) + return nullptr; + for (decltype(edgesLength) i = 0; i < edgesLength; i++) { + DeserializedEdge edge; + if (!edge.init(node.edges(i), owner)) + return nullptr; + edges.infallibleAppend(Move(edge)); + } + + if (!node.has_size()) + return nullptr; + uint64_t size = node.size(); + + return MakeUnique(id, + uniqueTypeName, + size, + Move(edges), + owner); +} + +DeserializedNode::DeserializedNode(NodeId id, + const char16_t *typeName, + uint64_t size, + EdgeVector &&edges, + HeapSnapshot &owner) + : id(id) + , typeName(typeName) + , size(size) + , edges(Move(edges)) + , owner(&owner) +{ } + +DeserializedNode & +DeserializedNode::getEdgeReferent(const DeserializedEdge &edge) +{ + auto ptr = owner->nodes.lookup(edge.referent); + MOZ_ASSERT(ptr); + return *ptr->value(); +} + +} // namespace devtools +} // namespace mozilla diff --git a/toolkit/devtools/server/DeserializedNode.h b/toolkit/devtools/server/DeserializedNode.h new file mode 100644 index 000000000000..b1b3218e8604 --- /dev/null +++ b/toolkit/devtools/server/DeserializedNode.h @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_devtools_DeserializedNode__ +#define mozilla_devtools_DeserializedNode__ + +#include "mozilla/devtools/CoreDump.pb.h" +#include "mozilla/MaybeOneOf.h" +#include "mozilla/Move.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Vector.h" + +// `Deserialized{Node,Edge}` translate protobuf messages from our core dump +// format into structures we can rely upon for implementing `JS::ubi::Node` +// specializations on top of. All of the properties of the protobuf messages are +// optional for future compatibility, and this is the layer where we validate +// that the properties that do actually exist in any given message fulfill our +// semantic requirements. +// +// Both `DeserializedNode` and `DeserializedEdge` are always owned by a +// `HeapSnapshot` instance, and their lifetimes must not extend after that of +// their owning `HeapSnapshot`. + +namespace mozilla { +namespace devtools { + +class HeapSnapshot; + +using NodeId = uint64_t; + +// A `DeserializedEdge` represents an edge in the heap graph pointing to the +// node with id equal to `DeserializedEdge::referent` that we deserialized from +// a core dump. +struct DeserializedEdge { + NodeId referent; + // A borrowed reference to a string owned by this node's owning HeapSnapshot. + const char16_t *name; + + explicit DeserializedEdge(); + DeserializedEdge(DeserializedEdge &&rhs); + DeserializedEdge &operator=(DeserializedEdge &&rhs); + + // Initialize this `DeserializedEdge` from the given `protobuf::Edge` message. + bool init(const protobuf::Edge &edge, HeapSnapshot &owner); + +private: + DeserializedEdge(const DeserializedEdge &) = delete; + DeserializedEdge& operator=(const DeserializedEdge &) = delete; +}; + +// A `DeserializedNode` is a node in the heap graph that we deserialized from a +// core dump. +struct DeserializedNode { + using EdgeVector = Vector; + using UniqueStringPtr = UniquePtr; + + NodeId id; + // A borrowed reference to a string owned by this node's owning HeapSnapshot. + const char16_t *typeName; + uint64_t size; + EdgeVector edges; + // A weak pointer to this node's owning `HeapSnapshot`. Safe without + // AddRef'ing because this node's lifetime is equal to that of its owner. + HeapSnapshot *owner; + + // Create a new `DeserializedNode` from the given `protobuf::Node` message. + static UniquePtr Create(const protobuf::Node &node, + HeapSnapshot &owner); + + DeserializedNode(NodeId id, + const char16_t *typeName, + uint64_t size, + EdgeVector &&edges, + HeapSnapshot &owner); + virtual ~DeserializedNode() { } + + // Get a borrowed reference to the given edge's referent. This method is + // virtual to provide a hook for gmock and gtest. + virtual DeserializedNode &getEdgeReferent(const DeserializedEdge &edge); + +private: + DeserializedNode(const DeserializedNode &) = delete; + DeserializedNode &operator=(const DeserializedNode &) = delete; +}; + +} // namespace devtools +} // namespace mozilla + +#endif // mozilla_devtools_DeserializedNode__ diff --git a/toolkit/devtools/server/HeapSnapshot.cpp b/toolkit/devtools/server/HeapSnapshot.cpp new file mode 100644 index 000000000000..4b61e4eb3e64 --- /dev/null +++ b/toolkit/devtools/server/HeapSnapshot.cpp @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HeapSnapshot.h" + +#include +#include +#include + +#include "mozilla/devtools/DeserializedNode.h" +#include "mozilla/dom/HeapSnapshotBinding.h" + +#include "CoreDump.pb.h" +#include "nsCycleCollectionParticipant.h" +#include "nsCRTGlue.h" +#include "nsISupportsImpl.h" + +namespace mozilla { +namespace devtools { + +using ::google::protobuf::io::ArrayInputStream; +using ::google::protobuf::io::CodedInputStream; +using ::google::protobuf::io::GzipInputStream; +using ::google::protobuf::io::ZeroCopyInputStream; + +NS_IMPL_CYCLE_COLLECTION_CLASS(HeapSnapshot) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HeapSnapshot) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(HeapSnapshot) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(HeapSnapshot) + NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(HeapSnapshot) +NS_IMPL_CYCLE_COLLECTING_RELEASE(HeapSnapshot) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HeapSnapshot) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +/* virtual */ JSObject * +HeapSnapshot::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return dom::HeapSnapshotBinding::Wrap(aCx, this, aGivenProto); +} + +/* static */ already_AddRefed +HeapSnapshot::Create(JSContext *cx, + dom::GlobalObject &global, + const uint8_t *buffer, + uint32_t size, + ErrorResult &rv) +{ + nsRefPtr snapshot = new HeapSnapshot(cx, global.GetAsSupports()); + if (!snapshot->init(buffer, size)) { + rv.Throw(NS_ERROR_UNEXPECTED); + return nullptr; + } + return snapshot.forget(); +} + +template +static bool +parseMessage(ZeroCopyInputStream &stream, MessageType &message) +{ + // We need to create a new `CodedInputStream` for each message so that the + // 64MB limit is applied per-message rather than to the whole stream. + CodedInputStream codedStream(&stream); + + // Because protobuf messages aren't self-delimiting, we serialize each message + // preceeded by its size in bytes. When deserializing, we read this size and + // then limit reading from the stream to the given byte size. If we didn't, + // then the first message would consume the entire stream. + + uint32_t size = 0; + if (NS_WARN_IF(!codedStream.ReadVarint32(&size))) + return false; + + auto limit = codedStream.PushLimit(size); + if (NS_WARN_IF(!message.ParseFromCodedStream(&codedStream)) || + NS_WARN_IF(!codedStream.ConsumedEntireMessage())) + { + return false; + } + + codedStream.PopLimit(limit); + return true; +} + +bool +HeapSnapshot::saveNode(const protobuf::Node &node) +{ + UniquePtr dn(DeserializedNode::Create(node, *this)); + if (!dn) + return false; + return nodes.put(dn->id, Move(dn)); +} + +static inline bool +StreamHasData(GzipInputStream &stream) +{ + // Test for the end of the stream. The protobuf library gives no way to tell + // the difference between an underlying read error and the stream being + // done. All we can do is attempt to read data and extrapolate guestimations + // from the result of that operation. + + const void *buf; + int size; + bool more = stream.Next(&buf, &size); + if (!more) + // Could not read any more data. We are optimistic and assume the stream is + // just exhausted and there is not an underlying IO error, since this + // function is only called at message boundaries. + return false; + + // There is more data still available in the stream. Return the data we read + // to the stream and let the parser get at it. + stream.BackUp(size); + return true; +} + +bool +HeapSnapshot::init(const uint8_t *buffer, uint32_t size) +{ + if (!nodes.init() || !strings.init()) + return false; + + ArrayInputStream stream(buffer, size); + GzipInputStream gzipStream(&stream); + + // First is the metadata. + + protobuf::Metadata metadata; + if (!parseMessage(gzipStream, metadata)) + return false; + if (metadata.has_timestamp()) + timestamp.emplace(metadata.timestamp()); + + // Next is the root node. + + protobuf::Node root; + if (!parseMessage(gzipStream, root)) + return false; + + // Although the id is optional in the protobuf format for future proofing, we + // can't currently do anything without it. + if (NS_WARN_IF(!root.has_id())) + return false; + rootId = root.id(); + + if (NS_WARN_IF(!saveNode(root))) + return false; + + // Finally, the rest of the nodes in the core dump. + + while (StreamHasData(gzipStream)) { + protobuf::Node node; + if (!parseMessage(gzipStream, node)) + return false; + if (NS_WARN_IF(!saveNode(node))) + return false; + } + + return true; +} + +const char16_t* +HeapSnapshot::borrowUniqueString(const char16_t* duplicateString, size_t length) +{ + MOZ_ASSERT(duplicateString); + UniqueStringHashPolicy::Lookup lookup(duplicateString, length); + auto ptr = strings.lookupForAdd(lookup); + + if (!ptr) { + UniqueString owned(NS_strndup(duplicateString, length)); + if (!owned || !strings.add(ptr, Move(owned))) + return nullptr; + } + + MOZ_ASSERT(ptr->get() != duplicateString); + return ptr->get(); +} + + +} // namespace devtools +} // namespace mozilla diff --git a/toolkit/devtools/server/HeapSnapshot.h b/toolkit/devtools/server/HeapSnapshot.h new file mode 100644 index 000000000000..9d14c829633e --- /dev/null +++ b/toolkit/devtools/server/HeapSnapshot.h @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_devtools_HeapSnapshot__ +#define mozilla_devtools_HeapSnapshot__ + +#include "js/HashTable.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/devtools/DeserializedNode.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/HashFunctions.h" +#include "mozilla/Maybe.h" +#include "mozilla/RefPtr.h" +#include "mozilla/UniquePtr.h" + +#include "CoreDump.pb.h" +#include "nsCOMPtr.h" +#include "nsCRTGlue.h" +#include "nsCycleCollectionParticipant.h" +#include "nsISupports.h" +#include "nsWrapperCache.h" +#include "nsXPCOM.h" + +namespace mozilla { +namespace devtools { + +struct NSFreePolicy { + void operator()(void* ptr) { + NS_Free(ptr); + } +}; + +using UniqueString = UniquePtr; + +struct UniqueStringHashPolicy { + struct Lookup { + const char16_t* str; + size_t length; + + Lookup(const char16_t* str, size_t length) + : str(str) + , length(length) + { } + }; + + static js::HashNumber hash(const Lookup& lookup) { + MOZ_ASSERT(lookup.str); + return HashString(lookup.str, lookup.length); + } + + static bool match(const UniqueString& existing, const Lookup& lookup) { + MOZ_ASSERT(lookup.str); + return NS_strncmp(existing.get(), lookup.str, lookup.length) == 0; + } +}; + +class HeapSnapshot final : public nsISupports + , public nsWrapperCache +{ + friend struct DeserializedNode; + + explicit HeapSnapshot(JSContext *cx, nsISupports *aParent) + : timestamp(Nothing()) + , rootId(0) + , nodes(cx) + , strings(cx) + , mParent(aParent) + { + MOZ_ASSERT(aParent); + }; + + // Initialize this HeapSnapshot from the given buffer that contains a + // serialized core dump. Do NOT take ownership of the buffer, only borrow it + // for the duration of the call. Return false on failure. + bool init(const uint8_t *buffer, uint32_t size); + + // Save the given `protobuf::Node` message in this `HeapSnapshot` as a + // `DeserializedNode`. + bool saveNode(const protobuf::Node &node); + + // If present, a timestamp in the same units that `PR_Now` gives. + Maybe timestamp; + + // The id of the root node for this deserialized heap graph. + NodeId rootId; + + // The set of nodes in this deserialized heap graph, keyed by id. + using NodeMap = js::HashMap>; + NodeMap nodes; + + // Core dump files have many duplicate strings: type names are repeated for + // each node, and although in theory edge names are highly customizable for + // specific edges, in practice they are also highly duplicated. Rather than + // make each Deserialized{Node,Edge} malloc their own copy of their edge and + // type names, we de-duplicate the strings here and Deserialized{Node,Edge} + // get borrowed pointers into this set. + using UniqueStringSet = js::HashSet; + UniqueStringSet strings; + +protected: + nsCOMPtr mParent; + + virtual ~HeapSnapshot() { } + +public: + // Create a `HeapSnapshot` from the given buffer that contains a serialized + // core dump. Do NOT take ownership of the buffer, only borrow it for the + // duration of the call. + static already_AddRefed Create(JSContext *cx, + dom::GlobalObject &global, + const uint8_t *buffer, + uint32_t size, + ErrorResult &rv); + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HeapSnapshot) + MOZ_DECLARE_REFCOUNTED_TYPENAME(HeapSnapshot) + + nsISupports *GetParentObject() const { return mParent; } + + virtual JSObject *WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + const char16_t* borrowUniqueString(const char16_t* duplicateString, + size_t length); +}; + +} // namespace devtools +} // namespace mozilla + +#endif // mozilla_devtools_HeapSnapshot__ diff --git a/toolkit/devtools/server/moz.build b/toolkit/devtools/server/moz.build index b4fcdca05b26..1cedd326048a 100644 --- a/toolkit/devtools/server/moz.build +++ b/toolkit/devtools/server/moz.build @@ -20,12 +20,16 @@ XPIDL_MODULE = 'jsinspector' EXPORTS.mozilla.devtools += [ 'ChromeUtils.h', 'CoreDump.pb.h', + 'DeserializedNode.h', + 'HeapSnapshot.h', 'ZeroCopyNSIOutputStream.h', ] SOURCES += [ 'ChromeUtils.cpp', 'CoreDump.pb.cc', + 'DeserializedNode.cpp', + 'HeapSnapshot.cpp', 'nsJSInspector.cpp', 'ZeroCopyNSIOutputStream.cpp', ] diff --git a/xpcom/glue/nsCRTGlue.cpp b/xpcom/glue/nsCRTGlue.cpp index c2fdbede0d37..17c034932cdc 100644 --- a/xpcom/glue/nsCRTGlue.cpp +++ b/xpcom/glue/nsCRTGlue.cpp @@ -76,6 +76,7 @@ NS_strtok(const char* aDelims, char** aStr) uint32_t NS_strlen(const char16_t* aString) { + MOZ_ASSERT(aString); const char16_t* end; for (end = aString; *end; ++end) { @@ -101,6 +102,23 @@ NS_strcmp(const char16_t* aStrA, const char16_t* aStrB) return *aStrA != '\0'; } +int +NS_strncmp(const char16_t* aStrA, const char16_t* aStrB, size_t aLen) +{ + while (aLen && *aStrB) { + int r = *aStrA - *aStrB; + if (r) { + return r; + } + + ++aStrA; + ++aStrB; + --aLen; + } + + return aLen ? *aStrA != '\0' : *aStrA - *aStrB; +} + char16_t* NS_strdup(const char16_t* aString) { diff --git a/xpcom/glue/nsCRTGlue.h b/xpcom/glue/nsCRTGlue.h index 1c10611a0e11..4e59c137c455 100644 --- a/xpcom/glue/nsCRTGlue.h +++ b/xpcom/glue/nsCRTGlue.h @@ -47,6 +47,11 @@ uint32_t NS_strlen(const char16_t* aString); */ int NS_strcmp(const char16_t* aStrA, const char16_t* aStrB); +/** + * "strncmp" for char16_t strings + */ +int NS_strncmp(const char16_t* aStrA, const char16_t* aStrB, size_t aLen); + /** * "strdup" for char16_t strings, uses the NS_Alloc allocator. */ From d000a5ce4058e7f67301af0f18dc1a4dd69fef2f Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:54 -0700 Subject: [PATCH 222/241] Bug 1024774 - Part 10: Add an xpcshell test for reading heap snapshots. r=jimb --- .../tests/unit/test_ReadHeapSnapshot.js | 22 +++++++++++++++++++ .../devtools/server/tests/unit/xpcshell.ini | 1 + 2 files changed, 23 insertions(+) create mode 100644 toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js diff --git a/toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js b/toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js new file mode 100644 index 000000000000..44e91a209a9b --- /dev/null +++ b/toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js @@ -0,0 +1,22 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Test that we can read core dumps into HeapSnapshot instances. + +const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {}); +var Debugger; +addDebuggerToGlobal(this); + +function run_test() { + const filePath = getFilePath("core-dump.tmp", true, true); + ok(filePath, "Should get a file path"); + + ChromeUtils.saveHeapSnapshot(filePath, { globals: [this] }); + ok(true, "Should be able to save a snapshot."); + + const snapshot = ChromeUtils.readHeapSnapshot(filePath); + ok(snapshot, "Should be able to read a heap snapshot"); + ok(snapshot instanceof HeapSnapshot, "Should be an instanceof HeapSnapshot"); + + do_test_finished(); +} diff --git a/toolkit/devtools/server/tests/unit/xpcshell.ini b/toolkit/devtools/server/tests/unit/xpcshell.ini index 90753c9f88f5..e9b725a24c8d 100644 --- a/toolkit/devtools/server/tests/unit/xpcshell.ini +++ b/toolkit/devtools/server/tests/unit/xpcshell.ini @@ -41,6 +41,7 @@ support-files = [test_getyoungestframe.js] [test_nsjsinspector.js] [test_SaveHeapSnapshot.js] +[test_ReadHeapSnapshot.js] [test_dbgactor.js] [test_dbgglobal.js] [test_dbgclient_debuggerstatement.js] From b9bae0d8876fb35ef50602a05df1aad356a70e3d Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:54 -0700 Subject: [PATCH 223/241] Bug 1024774 - Part 11: Implement a JS::ubi::Node specialization for DeserializedNode; r=jimb --- js/public/UbiNode.h | 31 +++---- toolkit/devtools/server/DeserializedNode.cpp | 85 ++++++++++++++++++++ toolkit/devtools/server/DeserializedNode.h | 36 +++++++++ 3 files changed, 138 insertions(+), 14 deletions(-) diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h index fc8b4855ced4..1f4256f645b5 100644 --- a/js/public/UbiNode.h +++ b/js/public/UbiNode.h @@ -187,6 +187,21 @@ class Base { } bool operator!=(const Base& rhs) const { return !(*this == rhs); } + // An identifier for this node, guaranteed to be stable and unique for as + // long as this ubi::Node's referent is alive and at the same address. + // + // This is probably suitable for use in serializations, as it is an integral + // type. It may also help save memory when constructing HashSets of + // ubi::Nodes: since a uintptr_t will always be smaller than a ubi::Node, a + // HashSet will use less space per element than a + // HashSet. + // + // (Note that 'unique' only means 'up to equality on ubi::Node'; see the + // caveats about multiple objects allocated at the same address for + // 'ubi::Node::operator=='.) + typedef uintptr_t Id; + virtual Id identifier() const { return reinterpret_cast(ptr); } + // Returns true if this node is pointing to something on the live heap, as // opposed to something from a deserialized core dump. Returns false, // otherwise. @@ -365,20 +380,8 @@ class Node { return base()->edges(cx, wantNames); } - // An identifier for this node, guaranteed to be stable and unique for as - // long as this ubi::Node's referent is alive and at the same address. - // - // This is probably suitable for use in serializations, as it is an integral - // type. It may also help save memory when constructing HashSets of - // ubi::Nodes: since a uintptr_t will always be smaller than a ubi::Node, a - // HashSet will use less space per element than a - // HashSet. - // - // (Note that 'unique' only means 'up to equality on ubi::Node'; see the - // caveats about multiple objects allocated at the same address for - // 'ubi::Node::operator=='.) - typedef uintptr_t Id; - Id identifier() const { return reinterpret_cast(base()->ptr); } + typedef Base::Id Id; + Id identifier() const { return base()->identifier(); } // A hash policy for ubi::Nodes. // This simply uses the stock PointerHasher on the ubi::Node's pointer. diff --git a/toolkit/devtools/server/DeserializedNode.cpp b/toolkit/devtools/server/DeserializedNode.cpp index db1515f414d8..08d104c2b079 100644 --- a/toolkit/devtools/server/DeserializedNode.cpp +++ b/toolkit/devtools/server/DeserializedNode.cpp @@ -4,6 +4,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/devtools/DeserializedNode.h" +#include "mozilla/devtools/HeapSnapshot.h" +#include "nsCRTGlue.h" namespace mozilla { namespace devtools { @@ -107,3 +109,86 @@ DeserializedNode::getEdgeReferent(const DeserializedEdge &edge) } // namespace devtools } // namespace mozilla + +namespace JS { +namespace ubi { + +using mozilla::devtools::DeserializedEdge; + +const char16_t Concrete::concreteTypeName[] = + MOZ_UTF16("mozilla::devtools::DeserializedNode"); + +const char16_t * +Concrete::typeName() const +{ + return get().typeName; +} + +size_t +Concrete::size(mozilla::MallocSizeOf mallocSizeof) const +{ + return get().size; +} + +class DeserializedEdgeRange : public EdgeRange +{ + SimpleEdgeVector edges; + size_t i; + + void settle() { + front_ = i < edges.length() ? &edges[i] : nullptr; + } + +public: + explicit DeserializedEdgeRange(JSContext* cx) + : edges(cx) + , i(0) + { + settle(); + } + + bool init(DeserializedNode &node) + { + if (!edges.reserve(node.edges.length())) + return false; + + for (DeserializedEdge *edgep = node.edges.begin(); + edgep != node.edges.end(); + edgep++) + { + char16_t *name = nullptr; + if (edgep->name) { + name = NS_strdup(edgep->name); + if (!name) + return false; + } + + DeserializedNode &referent = node.getEdgeReferent(*edgep); + edges.infallibleAppend(mozilla::Move(SimpleEdge(name, Node(&referent)))); + } + + settle(); + return true; + } + + void popFront() override + { + i++; + settle(); + } +}; + +UniquePtr +Concrete::edges(JSContext* cx, bool) const +{ + UniquePtr> range( + js_new(cx)); + + if (!range || !range->init(get())) + return nullptr; + + return UniquePtr(range.release()); +} + +} // namespace JS +} // namespace ubi diff --git a/toolkit/devtools/server/DeserializedNode.h b/toolkit/devtools/server/DeserializedNode.h index b1b3218e8604..b080c078bb75 100644 --- a/toolkit/devtools/server/DeserializedNode.h +++ b/toolkit/devtools/server/DeserializedNode.h @@ -6,6 +6,7 @@ #ifndef mozilla_devtools_DeserializedNode__ #define mozilla_devtools_DeserializedNode__ +#include "js/UbiNode.h" #include "mozilla/devtools/CoreDump.pb.h" #include "mozilla/MaybeOneOf.h" #include "mozilla/Move.h" @@ -88,4 +89,39 @@ private: } // namespace devtools } // namespace mozilla +namespace JS { +namespace ubi { + +using mozilla::devtools::DeserializedNode; +using mozilla::UniquePtr; + +template<> +struct Concrete : public Base +{ +protected: + explicit Concrete(DeserializedNode *ptr) : Base(ptr) { } + DeserializedNode &get() const { + return *static_cast(ptr); + } + +public: + static const char16_t concreteTypeName[]; + + static void construct(void *storage, DeserializedNode *ptr) { + new (storage) Concrete(ptr); + } + + Id identifier() const override { return get().id; } + bool isLive() const override { return false; } + const char16_t *typeName() const override; + size_t size(mozilla::MallocSizeOf mallocSizeof) const override; + + // We ignore the `bool wantNames` parameter because we can't control whether + // the core dump was serialized with edge names or not. + UniquePtr edges(JSContext* cx, bool) const override; +}; + +} // namespace JS +} // namespace ubi + #endif // mozilla_devtools_DeserializedNode__ From c54f2570b37d10f9414ff36696f97bdacfe536bd Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:54 -0700 Subject: [PATCH 224/241] Bug 1024774 - Part 12: Add a GTest for the JS::ubi::Node specialization for DeserializedNode; r=jimb --- toolkit/devtools/server/DeserializedNode.cpp | 8 ++ toolkit/devtools/server/DeserializedNode.h | 4 + .../tests/gtest/DeserializedNodeUbiNodes.cpp | 95 +++++++++++++++++++ toolkit/devtools/server/tests/gtest/moz.build | 1 + 4 files changed, 108 insertions(+) create mode 100644 toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp diff --git a/toolkit/devtools/server/DeserializedNode.cpp b/toolkit/devtools/server/DeserializedNode.cpp index 08d104c2b079..341103fd702d 100644 --- a/toolkit/devtools/server/DeserializedNode.cpp +++ b/toolkit/devtools/server/DeserializedNode.cpp @@ -99,6 +99,14 @@ DeserializedNode::DeserializedNode(NodeId id, , owner(&owner) { } +DeserializedNode::DeserializedNode(NodeId id, const char16_t *typeName, uint64_t size) + : id(id) + , typeName(typeName) + , size(size) + , edges() + , owner(nullptr) +{ } + DeserializedNode & DeserializedNode::getEdgeReferent(const DeserializedEdge &edge) { diff --git a/toolkit/devtools/server/DeserializedNode.h b/toolkit/devtools/server/DeserializedNode.h index b080c078bb75..dcdf82441e74 100644 --- a/toolkit/devtools/server/DeserializedNode.h +++ b/toolkit/devtools/server/DeserializedNode.h @@ -81,6 +81,10 @@ struct DeserializedNode { // virtual to provide a hook for gmock and gtest. virtual DeserializedNode &getEdgeReferent(const DeserializedEdge &edge); +protected: + // This is only for use with `MockDeserializedNode` in testing. + DeserializedNode(NodeId id, const char16_t *typeName, uint64_t size); + private: DeserializedNode(const DeserializedNode &) = delete; DeserializedNode &operator=(const DeserializedNode &) = delete; diff --git a/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp b/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp new file mode 100644 index 000000000000..1795360b798f --- /dev/null +++ b/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Test that the `JS::ubi::Node`s we create from +// `mozilla::devtools::DeserializedNode` instances look and behave as we would +// like. + +#include "DevTools.h" +#include "js/TypeDecls.h" +#include "mozilla/devtools/DeserializedNode.h" + +using testing::Field; +using testing::ReturnRef; + +// A mock DeserializedNode for testing. +struct MockDeserializedNode : public DeserializedNode +{ + MockDeserializedNode(NodeId id, const char16_t *typeName, uint64_t size) + : DeserializedNode(id, typeName, size) + { } + + bool addEdge(DeserializedEdge &&edge) + { + return edges.append(Move(edge)); + } + + MOCK_METHOD1(getEdgeReferent, DeserializedNode &(const DeserializedEdge &)); +}; + +size_t fakeMallocSizeOf(const void *) { + EXPECT_TRUE(false); + MOZ_ASSERT_UNREACHABLE("fakeMallocSizeOf should never be called because " + "DeserializedNodes report the deserialized size."); + return 0; +} + +DEF_TEST(DeserializedNodeUbiNodes, { + const char16_t *typeName = MOZ_UTF16("TestTypeName"); + + NodeId id = 1L << 33; + uint64_t size = 1L << 60; + MockDeserializedNode mocked(id, typeName, size); + + DeserializedNode &deserialized = mocked; + JS::ubi::Node ubi(&deserialized); + + // Test the ubi::Node accessors. + + EXPECT_EQ(size, ubi.size(fakeMallocSizeOf)); + EXPECT_EQ(typeName, ubi.typeName()); + EXPECT_EQ(id, ubi.identifier()); + EXPECT_FALSE(ubi.isLive()); + + // Test the ubi::Node's edges. + + UniquePtr referent1(new MockDeserializedNode(1, + nullptr, + 10)); + DeserializedEdge edge1; + edge1.referent = referent1->id; + mocked.addEdge(Move(edge1)); + EXPECT_CALL(mocked, + getEdgeReferent(Field(&DeserializedEdge::referent, + referent1->id))) + .Times(1) + .WillOnce(ReturnRef(*referent1.get())); + + UniquePtr referent2(new MockDeserializedNode(2, + nullptr, + 20)); + DeserializedEdge edge2; + edge2.referent = referent2->id; + mocked.addEdge(Move(edge2)); + EXPECT_CALL(mocked, + getEdgeReferent(Field(&DeserializedEdge::referent, + referent2->id))) + .Times(1) + .WillOnce(ReturnRef(*referent2.get())); + + UniquePtr referent3(new MockDeserializedNode(3, + nullptr, + 30)); + DeserializedEdge edge3; + edge3.referent = referent3->id; + mocked.addEdge(Move(edge3)); + EXPECT_CALL(mocked, + getEdgeReferent(Field(&DeserializedEdge::referent, + referent3->id))) + .Times(1) + .WillOnce(ReturnRef(*referent3.get())); + + ubi.edges(cx); + }); diff --git a/toolkit/devtools/server/tests/gtest/moz.build b/toolkit/devtools/server/tests/gtest/moz.build index 83005c0950aa..eb78b6ff7ed2 100644 --- a/toolkit/devtools/server/tests/gtest/moz.build +++ b/toolkit/devtools/server/tests/gtest/moz.build @@ -11,6 +11,7 @@ LOCAL_INCLUDES += [ ] UNIFIED_SOURCES = [ + 'DeserializedNodeUbiNodes.cpp', 'DoesCrossZoneBoundaries.cpp', 'DoesntCrossZoneBoundaries.cpp', 'SerializesEdgeNames.cpp', From 6e0841b4f51836728f35b9305e49301ce1ab8eac Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:55 -0700 Subject: [PATCH 225/241] Bug 1024774 - Part 13: Change to new SpiderMonkey style from bug 1144366; r=me --- js/public/Debug.h | 4 +- js/src/jsfriendapi.h | 2 +- js/src/vm/Debugger.cpp | 6 +- js/src/vm/DebuggerMemory.cpp | 2 +- toolkit/devtools/server/ChromeUtils.cpp | 80 +++++++++---------- toolkit/devtools/server/ChromeUtils.h | 30 +++---- toolkit/devtools/server/DeserializedNode.cpp | 30 +++---- toolkit/devtools/server/DeserializedNode.h | 44 +++++----- toolkit/devtools/server/HeapSnapshot.cpp | 20 ++--- toolkit/devtools/server/HeapSnapshot.h | 18 ++--- .../server/ZeroCopyNSIOutputStream.cpp | 4 +- .../devtools/server/ZeroCopyNSIOutputStream.h | 6 +- .../tests/gtest/DeserializedNodeUbiNodes.cpp | 12 +-- .../devtools/server/tests/gtest/DevTools.h | 29 ++++--- .../tests/gtest/DoesCrossZoneBoundaries.cpp | 2 +- .../tests/gtest/DoesntCrossZoneBoundaries.cpp | 2 +- 16 files changed, 145 insertions(+), 146 deletions(-) diff --git a/js/public/Debug.h b/js/public/Debug.h index 3ba915fb55a1..b20b6c3ebe01 100644 --- a/js/public/Debug.h +++ b/js/public/Debug.h @@ -322,12 +322,12 @@ onPromiseSettled(JSContext* cx, HandleObject promise); // Return true if the given value is a Debugger object, false otherwise. JS_PUBLIC_API(bool) -IsDebugger(const JSObject &obj); +IsDebugger(const JSObject& obj); // Append each of the debuggee global objects observed by the Debugger object // |dbgObj| to |vector|. Returns true on success, false on failure. JS_PUBLIC_API(bool) -GetDebuggeeGlobals(JSContext *cx, const JSObject &dbgObj, AutoObjectVector &vector); +GetDebuggeeGlobals(JSContext* cx, const JSObject& dbgObj, AutoObjectVector& vector); } // namespace dbg } // namespace JS diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 409618a8a166..33eb6c435291 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -474,7 +474,7 @@ extern JS_FRIEND_API(bool) IsAtomsCompartment(JSCompartment* comp); extern JS_FRIEND_API(bool) -IsAtomsZone(JS::Zone *zone); +IsAtomsZone(JS::Zone* zone); /* * Returns whether we're in a non-strict property set (in that we're in a diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 4dae4b37326d..65b9c6a7479c 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -7882,17 +7882,17 @@ JS::dbg::onPromiseSettled(JSContext* cx, HandleObject promise) } JS_PUBLIC_API(bool) -JS::dbg::IsDebugger(const JSObject &obj) +JS::dbg::IsDebugger(const JSObject& obj) { return js::GetObjectClass(&obj) == &Debugger::jsclass && js::Debugger::fromJSObject(&obj) != nullptr; } JS_PUBLIC_API(bool) -JS::dbg::GetDebuggeeGlobals(JSContext *cx, const JSObject &dbgObj, AutoObjectVector &vector) +JS::dbg::GetDebuggeeGlobals(JSContext* cx, const JSObject& dbgObj, AutoObjectVector& vector) { MOZ_ASSERT(IsDebugger(dbgObj)); - js::Debugger *dbg = js::Debugger::fromJSObject(&dbgObj); + js::Debugger* dbg = js::Debugger::fromJSObject(&dbgObj); if (!vector.reserve(vector.length() + dbg->debuggees.count())) { JS_ReportOutOfMemory(cx); diff --git a/js/src/vm/DebuggerMemory.cpp b/js/src/vm/DebuggerMemory.cpp index b459546def0d..02febe4e839a 100644 --- a/js/src/vm/DebuggerMemory.cpp +++ b/js/src/vm/DebuggerMemory.cpp @@ -326,7 +326,7 @@ JS::dbg::SetDebuggerMallocSizeOf(JSRuntime* rt, mozilla::MallocSizeOf mallocSize } JS_PUBLIC_API(mozilla::MallocSizeOf) -JS::dbg::GetDebuggerMallocSizeOf(JSRuntime *rt) +JS::dbg::GetDebuggerMallocSizeOf(JSRuntime* rt) { return rt->debuggerMallocSizeOf; } diff --git a/toolkit/devtools/server/ChromeUtils.cpp b/toolkit/devtools/server/ChromeUtils.cpp index db291198f61e..4e47fc8276a6 100644 --- a/toolkit/devtools/server/ChromeUtils.cpp +++ b/toolkit/devtools/server/ChromeUtils.cpp @@ -35,7 +35,7 @@ using namespace dom; // globals, find the set of zones the globals are allocated within. Returns // false on OOM failure. static bool -PopulateZonesWithGlobals(ZoneSet &zones, AutoObjectVector &globals) +PopulateZonesWithGlobals(ZoneSet& zones, AutoObjectVector& globals) { if (!zones.init()) return false; @@ -52,7 +52,7 @@ PopulateZonesWithGlobals(ZoneSet &zones, AutoObjectVector &globals) // Add the given set of globals as explicit roots in the given roots // list. Returns false on OOM failure. static bool -AddGlobalsAsRoots(AutoObjectVector &globals, ubi::RootList &roots) +AddGlobalsAsRoots(AutoObjectVector& globals, ubi::RootList& roots) { unsigned length = globals.length(); for (unsigned i = 0; i < length; i++) { @@ -75,11 +75,11 @@ AddGlobalsAsRoots(AutoObjectVector &globals, ubi::RootList &roots) // handle it, or we run out of memory, set `rv` appropriately and return // `false`. static bool -EstablishBoundaries(JSContext *cx, - ErrorResult &rv, - const HeapSnapshotBoundaries &boundaries, - ubi::RootList &roots, - ZoneSet &zones) +EstablishBoundaries(JSContext* cx, + ErrorResult& rv, + const HeapSnapshotBoundaries& boundaries, + ubi::RootList& roots, + ZoneSet& zones) { MOZ_ASSERT(!roots.initialized()); MOZ_ASSERT(!zones.initialized()); @@ -107,7 +107,7 @@ EstablishBoundaries(JSContext *cx, } foundBoundaryProperty = true; - JSObject *dbgObj = boundaries.mDebugger.Value(); + JSObject* dbgObj = boundaries.mDebugger.Value(); if (!dbgObj || !dbg::IsDebugger(*dbgObj)) { rv.Throw(NS_ERROR_INVALID_ARG); return false; @@ -139,7 +139,7 @@ EstablishBoundaries(JSContext *cx, AutoObjectVector globals(cx); for (uint32_t i = 0; i < length; i++) { - JSObject *global = boundaries.mGlobals.Value().ElementAt(i); + JSObject* global = boundaries.mGlobals.Value().ElementAt(i); if (!JS_IsGlobalObject(global)) { rv.Throw(NS_ERROR_INVALID_ARG); return false; @@ -175,12 +175,12 @@ EstablishBoundaries(JSContext *cx, // given `ZeroCopyOutputStream`. class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter { - JSContext *cx; + JSContext* cx; bool wantNames; - ::google::protobuf::io::ZeroCopyOutputStream &stream; + ::google::protobuf::io::ZeroCopyOutputStream& stream; - bool writeMessage(const ::google::protobuf::MessageLite &message) { + bool writeMessage(const ::google::protobuf::MessageLite& message) { // We have to create a new CodedOutputStream when writing each message so // that the 64MB size limit used by Coded{Output,Input}Stream to prevent // integer overflow is enforced per message rather than on the whole stream. @@ -191,8 +191,8 @@ class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter } public: - StreamWriter(JSContext *cx, - ::google::protobuf::io::ZeroCopyOutputStream &stream, + StreamWriter(JSContext* cx, + ::google::protobuf::io::ZeroCopyOutputStream& stream, bool wantNames) : cx(cx) , wantNames(wantNames) @@ -207,16 +207,16 @@ public: return writeMessage(metadata); } - virtual bool writeNode(const JS::ubi::Node &ubiNode, + virtual bool writeNode(const JS::ubi::Node& ubiNode, EdgePolicy includeEdges) override { protobuf::Node protobufNode; protobufNode.set_id(ubiNode.identifier()); - const char16_t *typeName = ubiNode.typeName(); + const char16_t* typeName = ubiNode.typeName(); size_t length = NS_strlen(typeName) * sizeof(char16_t); protobufNode.set_typename_(typeName, length); - JSRuntime *rt = JS_GetRuntime(cx); + JSRuntime* rt = JS_GetRuntime(cx); mozilla::MallocSizeOf mallocSizeOf = dbg::GetDebuggerMallocSizeOf(rt); MOZ_ASSERT(mallocSizeOf); protobufNode.set_size(ubiNode.size(mallocSizeOf)); @@ -227,9 +227,9 @@ public: return false; for ( ; !edges->empty(); edges->popFront()) { - const ubi::Edge &ubiEdge = edges->front(); + const ubi::Edge& ubiEdge = edges->front(); - protobuf::Edge *protobufEdge = protobufNode.add_edges(); + protobuf::Edge* protobufEdge = protobufNode.add_edges(); if (NS_WARN_IF(!protobufEdge)) { return false; } @@ -251,7 +251,7 @@ public: // core dump. class MOZ_STACK_CLASS HeapSnapshotHandler { CoreDumpWriter& writer; - JS::ZoneSet* zones; + JS::ZoneSet* zones; public: HeapSnapshotHandler(CoreDumpWriter& writer, @@ -264,10 +264,10 @@ public: class NodeData { }; typedef JS::ubi::BreadthFirst Traversal; - bool operator() (Traversal &traversal, + bool operator() (Traversal& traversal, JS::ubi::Node origin, - const JS::ubi::Edge &edge, - NodeData *, + const JS::ubi::Edge& edge, + NodeData*, bool first) { // We're only interested in the first time we reach edge.referent, not in @@ -279,7 +279,7 @@ public: if (!first) return true; - const JS::ubi::Node &referent = edge.referent; + const JS::ubi::Node& referent = edge.referent; if (!zones) // We aren't targeting a particular set of zones, so serialize all the @@ -293,7 +293,7 @@ public: // by traversing the heap graph. However, we do not serialize its outgoing // edges and we abandon further traversal from this node. - JS::Zone *zone = referent.zone(); + JS::Zone* zone = referent.zone(); if (zones->has(zone)) return writer.writeNode(referent, CoreDumpWriter::INCLUDE_EDGES); @@ -305,12 +305,12 @@ public: bool -WriteHeapGraph(JSContext *cx, - const JS::ubi::Node &node, - CoreDumpWriter &writer, +WriteHeapGraph(JSContext* cx, + const JS::ubi::Node& node, + CoreDumpWriter& writer, bool wantNames, - JS::ZoneSet *zones, - JS::AutoCheckCannotGC &noGC) + JS::ZoneSet* zones, + JS::AutoCheckCannotGC& noGC) { // Serialize the starting node to the core dump. @@ -332,10 +332,10 @@ WriteHeapGraph(JSContext *cx, } /* static */ void -ChromeUtils::SaveHeapSnapshot(GlobalObject &global, - JSContext *cx, - const nsAString &filePath, - const HeapSnapshotBoundaries &boundaries, +ChromeUtils::SaveHeapSnapshot(GlobalObject& global, + JSContext* cx, + const nsAString& filePath, + const HeapSnapshotBoundaries& boundaries, ErrorResult& rv) { bool wantNames = true; @@ -384,10 +384,10 @@ ChromeUtils::SaveHeapSnapshot(GlobalObject &global, } /* static */ already_AddRefed -ChromeUtils::ReadHeapSnapshot(GlobalObject &global, - JSContext *cx, - const nsAString &filePath, - ErrorResult &rv) +ChromeUtils::ReadHeapSnapshot(GlobalObject& global, + JSContext* cx, + const nsAString& filePath, + ErrorResult& rv) { UniquePtr path(ToNewCString(filePath)); if (!path) { @@ -402,13 +402,13 @@ ChromeUtils::ReadHeapSnapshot(GlobalObject &global, } uint32_t size = fileInfo.size; - ScopedFreePtr buffer(static_cast(malloc(size))); + ScopedFreePtr buffer(static_cast(malloc(size))); if (!buffer) { rv.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } - PRFileDesc *fd = PR_Open(path.get(), PR_RDONLY, 0); + PRFileDesc* fd = PR_Open(path.get(), PR_RDONLY, 0); if (!fd) { rv.Throw(NS_ERROR_UNEXPECTED); return nullptr; diff --git a/toolkit/devtools/server/ChromeUtils.h b/toolkit/devtools/server/ChromeUtils.h index efbed444c3f3..047194b3d3d3 100644 --- a/toolkit/devtools/server/ChromeUtils.h +++ b/toolkit/devtools/server/ChromeUtils.h @@ -39,7 +39,7 @@ public: // Write the given `JS::ubi::Node` to the core dump. The given `EdgePolicy` // dictates whether its outgoing edges should also be written to the core // dump, or excluded. - virtual bool writeNode(const JS::ubi::Node &node, + virtual bool writeNode(const JS::ubi::Node& node, EdgePolicy includeEdges) = 0; }; @@ -49,12 +49,12 @@ public: // non-null, only capture the sub-graph within the zone set, otherwise capture // the whole heap graph. Returns false on failure. bool -WriteHeapGraph(JSContext *cx, - const JS::ubi::Node &node, - CoreDumpWriter &writer, +WriteHeapGraph(JSContext* cx, + const JS::ubi::Node& node, + CoreDumpWriter& writer, bool wantNames, - JS::ZoneSet *zones, - JS::AutoCheckCannotGC &noGC); + JS::ZoneSet* zones, + JS::AutoCheckCannotGC& noGC); class HeapSnapshot; @@ -63,16 +63,16 @@ class HeapSnapshot; class ChromeUtils { public: - static void SaveHeapSnapshot(dom::GlobalObject &global, - JSContext *cx, - const nsAString &filePath, - const dom::HeapSnapshotBoundaries &boundaries, - ErrorResult &rv); + static void SaveHeapSnapshot(dom::GlobalObject& global, + JSContext* cx, + const nsAString& filePath, + const dom::HeapSnapshotBoundaries& boundaries, + ErrorResult& rv); - static already_AddRefed ReadHeapSnapshot(dom::GlobalObject &global, - JSContext *cx, - const nsAString &filePath, - ErrorResult &rv); + static already_AddRefed ReadHeapSnapshot(dom::GlobalObject& global, + JSContext* cx, + const nsAString& filePath, + ErrorResult& rv); }; } // namespace devtools diff --git a/toolkit/devtools/server/DeserializedNode.cpp b/toolkit/devtools/server/DeserializedNode.cpp index 341103fd702d..9600be76a3e9 100644 --- a/toolkit/devtools/server/DeserializedNode.cpp +++ b/toolkit/devtools/server/DeserializedNode.cpp @@ -15,13 +15,13 @@ DeserializedEdge::DeserializedEdge() , name(nullptr) { } -DeserializedEdge::DeserializedEdge(DeserializedEdge &&rhs) +DeserializedEdge::DeserializedEdge(DeserializedEdge&& rhs) { referent = rhs.referent; name = rhs.name; } -DeserializedEdge &DeserializedEdge::operator=(DeserializedEdge &&rhs) +DeserializedEdge& DeserializedEdge::operator=(DeserializedEdge&& rhs) { MOZ_ASSERT(&rhs != this); this->~DeserializedEdge(); @@ -30,7 +30,7 @@ DeserializedEdge &DeserializedEdge::operator=(DeserializedEdge &&rhs) } bool -DeserializedEdge::init(const protobuf::Edge &edge, HeapSnapshot &owner) +DeserializedEdge::init(const protobuf::Edge& edge, HeapSnapshot& owner) { // Although the referent property is optional in the protobuf format for // future compatibility, we can't semantically have an edge to nowhere and @@ -50,7 +50,7 @@ DeserializedEdge::init(const protobuf::Edge &edge, HeapSnapshot &owner) } /* static */ UniquePtr -DeserializedNode::Create(const protobuf::Node &node, HeapSnapshot &owner) +DeserializedNode::Create(const protobuf::Node& node, HeapSnapshot& owner) { if (!node.has_id()) return nullptr; @@ -88,10 +88,10 @@ DeserializedNode::Create(const protobuf::Node &node, HeapSnapshot &owner) } DeserializedNode::DeserializedNode(NodeId id, - const char16_t *typeName, + const char16_t* typeName, uint64_t size, - EdgeVector &&edges, - HeapSnapshot &owner) + EdgeVector&& edges, + HeapSnapshot& owner) : id(id) , typeName(typeName) , size(size) @@ -99,7 +99,7 @@ DeserializedNode::DeserializedNode(NodeId id, , owner(&owner) { } -DeserializedNode::DeserializedNode(NodeId id, const char16_t *typeName, uint64_t size) +DeserializedNode::DeserializedNode(NodeId id, const char16_t* typeName, uint64_t size) : id(id) , typeName(typeName) , size(size) @@ -107,8 +107,8 @@ DeserializedNode::DeserializedNode(NodeId id, const char16_t *typeName, uint64_t , owner(nullptr) { } -DeserializedNode & -DeserializedNode::getEdgeReferent(const DeserializedEdge &edge) +DeserializedNode& +DeserializedNode::getEdgeReferent(const DeserializedEdge& edge) { auto ptr = owner->nodes.lookup(edge.referent); MOZ_ASSERT(ptr); @@ -126,7 +126,7 @@ using mozilla::devtools::DeserializedEdge; const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("mozilla::devtools::DeserializedNode"); -const char16_t * +const char16_t* Concrete::typeName() const { return get().typeName; @@ -155,23 +155,23 @@ public: settle(); } - bool init(DeserializedNode &node) + bool init(DeserializedNode& node) { if (!edges.reserve(node.edges.length())) return false; - for (DeserializedEdge *edgep = node.edges.begin(); + for (DeserializedEdge* edgep = node.edges.begin(); edgep != node.edges.end(); edgep++) { - char16_t *name = nullptr; + char16_t* name = nullptr; if (edgep->name) { name = NS_strdup(edgep->name); if (!name) return false; } - DeserializedNode &referent = node.getEdgeReferent(*edgep); + DeserializedNode& referent = node.getEdgeReferent(*edgep); edges.infallibleAppend(mozilla::Move(SimpleEdge(name, Node(&referent)))); } diff --git a/toolkit/devtools/server/DeserializedNode.h b/toolkit/devtools/server/DeserializedNode.h index dcdf82441e74..876dec906d2b 100644 --- a/toolkit/devtools/server/DeserializedNode.h +++ b/toolkit/devtools/server/DeserializedNode.h @@ -37,18 +37,18 @@ using NodeId = uint64_t; struct DeserializedEdge { NodeId referent; // A borrowed reference to a string owned by this node's owning HeapSnapshot. - const char16_t *name; + const char16_t* name; explicit DeserializedEdge(); - DeserializedEdge(DeserializedEdge &&rhs); - DeserializedEdge &operator=(DeserializedEdge &&rhs); + DeserializedEdge(DeserializedEdge&& rhs); + DeserializedEdge& operator=(DeserializedEdge&& rhs); // Initialize this `DeserializedEdge` from the given `protobuf::Edge` message. - bool init(const protobuf::Edge &edge, HeapSnapshot &owner); + bool init(const protobuf::Edge& edge, HeapSnapshot& owner); private: - DeserializedEdge(const DeserializedEdge &) = delete; - DeserializedEdge& operator=(const DeserializedEdge &) = delete; + DeserializedEdge(const DeserializedEdge&) = delete; + DeserializedEdge& operator=(const DeserializedEdge&) = delete; }; // A `DeserializedNode` is a node in the heap graph that we deserialized from a @@ -59,35 +59,35 @@ struct DeserializedNode { NodeId id; // A borrowed reference to a string owned by this node's owning HeapSnapshot. - const char16_t *typeName; + const char16_t* typeName; uint64_t size; EdgeVector edges; // A weak pointer to this node's owning `HeapSnapshot`. Safe without // AddRef'ing because this node's lifetime is equal to that of its owner. - HeapSnapshot *owner; + HeapSnapshot* owner; // Create a new `DeserializedNode` from the given `protobuf::Node` message. - static UniquePtr Create(const protobuf::Node &node, - HeapSnapshot &owner); + static UniquePtr Create(const protobuf::Node& node, + HeapSnapshot& owner); DeserializedNode(NodeId id, - const char16_t *typeName, + const char16_t* typeName, uint64_t size, - EdgeVector &&edges, - HeapSnapshot &owner); + EdgeVector&& edges, + HeapSnapshot& owner); virtual ~DeserializedNode() { } // Get a borrowed reference to the given edge's referent. This method is // virtual to provide a hook for gmock and gtest. - virtual DeserializedNode &getEdgeReferent(const DeserializedEdge &edge); + virtual DeserializedNode& getEdgeReferent(const DeserializedEdge& edge); protected: // This is only for use with `MockDeserializedNode` in testing. - DeserializedNode(NodeId id, const char16_t *typeName, uint64_t size); + DeserializedNode(NodeId id, const char16_t* typeName, uint64_t size); private: - DeserializedNode(const DeserializedNode &) = delete; - DeserializedNode &operator=(const DeserializedNode &) = delete; + DeserializedNode(const DeserializedNode&) = delete; + DeserializedNode& operator=(const DeserializedNode&) = delete; }; } // namespace devtools @@ -103,21 +103,21 @@ template<> struct Concrete : public Base { protected: - explicit Concrete(DeserializedNode *ptr) : Base(ptr) { } - DeserializedNode &get() const { - return *static_cast(ptr); + explicit Concrete(DeserializedNode* ptr) : Base(ptr) { } + DeserializedNode& get() const { + return *static_cast(ptr); } public: static const char16_t concreteTypeName[]; - static void construct(void *storage, DeserializedNode *ptr) { + static void construct(void* storage, DeserializedNode* ptr) { new (storage) Concrete(ptr); } Id identifier() const override { return get().id; } bool isLive() const override { return false; } - const char16_t *typeName() const override; + const char16_t* typeName() const override; size_t size(mozilla::MallocSizeOf mallocSizeof) const override; // We ignore the `bool wantNames` parameter because we can't control whether diff --git a/toolkit/devtools/server/HeapSnapshot.cpp b/toolkit/devtools/server/HeapSnapshot.cpp index 4b61e4eb3e64..b4decbd036f3 100644 --- a/toolkit/devtools/server/HeapSnapshot.cpp +++ b/toolkit/devtools/server/HeapSnapshot.cpp @@ -46,18 +46,18 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HeapSnapshot) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END -/* virtual */ JSObject * +/* virtual */ JSObject* HeapSnapshot::WrapObject(JSContext* aCx, JS::Handle aGivenProto) { return dom::HeapSnapshotBinding::Wrap(aCx, this, aGivenProto); } /* static */ already_AddRefed -HeapSnapshot::Create(JSContext *cx, - dom::GlobalObject &global, - const uint8_t *buffer, +HeapSnapshot::Create(JSContext* cx, + dom::GlobalObject& global, + const uint8_t* buffer, uint32_t size, - ErrorResult &rv) + ErrorResult& rv) { nsRefPtr snapshot = new HeapSnapshot(cx, global.GetAsSupports()); if (!snapshot->init(buffer, size)) { @@ -69,7 +69,7 @@ HeapSnapshot::Create(JSContext *cx, template static bool -parseMessage(ZeroCopyInputStream &stream, MessageType &message) +parseMessage(ZeroCopyInputStream& stream, MessageType& message) { // We need to create a new `CodedInputStream` for each message so that the // 64MB limit is applied per-message rather than to the whole stream. @@ -96,7 +96,7 @@ parseMessage(ZeroCopyInputStream &stream, MessageType &message) } bool -HeapSnapshot::saveNode(const protobuf::Node &node) +HeapSnapshot::saveNode(const protobuf::Node& node) { UniquePtr dn(DeserializedNode::Create(node, *this)); if (!dn) @@ -105,14 +105,14 @@ HeapSnapshot::saveNode(const protobuf::Node &node) } static inline bool -StreamHasData(GzipInputStream &stream) +StreamHasData(GzipInputStream& stream) { // Test for the end of the stream. The protobuf library gives no way to tell // the difference between an underlying read error and the stream being // done. All we can do is attempt to read data and extrapolate guestimations // from the result of that operation. - const void *buf; + const void* buf; int size; bool more = stream.Next(&buf, &size); if (!more) @@ -128,7 +128,7 @@ StreamHasData(GzipInputStream &stream) } bool -HeapSnapshot::init(const uint8_t *buffer, uint32_t size) +HeapSnapshot::init(const uint8_t* buffer, uint32_t size) { if (!nodes.init() || !strings.init()) return false; diff --git a/toolkit/devtools/server/HeapSnapshot.h b/toolkit/devtools/server/HeapSnapshot.h index 9d14c829633e..ead729a9e5b3 100644 --- a/toolkit/devtools/server/HeapSnapshot.h +++ b/toolkit/devtools/server/HeapSnapshot.h @@ -61,7 +61,7 @@ class HeapSnapshot final : public nsISupports { friend struct DeserializedNode; - explicit HeapSnapshot(JSContext *cx, nsISupports *aParent) + explicit HeapSnapshot(JSContext* cx, nsISupports* aParent) : timestamp(Nothing()) , rootId(0) , nodes(cx) @@ -74,11 +74,11 @@ class HeapSnapshot final : public nsISupports // Initialize this HeapSnapshot from the given buffer that contains a // serialized core dump. Do NOT take ownership of the buffer, only borrow it // for the duration of the call. Return false on failure. - bool init(const uint8_t *buffer, uint32_t size); + bool init(const uint8_t* buffer, uint32_t size); // Save the given `protobuf::Node` message in this `HeapSnapshot` as a // `DeserializedNode`. - bool saveNode(const protobuf::Node &node); + bool saveNode(const protobuf::Node& node); // If present, a timestamp in the same units that `PR_Now` gives. Maybe timestamp; @@ -108,19 +108,19 @@ public: // Create a `HeapSnapshot` from the given buffer that contains a serialized // core dump. Do NOT take ownership of the buffer, only borrow it for the // duration of the call. - static already_AddRefed Create(JSContext *cx, - dom::GlobalObject &global, - const uint8_t *buffer, + static already_AddRefed Create(JSContext* cx, + dom::GlobalObject& global, + const uint8_t* buffer, uint32_t size, - ErrorResult &rv); + ErrorResult& rv); NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HeapSnapshot) MOZ_DECLARE_REFCOUNTED_TYPENAME(HeapSnapshot) - nsISupports *GetParentObject() const { return mParent; } + nsISupports* GetParentObject() const { return mParent; } - virtual JSObject *WrapObject(JSContext* aCx, + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; const char16_t* borrowUniqueString(const char16_t* duplicateString, diff --git a/toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp b/toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp index 41e85923eba1..6a5a06e5be85 100644 --- a/toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp +++ b/toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp @@ -10,7 +10,7 @@ namespace mozilla { namespace devtools { -ZeroCopyNSIOutputStream::ZeroCopyNSIOutputStream(nsCOMPtr &out) +ZeroCopyNSIOutputStream::ZeroCopyNSIOutputStream(nsCOMPtr& out) : out(out) , result_(NS_OK) , amountUsed(0) @@ -57,7 +57,7 @@ ZeroCopyNSIOutputStream::writeBuffer() // ZeroCopyOutputStream Interface bool -ZeroCopyNSIOutputStream::Next(void **data, int *size) +ZeroCopyNSIOutputStream::Next(void** data, int* size) { MOZ_ASSERT(data != nullptr); MOZ_ASSERT(size != nullptr); diff --git a/toolkit/devtools/server/ZeroCopyNSIOutputStream.h b/toolkit/devtools/server/ZeroCopyNSIOutputStream.h index 80ec55dc6e0a..117fc0f877e5 100644 --- a/toolkit/devtools/server/ZeroCopyNSIOutputStream.h +++ b/toolkit/devtools/server/ZeroCopyNSIOutputStream.h @@ -28,7 +28,7 @@ class MOZ_STACK_CLASS ZeroCopyNSIOutputStream static const int BUFFER_SIZE = 8192; // The nsIOutputStream we are streaming to. - nsCOMPtr &out; + nsCOMPtr& out; // The buffer we write data to before passing it to the output stream. char buffer[BUFFER_SIZE]; @@ -48,7 +48,7 @@ class MOZ_STACK_CLASS ZeroCopyNSIOutputStream nsresult writeBuffer(); public: - explicit ZeroCopyNSIOutputStream(nsCOMPtr &out); + explicit ZeroCopyNSIOutputStream(nsCOMPtr& out); nsresult flush() { return writeBuffer(); } @@ -59,7 +59,7 @@ public: // ZeroCopyOutputStream Interface virtual ~ZeroCopyNSIOutputStream() override; - virtual bool Next(void **data, int *size) override; + virtual bool Next(void** data, int* size) override; virtual void BackUp(int count) override; virtual ::google::protobuf::int64 ByteCount() const override; }; diff --git a/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp b/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp index 1795360b798f..76d7845ee7f4 100644 --- a/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp +++ b/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp @@ -17,19 +17,19 @@ using testing::ReturnRef; // A mock DeserializedNode for testing. struct MockDeserializedNode : public DeserializedNode { - MockDeserializedNode(NodeId id, const char16_t *typeName, uint64_t size) + MockDeserializedNode(NodeId id, const char16_t* typeName, uint64_t size) : DeserializedNode(id, typeName, size) { } - bool addEdge(DeserializedEdge &&edge) + bool addEdge(DeserializedEdge&& edge) { return edges.append(Move(edge)); } - MOCK_METHOD1(getEdgeReferent, DeserializedNode &(const DeserializedEdge &)); + MOCK_METHOD1(getEdgeReferent, DeserializedNode&(const DeserializedEdge&)); }; -size_t fakeMallocSizeOf(const void *) { +size_t fakeMallocSizeOf(const void*) { EXPECT_TRUE(false); MOZ_ASSERT_UNREACHABLE("fakeMallocSizeOf should never be called because " "DeserializedNodes report the deserialized size."); @@ -37,13 +37,13 @@ size_t fakeMallocSizeOf(const void *) { } DEF_TEST(DeserializedNodeUbiNodes, { - const char16_t *typeName = MOZ_UTF16("TestTypeName"); + const char16_t* typeName = MOZ_UTF16("TestTypeName"); NodeId id = 1L << 33; uint64_t size = 1L << 60; MockDeserializedNode mocked(id, typeName, size); - DeserializedNode &deserialized = mocked; + DeserializedNode& deserialized = mocked; JS::ubi::Node ubi(&deserialized); // Test the ubi::Node accessors. diff --git a/toolkit/devtools/server/tests/gtest/DevTools.h b/toolkit/devtools/server/tests/gtest/DevTools.h index 0c52f80e3a67..78c89762cce1 100644 --- a/toolkit/devtools/server/tests/gtest/DevTools.h +++ b/toolkit/devtools/server/tests/gtest/DevTools.h @@ -26,10 +26,10 @@ using namespace testing; // GTest fixture class that all of our tests derive from. struct DevTools : public ::testing::Test { bool _initialized; - JSRuntime *rt; - JSContext *cx; - JSCompartment *compartment; - JS::Zone *zone; + JSRuntime* rt; + JSContext* cx; + JSCompartment* compartment; + JS::Zone* zone; JS::PersistentRootedObject global; DevTools() @@ -65,7 +65,7 @@ struct DevTools : public ::testing::Test { return CycleCollectedJSRuntime::Get()->Runtime(); } - static void setNativeStackQuota(JSRuntime *rt) + static void setNativeStackQuota(JSRuntime* rt) { const size_t MAX_STACK_SIZE = /* Assume we can't use more than 5e5 bytes of C stack by default. */ @@ -83,18 +83,18 @@ struct DevTools : public ::testing::Test { JS_SetNativeStackQuota(rt, MAX_STACK_SIZE); } - static void reportError(JSContext *cx, const char *message, JSErrorReport *report) { + static void reportError(JSContext* cx, const char* message, JSErrorReport* report) { fprintf(stderr, "%s:%u:%s\n", report->filename ? report->filename : "", (unsigned int) report->lineno, message); } - JSContext *createContext() { + JSContext* createContext() { return JS_NewContext(rt, 8192); } - static const JSClass *getGlobalClass() { + static const JSClass* getGlobalClass() { static const JSClass globalClass = { "global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, @@ -105,7 +105,7 @@ struct DevTools : public ::testing::Test { return &globalClass; } - JSObject *createGlobal() + JSObject* createGlobal() { /* Create the global object. */ JS::RootedObject newGlobal(cx); @@ -151,7 +151,6 @@ struct DevTools : public ::testing::Test { // Fake JS::ubi::Node implementation - class MOZ_STACK_CLASS FakeNode { public: @@ -212,8 +211,8 @@ const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("FakeNode"); } // namespace ubi } // namespace JS -void AddEdge(FakeNode &node, FakeNode &referent, const char16_t *edgeName = nullptr) { - char16_t *ownedEdgeName = nullptr; +void AddEdge(FakeNode& node, FakeNode& referent, const char16_t* edgeName = nullptr) { + char16_t* ownedEdgeName = nullptr; if (edgeName) { ownedEdgeName = NS_strdup(edgeName); ASSERT_NE(ownedEdgeName, nullptr); @@ -253,7 +252,7 @@ MATCHER_P3(Edge, cx, n, matcher, "") { int i = 0; for ( ; !edges->empty(); edges->popFront()) { if (i == n) { - return Matcher(matcher) + return Matcher(matcher) .MatchAndExplain(edges->front(), result_listener); } @@ -276,11 +275,11 @@ class MockWriter : public CoreDumpWriter { public: virtual ~MockWriter() override { } - MOCK_METHOD2(writeNode, bool(const JS::ubi::Node &, CoreDumpWriter::EdgePolicy)); + MOCK_METHOD2(writeNode, bool(const JS::ubi::Node&, CoreDumpWriter::EdgePolicy)); MOCK_METHOD1(writeMetadata, bool(uint64_t)); }; -void ExpectWriteNode(MockWriter &writer, FakeNode &node) { +void ExpectWriteNode(MockWriter& writer, FakeNode& node) { EXPECT_CALL(writer, writeNode(Eq(JS::ubi::Node(&node)), _)) .Times(1) .WillOnce(Return(true)); diff --git a/toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp b/toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp index 9bc92fa33485..c2c54816f33b 100644 --- a/toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp +++ b/toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp @@ -14,7 +14,7 @@ DEF_TEST(DoesCrossZoneBoundaries, { nullptr, JS::FireOnNewGlobalHook)); ASSERT_TRUE(newGlobal); - JS::Zone *newZone = nullptr; + JS::Zone* newZone = nullptr; { JSAutoCompartment ac(cx, newGlobal); ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal)); diff --git a/toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp b/toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp index cbfa9999e5f5..75e1039d330f 100644 --- a/toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp +++ b/toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp @@ -14,7 +14,7 @@ DEF_TEST(DoesntCrossZoneBoundaries, { nullptr, JS::FireOnNewGlobalHook)); ASSERT_TRUE(newGlobal); - JS::Zone *newZone = nullptr; + JS::Zone* newZone = nullptr; { JSAutoCompartment ac(cx, newGlobal); ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal)); From 7451725aaeb0346359f1b8baa5c9bac597c3a6be Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:09:55 -0700 Subject: [PATCH 226/241] Bug 1024774 - Part 14: Ignore protobuf indirect calls in the GC hazard analysis; r=sfink --- js/src/devtools/rootAnalysis/annotations.js | 45 ++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index effcd4ca9a87..de4b83dc8ab3 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -13,7 +13,7 @@ var ignoreIndirectCalls = { "__conv" : true, "__convf" : true, "prerrortable.c:callback_newtable" : true, - "mozalloc_oom.cpp:void (* gAbortHandler)(size_t)" : true + "mozalloc_oom.cpp:void (* gAbortHandler)(size_t)" : true, }; function indirectCallCannotGC(fullCaller, fullVariable) @@ -174,8 +174,34 @@ var ignoreFunctions = { // And these are workarounds to avoid even more analysis work, // which would sadly still be needed even with bug 898815. "void js::AutoCompartment::AutoCompartment(js::ExclusiveContext*, JSCompartment*)": true, + + // Similar to heap snapshot mock classes, and GTests below. This posts a + // synchronous runnable when a GTest fails, and we are pretty sure that the + // particular runnable it posts can't even GC, but the analysis isn't + // currently smart enough to determine that. In either case, this is (a) + // only in GTests, and (b) only when the Gtest has already failed. We have + // static and dynamic checks for no GC in the non-test code, and in the test + // code we fall back to only the dynamic checks. + "void test::RingbufferDumper::OnTestPartResult(testing::TestPartResult*)" : true, }; +function isProtobuf(name) +{ + return name.match(/\bgoogle::protobuf\b/) || + name.match(/\bmozilla::devtools::protobuf\b/); +} + +function isHeapSnapshotMockClass(name) +{ + return name.match(/\bMockWriter\b/) || + name.match(/\bMockDeserializedNode\b/); +} + +function isGTest(name) +{ + return name.match(/\btesting::/); +} + function ignoreGCFunction(mangled) { assert(mangled in readableNames); @@ -184,6 +210,23 @@ function ignoreGCFunction(mangled) if (fun in ignoreFunctions) return true; + // The protobuf library, and [de]serialization code generated by the + // protobuf compiler, uses a _ton_ of function pointers but they are all + // internal. Easiest to just ignore that mess here. + if (isProtobuf(fun)) + return true; + + // Ignore anything that goes through heap snapshot GTests or mocked classes + // used in heap snapshot GTests. GTest and GMock expose a lot of virtual + // methods and function pointers that could potentially GC after an + // assertion has already failed (depending on user-provided code), but don't + // exhibit that behavior currently. For non-test code, we have dynamic and + // static checks that ensure we don't GC. However, for test code we opt out + // of static checks here, because of the above stated GMock/GTest issues, + // and rely on only the dynamic checks provided by AutoAssertCannotGC. + if (isHeapSnapshotMockClass(fun) || isGTest(fun)) + return true; + // Templatized function if (fun.indexOf("void nsCOMPtr::Assert_NoQueryNeeded()") >= 0) return true; From b743410d6322591fa3b0029c4aaa55a0e331daaf Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 11:38:09 -0700 Subject: [PATCH 227/241] Bug 1065657 - Follow up: remove bad friend declaration that leads to GCC warnings and burnt trees on a CLOSED TREE; r=tromey --- js/src/vm/Debugger.h | 1 - 1 file changed, 1 deletion(-) diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index 1a9af15ad0df..d65df7d5db92 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -190,7 +190,6 @@ class Debugger : private mozilla::LinkedListElement friend bool (::JS_DefineDebuggerObject)(JSContext* cx, JS::HandleObject obj); friend bool (::JS::dbg::IsDebugger)(const JSObject&); friend bool (::JS::dbg::GetDebuggeeGlobals)(JSContext*, const JSObject&, AutoObjectVector&); - friend JSObject* SavedStacksMetadataCallback(JSContext* cx); friend void JS::dbg::onNewPromise(JSContext* cx, HandleObject promise); friend void JS::dbg::onPromiseSettled(JSContext* cx, HandleObject promise); friend bool JS::dbg::FireOnGarbageCollectionHook(JSContext* cx, From b9f7c92db7866698f4f1703860fc228eb9feb542 Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Wed, 22 Apr 2015 15:18:22 -0400 Subject: [PATCH 228/241] Bug 1157193, fix null pointer check when dragging images, r=smaug --- dom/base/nsContentUtils.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index e6dbd511c325..e3113e1a2476 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7303,24 +7303,25 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable, RefPtr surface = image->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE); + if (surface) { + mozilla::RefPtr dataSurface = + surface->GetDataSurface(); + size_t length; + int32_t stride; + mozilla::UniquePtr surfaceData = + nsContentUtils::GetSurfaceData(dataSurface, &length, &stride); + + IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); + item->flavor() = nsCString(flavorStr); + item->data() = nsCString(surfaceData.get(), length); - mozilla::RefPtr dataSurface = - surface->GetDataSurface(); - size_t length; - int32_t stride; - mozilla::UniquePtr surfaceData = - nsContentUtils::GetSurfaceData(dataSurface, &length, &stride); - - IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); - item->flavor() = nsCString(flavorStr); - item->data() = nsCString(surfaceData.get(), length); - - IPCDataTransferImage& imageDetails = item->imageDetails(); - mozilla::gfx::IntSize size = dataSurface->GetSize(); - imageDetails.width() = size.width; - imageDetails.height() = size.height; - imageDetails.stride() = stride; - imageDetails.format() = static_cast(dataSurface->GetFormat()); + IPCDataTransferImage& imageDetails = item->imageDetails(); + mozilla::gfx::IntSize size = dataSurface->GetSize(); + imageDetails.width() = size.width; + imageDetails.height() = size.height; + imageDetails.stride() = stride; + imageDetails.format() = static_cast(dataSurface->GetFormat()); + } continue; } From 525df2926a5aa6018a1d0712702e6423d6665782 Mon Sep 17 00:00:00 2001 From: Kannan Vijayan Date: Wed, 22 Apr 2015 15:36:43 -0400 Subject: [PATCH 229/241] Bug 1145306 - Expose circular buffer status from profiler. r=mstange --- tools/profiler/GeckoProfiler.h | 16 ++++++++++++++++ tools/profiler/GeckoProfilerFunc.h | 3 +++ tools/profiler/GeckoProfilerImpl.h | 7 +++++++ tools/profiler/TableTicker.cpp | 8 ++++++++ tools/profiler/TableTicker.h | 2 ++ tools/profiler/nsIProfiler.idl | 5 ++++- tools/profiler/nsProfiler.cpp | 10 ++++++++++ tools/profiler/platform.cpp | 17 +++++++++++++++++ 8 files changed, 67 insertions(+), 1 deletion(-) diff --git a/tools/profiler/GeckoProfiler.h b/tools/profiler/GeckoProfiler.h index 77760d647160..6ad624f02e2e 100644 --- a/tools/profiler/GeckoProfiler.h +++ b/tools/profiler/GeckoProfiler.h @@ -170,6 +170,22 @@ static inline void profiler_save_profile_to_file(char* aFilename) { } // Returns a null terminated char* array. static inline char** profiler_get_features() { return nullptr; } +// Get information about the current buffer status. +// Retursn (using outparams) the current write position in the buffer, +// the total size of the buffer, and the generation of the buffer. +// This information may be useful to a user-interface displaying the +// current status of the profiler, allowing the user to get a sense +// for how fast the buffer is being written to, and how much +// data is visible. +static inline void profiler_get_buffer_info(uint32_t *aCurrentPosition, + uint32_t *aTotalSize, + uint32_t *aGeneration) +{ + *aCurrentPosition = 0; + *aTotalSize = 0; + *aGeneration = 0; +} + // Discard the profile, throw away the profile and notify 'profiler-locked'. // This function is to be used when entering private browsing to prevent // the profiler from collecting sensitive data. diff --git a/tools/profiler/GeckoProfilerFunc.h b/tools/profiler/GeckoProfilerFunc.h index 1030b39bc4b1..5f444b87caec 100644 --- a/tools/profiler/GeckoProfilerFunc.h +++ b/tools/profiler/GeckoProfilerFunc.h @@ -65,6 +65,9 @@ extern "C" { const char** mozilla_sampler_get_features(); +void mozilla_sampler_get_buffer_info(uint32_t *aCurrentPosition, uint32_t *aTotalSize, + uint32_t *aGeneration); + void mozilla_sampler_init(void* stackTop); void mozilla_sampler_shutdown(); diff --git a/tools/profiler/GeckoProfilerImpl.h b/tools/profiler/GeckoProfilerImpl.h index b81ab98a7f49..fa358f8e1a94 100644 --- a/tools/profiler/GeckoProfilerImpl.h +++ b/tools/profiler/GeckoProfilerImpl.h @@ -167,6 +167,13 @@ const char** profiler_get_features() return mozilla_sampler_get_features(); } +static inline +void profiler_get_buffer_info(uint32_t *aCurrentPosition, uint32_t *aTotalSize, + uint32_t *aGeneration) +{ + return mozilla_sampler_get_buffer_info(aCurrentPosition, aTotalSize, aGeneration); +} + static inline void profiler_lock() { diff --git a/tools/profiler/TableTicker.cpp b/tools/profiler/TableTicker.cpp index 45b9a6658faa..f68c14b179b5 100644 --- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -1079,3 +1079,11 @@ SyncProfile* TableTicker::GetBacktrace() return profile; } + +void +TableTicker::GetBufferInfo(uint32_t *aCurrentPosition, uint32_t *aTotalSize, uint32_t *aGeneration) +{ + *aCurrentPosition = mBuffer->mWritePos; + *aTotalSize = mBuffer->mEntrySize; + *aGeneration = mBuffer->mGeneration; +} diff --git a/tools/profiler/TableTicker.h b/tools/profiler/TableTicker.h index 24bb26f0f4ff..9bb86f8e770f 100644 --- a/tools/profiler/TableTicker.h +++ b/tools/profiler/TableTicker.h @@ -210,6 +210,8 @@ class TableTicker: public Sampler { bool DisplayListDump() const { return mDisplayListDump; } bool ProfileRestyle() const { return mProfileRestyle; } + void GetBufferInfo(uint32_t *aCurrentPosition, uint32_t *aTotalSize, uint32_t *aGeneration); + protected: // Called within a signal. This function must be reentrant virtual void InplaceTick(TickSample* sample); diff --git a/tools/profiler/nsIProfiler.idl b/tools/profiler/nsIProfiler.idl index 87f58accc475..e4546cefb88c 100644 --- a/tools/profiler/nsIProfiler.idl +++ b/tools/profiler/nsIProfiler.idl @@ -12,7 +12,7 @@ class nsCString; [ref] native StringArrayRef(const nsTArray); -[scriptable, uuid(42d1e0e3-303a-424f-89ea-4f15c699d767)] +[scriptable, uuid(edd65f3f-c2a2-4217-a2e2-40347ba4a2b3)] interface nsIProfiler : nsISupports { void StartProfiler(in uint32_t aEntries, in double aInterval, @@ -31,6 +31,9 @@ interface nsIProfiler : nsISupports boolean IsActive(); void GetFeatures(out uint32_t aCount, [retval, array, size_is(aCount)] out string aFeatures); + void GetBufferInfo(out uint32_t aCurrentPosition, out uint32_t aTotalSize, + out uint32_t aGeneration); + /** * Returns a JSON string of an array of shared library objects. * Every object has three properties: start, end, and name. diff --git a/tools/profiler/nsProfiler.cpp b/tools/profiler/nsProfiler.cpp index b9ed68c3d073..9d127b4a9d07 100644 --- a/tools/profiler/nsProfiler.cpp +++ b/tools/profiler/nsProfiler.cpp @@ -248,3 +248,13 @@ nsProfiler::GetFeatures(uint32_t *aCount, char ***aFeatures) *aCount = len; return NS_OK; } + +NS_IMETHODIMP +nsProfiler::GetBufferInfo(uint32_t *aCurrentPosition, uint32_t *aTotalSize, uint32_t *aGeneration) +{ + MOZ_ASSERT(aCurrentPosition); + MOZ_ASSERT(aTotalSize); + MOZ_ASSERT(aGeneration); + profiler_get_buffer_info(aCurrentPosition, aTotalSize, aGeneration); + return NS_OK; +} diff --git a/tools/profiler/platform.cpp b/tools/profiler/platform.cpp index f6de7926da43..8ff616a004a4 100644 --- a/tools/profiler/platform.cpp +++ b/tools/profiler/platform.cpp @@ -650,6 +650,23 @@ const char** mozilla_sampler_get_features() return features; } +void mozilla_sampler_get_buffer_info(uint32_t *aCurrentPosition, uint32_t *aTotalSize, + uint32_t *aGeneration) +{ + *aCurrentPosition = 0; + *aTotalSize = 0; + *aGeneration = 0; + + if (!stack_key_initialized) + return; + + TableTicker *t = tlsTicker.get(); + if (!t) + return; + + t->GetBufferInfo(aCurrentPosition, aTotalSize, aGeneration); +} + // Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, double aInterval, const char** aFeatures, uint32_t aFeatureCount, From acb448f5f998f853867a31612e0301ae8bd37f56 Mon Sep 17 00:00:00 2001 From: Steven Michaud Date: Wed, 22 Apr 2015 14:56:09 -0500 Subject: [PATCH 230/241] Bug 1153809 - Loosen Mac content process sandbox rules for NVidia and Intel HD 3000 graphics hardware. r=areinald --- security/sandbox/mac/Sandbox.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/security/sandbox/mac/Sandbox.mm b/security/sandbox/mac/Sandbox.mm index f283a530cb6b..2c811d7918f2 100644 --- a/security/sandbox/mac/Sandbox.mm +++ b/security/sandbox/mac/Sandbox.mm @@ -392,6 +392,11 @@ static const char contentSandboxRules[] = " (appleevent-destination \"com.apple.preview\")\n" " (appleevent-destination \"com.apple.imagecaptureextension2\"))\n" "\n" + "; bug 1153809\n" + " (allow iokit-open\n" + " (iokit-user-client-class \"NVDVDContextTesla\")\n" + " (iokit-user-client-class \"Gen6DVDContext\"))\n" + "\n" "; accelerated graphics\n" " (allow-shared-preferences-read \"com.apple.opengl\")\n" " (allow-shared-preferences-read \"com.nvidia.OpenGL\")\n" From 24f35dfe499a3dd2850581c4e88c7297955f3808 Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Wed, 22 Apr 2015 12:55:23 -0700 Subject: [PATCH 231/241] Bug 1124076 - Properly detect certs when loaded and prompt to import them. r=sworkman/dkeeler --HG-- extra : rebase_source : 11fb8b1c1a3044b82668136f4cfec4c758d9270c --- dom/ipc/ContentChild.cpp | 18 + dom/ipc/ContentChild.h | 4 + dom/ipc/ContentParent.cpp | 18 + dom/ipc/ContentParent.h | 4 + dom/ipc/PContent.ipdl | 4 + .../ssl/src/PPSMContentDownloader.ipdl | 28 + .../manager/ssl/src/PSMContentListener.cpp | 484 +++++++++++------- security/manager/ssl/src/PSMContentListener.h | 72 +++ security/manager/ssl/src/moz.build | 8 + security/manager/ssl/src/nsNSSModule.cpp | 14 +- 10 files changed, 476 insertions(+), 178 deletions(-) create mode 100644 security/manager/ssl/src/PPSMContentDownloader.ipdl diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 74b1a8b36833..799497ffd7a9 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -38,6 +38,7 @@ #include "mozilla/dom/asmjscache/AsmJSCache.h" #include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h" #include "mozilla/dom/nsIContentChild.h" +#include "mozilla/psm/PSMContentListener.h" #include "mozilla/hal_sandbox/PHalChild.h" #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/FileDescriptorSetChild.h" @@ -203,6 +204,7 @@ using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::net; using namespace mozilla::jsipc; +using namespace mozilla::psm; using namespace mozilla::widget; #if defined(MOZ_WIDGET_GONK) using namespace mozilla::system; @@ -1623,6 +1625,22 @@ ContentChild::DeallocPScreenManagerChild(PScreenManagerChild* aService) return true; } +PPSMContentDownloaderChild* +ContentChild::AllocPPSMContentDownloaderChild(const uint32_t& aCertType) +{ + // NB: We don't need aCertType in the child actor. + nsRefPtr child = new PSMContentDownloaderChild(); + return child.forget().take(); +} + +bool +ContentChild::DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aListener) +{ + auto* listener = static_cast(aListener); + nsRefPtr child = dont_AddRef(listener); + return true; +} + PExternalHelperAppChild* ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 6adf18e222d9..bb2d8d999a47 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -232,6 +232,10 @@ public: bool* aSuccess) override; virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) override; + virtual PPSMContentDownloaderChild* AllocPPSMContentDownloaderChild( + const uint32_t& aCertType) override; + virtual bool DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aDownloader) override; + virtual PExternalHelperAppChild *AllocPExternalHelperAppChild( const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 0bc87b8b197f..d8b4c25768d8 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -156,6 +156,7 @@ #include "prio.h" #include "private/pprio.h" #include "ContentProcessManager.h" +#include "mozilla/psm/PSMContentListener.h" #include "nsIBidiKeyboard.h" @@ -249,6 +250,7 @@ using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::net; using namespace mozilla::jsipc; +using namespace mozilla::psm; using namespace mozilla::widget; #ifdef ENABLE_TESTS @@ -3665,6 +3667,22 @@ ContentParent::DeallocPScreenManagerParent(PScreenManagerParent* aActor) return true; } +PPSMContentDownloaderParent* +ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType) +{ + nsRefPtr downloader = + new PSMContentDownloaderParent(aCertType); + return downloader.forget().take(); +} + +bool +ContentParent::DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aListener) +{ + auto* listener = static_cast(aListener); + nsRefPtr downloader = dont_AddRef(listener); + return true; +} + PExternalHelperAppParent* ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri, const nsCString& aMimeContentType, diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 8affe5a57c1d..680845e43a46 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -606,6 +606,10 @@ private: virtual bool DeallocPNeckoParent(PNeckoParent* necko) override; + virtual PPSMContentDownloaderParent* AllocPPSMContentDownloaderParent( + const uint32_t& aCertType) override; + virtual bool DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aDownloader) override; + virtual PExternalHelperAppParent* AllocPExternalHelperAppParent( const OptionalURIParams& aUri, const nsCString& aMimeContentType, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 0cbefb324074..cc92354bd7d0 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -16,6 +16,7 @@ include protocol PContentPermissionRequest; include protocol PCycleCollectWithLogs; include protocol PCrashReporter; include protocol PDocAccessible; +include protocol PPSMContentDownloader; include protocol PExternalHelperApp; include protocol PDeviceStorageRequest; include protocol PFileDescriptorSet; @@ -388,6 +389,7 @@ prio(normal upto urgent) sync protocol PContent manages PDocAccessible; manages PDeviceStorageRequest; manages PFileSystemRequest; + manages PPSMContentDownloader; manages PExternalHelperApp; manages PFileDescriptorSet; manages PFMRadio; @@ -756,6 +758,8 @@ parent: CloseAlert(nsString name, Principal principal); + PPSMContentDownloader(uint32_t aCertType); + PExternalHelperApp(OptionalURIParams uri, nsCString aMimeContentType, nsCString aContentDisposition, diff --git a/security/manager/ssl/src/PPSMContentDownloader.ipdl b/security/manager/ssl/src/PPSMContentDownloader.ipdl new file mode 100644 index 000000000000..ac97d7c444fb --- /dev/null +++ b/security/manager/ssl/src/PPSMContentDownloader.ipdl @@ -0,0 +1,28 @@ +/* vim: set sw=2 sts=2 ts=2 et tw=80 ft=cpp: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PContent; +include protocol PChannelDiverter; + +namespace mozilla { +namespace psm { + +protocol PPSMContentDownloader +{ + manager PContent; + +parent: + OnStartRequest(uint32_t contentLength); + OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); + OnStopRequest(nsresult code); + + DivertToParentUsing(PChannelDiverter diverter); + +child: + __delete__(); +}; + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/src/PSMContentListener.cpp b/security/manager/ssl/src/PSMContentListener.cpp index 789aac0fa668..47932796fd43 100644 --- a/security/manager/ssl/src/PSMContentListener.cpp +++ b/security/manager/ssl/src/PSMContentListener.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set sw=2 sts=2 ts=2 et tw=80: * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -6,16 +7,22 @@ #include "PSMContentListener.h" +#include "nsIDivertableChannel.h" #include "nsIStreamListener.h" #include "nsIX509CertDB.h" +#include "nsIXULAppInfo.h" #include "mozilla/Casting.h" #include "mozilla/Services.h" +#include "mozilla/unused.h" + +#include "mozilla/dom/ContentChild.h" +#include "mozilla/net/ChannelDiverterParent.h" +#include "mozilla/net/ChannelDiverterChild.h" #include "nsCRT.h" #include "nsNetUtil.h" #include "nsNSSHelper.h" -#include "nsNSSShutDown.h" #include "prlog.h" @@ -27,139 +34,140 @@ namespace mozilla { namespace psm { namespace { -class PSMContentDownloader : public nsIStreamListener -{ -public: - PSMContentDownloader() {NS_ASSERTION(false, "don't use this constructor."); } - explicit PSMContentDownloader(uint32_t type); - void setSilentDownload(bool flag); - - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - enum {UNKNOWN_TYPE = 0}; - enum {X509_CA_CERT = 1}; - enum {X509_USER_CERT = 2}; - enum {X509_EMAIL_CERT = 3}; - enum {X509_SERVER_CERT = 4}; - -protected: - virtual ~PSMContentDownloader(); - - char* mByteData; - int32_t mBufferOffset; - int32_t mBufferSize; - uint32_t mType; - nsCOMPtr mURI; -}; - -PSMContentDownloader::PSMContentDownloader(uint32_t type) - : mByteData(nullptr), - mType(type) -{ -} - -PSMContentDownloader::~PSMContentDownloader() -{ - if (mByteData) - free(mByteData); -} - -NS_IMPL_ISUPPORTS(PSMContentDownloader, nsIStreamListener, nsIRequestObserver) - const int32_t kDefaultCertAllocLength = 2048; -NS_IMETHODIMP -PSMContentDownloader::OnStartRequest(nsIRequest* request, nsISupports* context) -{ - nsresult rv; - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStartRequest\n")); - nsCOMPtr channel(do_QueryInterface(request)); - if (!channel) return NS_ERROR_FAILURE; +enum { + UNKNOWN_TYPE = 0, + X509_CA_CERT = 1, + X509_USER_CERT = 2, + X509_EMAIL_CERT = 3, + X509_SERVER_CERT = 4 +}; - // Get the URI // - channel->GetURI(getter_AddRefs(mURI)); +/* other mime types that we should handle sometime: + + application/x-pkcs7-mime + application/pkcs7-signature + application/pre-encrypted + +*/ + +uint32_t +getPSMContentType(const char* aContentType) +{ + // Don't forget to update the registration of content listeners in nsNSSModule.cpp + // for every supported content type. + + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert")) + return X509_CA_CERT; + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert")) + return X509_SERVER_CERT; + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert")) + return X509_USER_CERT; + if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert")) + return X509_EMAIL_CERT; + + return UNKNOWN_TYPE; +} + +int64_t +ComputeContentLength(nsIRequest* request) +{ + nsCOMPtr channel(do_QueryInterface(request)); + if (!channel) { + return -1; + } int64_t contentLength; - rv = channel->GetContentLength(&contentLength); - if (NS_FAILED(rv) || contentLength <= 0) - contentLength = kDefaultCertAllocLength; - if (contentLength > INT32_MAX) - return NS_ERROR_OUT_OF_MEMORY; - - mBufferOffset = 0; - mBufferSize = 0; - mByteData = (char*)moz_xmalloc(AssertedCast(contentLength)); - if (!mByteData) - return NS_ERROR_OUT_OF_MEMORY; - - mBufferSize = int32_t(contentLength); + nsresult rv = channel->GetContentLength(&contentLength); + if (NS_FAILED(rv) || contentLength <= 0) { + return kDefaultCertAllocLength; + } + + if (contentLength > INT32_MAX) { + return -1; + } + + return contentLength; +} + +} // unnamed namespace + +/* ------------------------ + * PSMContentStreamListener + * ------------------------ */ + +PSMContentStreamListener::PSMContentStreamListener(uint32_t type) + : mType(type) +{ +} + +PSMContentStreamListener::~PSMContentStreamListener() +{ +} + +NS_IMPL_ISUPPORTS(PSMContentStreamListener, nsIStreamListener, nsIRequestObserver) + +NS_IMETHODIMP +PSMContentStreamListener::OnStartRequest(nsIRequest* request, nsISupports* context) +{ + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStartRequest\n")); + + int64_t contentLength = ComputeContentLength(request); + if (contentLength < 0) { + return NS_ERROR_FAILURE; + } + + mByteData.SetCapacity(contentLength); return NS_OK; } NS_IMETHODIMP -PSMContentDownloader::OnDataAvailable(nsIRequest* request, - nsISupports* context, - nsIInputStream *aIStream, - uint64_t aSourceOffset, - uint32_t aLength) +PSMContentStreamListener::OnDataAvailable(nsIRequest* request, + nsISupports* context, + nsIInputStream* aIStream, + uint64_t aSourceOffset, + uint32_t aLength) { - if (!mByteData) - return NS_ERROR_OUT_OF_MEMORY; - - uint32_t amt; - nsresult err; - //Do a check to see if we need to allocate more memory. - if ((mBufferOffset + (int32_t)aLength) > mBufferSize) { - size_t newSize = (mBufferOffset + aLength) *2; // grow some more than needed - char *newBuffer; - newBuffer = (char*)moz_xrealloc(mByteData, newSize); - if (!newBuffer) { - return NS_ERROR_OUT_OF_MEMORY; - } - mByteData = newBuffer; - mBufferSize = newSize; - } - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnDataAvailable\n")); - do { - err = aIStream->Read(mByteData+mBufferOffset, - aLength, &amt); - if (NS_FAILED(err)) return err; - if (amt == 0) break; - - aLength -= amt; - mBufferOffset += amt; - - } while (aLength > 0); - + + nsCString chunk; + nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength); + if (NS_FAILED(rv)) { + return rv; + } + + mByteData.Append(chunk); return NS_OK; } NS_IMETHODIMP -PSMContentDownloader::OnStopRequest(nsIRequest* request, - nsISupports* context, - nsresult aStatus) +PSMContentStreamListener::OnStopRequest(nsIRequest* request, + nsISupports* context, + nsresult aStatus) { - nsNSSShutDownPreventionLock locker; - //Check if the download succeeded - it might have failed due to - //network issues, etc. - if (NS_FAILED(aStatus)){ - return aStatus; - } - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStopRequest\n")); + // Because importing the cert can spin the event loop (via alerts), we can't + // do it here. Do it off the event loop instead. + nsCOMPtr r = + NS_NewRunnableMethod(this, &PSMContentStreamListener::ImportCertificate); + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r))); + + return NS_OK; +} + +void +PSMContentStreamListener::ImportCertificate() +{ nsCOMPtr certdb; - nsresult rv; nsCOMPtr ctx = new PipUIContext(); switch (mType) { - case PSMContentDownloader::X509_CA_CERT: - case PSMContentDownloader::X509_USER_CERT: - case PSMContentDownloader::X509_EMAIL_CERT: + case X509_CA_CERT: + case X509_USER_CERT: + case X509_EMAIL_CERT: certdb = do_GetService(NS_X509CERTDB_CONTRACTID); break; @@ -167,48 +175,172 @@ PSMContentDownloader::OnStopRequest(nsIRequest* request, break; } + if (!certdb) { + return; + } + switch (mType) { - case PSMContentDownloader::X509_CA_CERT: - return certdb->ImportCertificates((uint8_t*)mByteData, mBufferOffset, mType, ctx); - case PSMContentDownloader::X509_USER_CERT: - return certdb->ImportUserCertificate((uint8_t*)mByteData, mBufferOffset, ctx); - case PSMContentDownloader::X509_EMAIL_CERT: - return certdb->ImportEmailCertificate((uint8_t*)mByteData, mBufferOffset, ctx); + case X509_CA_CERT: + certdb->ImportCertificates(reinterpret_cast(mByteData.BeginWriting()), + mByteData.Length(), mType, ctx); + break; + + case X509_USER_CERT: + certdb->ImportUserCertificate(reinterpret_cast(mByteData.BeginWriting()), + mByteData.Length(), ctx); + break; + + case X509_EMAIL_CERT: + certdb->ImportEmailCertificate(reinterpret_cast(mByteData.BeginWriting()), + mByteData.Length(), ctx); + break; + default: - rv = NS_ERROR_FAILURE; break; } - +} + +/* ------------------------ + * PSMContentDownloaderParent + * ------------------------ */ + +PSMContentDownloaderParent::PSMContentDownloaderParent(uint32_t type) + : PSMContentStreamListener(type) + , mIPCOpen(true) +{ +} + +PSMContentDownloaderParent::~PSMContentDownloaderParent() +{ +} + +bool +PSMContentDownloaderParent::RecvOnStartRequest(const uint32_t& contentLength) +{ + mByteData.SetCapacity(contentLength); + return true; +} + +bool +PSMContentDownloaderParent::RecvOnDataAvailable(const nsCString& data, + const uint64_t& offset, + const uint32_t& count) +{ + mByteData.Append(data); + return true; +} + +bool +PSMContentDownloaderParent::RecvOnStopRequest(const nsresult& code) +{ + if (NS_SUCCEEDED(code)) { + // See also PSMContentStreamListener::OnStopRequest. In this case, we don't + // have to dispatch ImportCertificate off of an event because we don't have + // to worry about Necko sending "clean up" events and destroying us if + // ImportCertificate spins the event loop. + ImportCertificate(); + } + + if (mIPCOpen) { + mozilla::unused << Send__delete__(this); + } + return true; +} + +NS_IMETHODIMP +PSMContentDownloaderParent::OnStopRequest(nsIRequest* request, nsISupports* context, nsresult code) +{ + nsresult rv = PSMContentStreamListener::OnStopRequest(request, context, code); + + if (mIPCOpen) { + mozilla::unused << Send__delete__(this); + } return rv; } -/* other mime types that we should handle sometime: - - application/x-pkcs7-mime - application/pkcs7-signature - application/pre-encrypted - -*/ - -uint32_t -getPSMContentType(const char * aContentType) -{ - // Don't forget to update the registration of content listeners in nsNSSModule.cpp - // for every supported content type. - - if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert")) - return PSMContentDownloader::X509_CA_CERT; - else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert")) - return PSMContentDownloader::X509_SERVER_CERT; - else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert")) - return PSMContentDownloader::X509_USER_CERT; - else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert")) - return PSMContentDownloader::X509_EMAIL_CERT; - - return PSMContentDownloader::UNKNOWN_TYPE; +bool +PSMContentDownloaderParent::RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent* diverter) +{ + MOZ_ASSERT(diverter); + auto p = static_cast(diverter); + p->DivertTo(this); + mozilla::unused << p->Send__delete__(p); + return true; } -} // unnamed namespace +void +PSMContentDownloaderParent::ActorDestroy(ActorDestroyReason why) +{ + mIPCOpen = false; +} + +/* ------------------------ + * PSMContentDownloaderChild + * ------------------------ */ + +NS_IMPL_ISUPPORTS(PSMContentDownloaderChild, nsIStreamListener) + +PSMContentDownloaderChild::PSMContentDownloaderChild() +{ +} + +PSMContentDownloaderChild::~PSMContentDownloaderChild() +{ +} + +NS_IMETHODIMP +PSMContentDownloaderChild::OnStartRequest(nsIRequest* request, nsISupports* context) +{ + nsCOMPtr divertable = do_QueryInterface(request); + if (divertable) { + mozilla::net::ChannelDiverterChild* diverter = nullptr; + nsresult rv = divertable->DivertToParent(&diverter); + if (NS_FAILED(rv)) { + return rv; + } + MOZ_ASSERT(diverter); + + return SendDivertToParentUsing(diverter) ? NS_OK : NS_ERROR_FAILURE; + } + + int64_t contentLength = ComputeContentLength(request); + if (contentLength < 0) { + return NS_ERROR_FAILURE; + } + + mozilla::unused << SendOnStartRequest(contentLength); + return NS_OK; +} + +NS_IMETHODIMP +PSMContentDownloaderChild::OnDataAvailable(nsIRequest* request, + nsISupports* context, + nsIInputStream* aIStream, + uint64_t aSourceOffset, + uint32_t aLength) +{ + nsCString chunk; + nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength); + if (NS_FAILED(rv)) { + return rv; + } + + mozilla::unused << SendOnDataAvailable(chunk, aSourceOffset, aLength); + return NS_OK; +} + +NS_IMETHODIMP +PSMContentDownloaderChild::OnStopRequest(nsIRequest* request, + nsISupports* context, + nsresult aStatus) +{ + mozilla::unused << SendOnStopRequest(aStatus); + return NS_OK; +} + +/* ------------------------ + * PSMContentListener + * ------------------------ */ NS_IMPL_ISUPPORTS(PSMContentListener, nsIURIContentListener, @@ -231,7 +363,7 @@ PSMContentListener::init() } NS_IMETHODIMP -PSMContentListener::OnStartURIOpen(nsIURI *aURI, bool *aAbortOpen) +PSMContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen) { //if we don't want to handle the URI, return true in //*aAbortOpen @@ -239,73 +371,77 @@ PSMContentListener::OnStartURIOpen(nsIURI *aURI, bool *aAbortOpen) } NS_IMETHODIMP -PSMContentListener::IsPreferred(const char * aContentType, - char ** aDesiredContentType, - bool * aCanHandleContent) +PSMContentListener::IsPreferred(const char* aContentType, + char** aDesiredContentType, + bool* aCanHandleContent) { return CanHandleContent(aContentType, true, aDesiredContentType, aCanHandleContent); } NS_IMETHODIMP -PSMContentListener::CanHandleContent(const char * aContentType, +PSMContentListener::CanHandleContent(const char* aContentType, bool aIsContentPreferred, - char ** aDesiredContentType, - bool * aCanHandleContent) + char** aDesiredContentType, + bool* aCanHandleContent) { - uint32_t type; - type = getPSMContentType(aContentType); - if (type == PSMContentDownloader::UNKNOWN_TYPE) { - *aCanHandleContent = false; - } else { - *aCanHandleContent = true; - } + uint32_t type = getPSMContentType(aContentType); + *aCanHandleContent = (type != UNKNOWN_TYPE); return NS_OK; } NS_IMETHODIMP -PSMContentListener::DoContent(const nsACString & aContentType, +PSMContentListener::DoContent(const nsACString& aContentType, bool aIsContentPreferred, - nsIRequest * aRequest, - nsIStreamListener ** aContentHandler, - bool * aAbortProcess) + nsIRequest* aRequest, + nsIStreamListener** aContentHandler, + bool* aAbortProcess) { uint32_t type; type = getPSMContentType(PromiseFlatCString(aContentType).get()); - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n")); - if (type != PSMContentDownloader::UNKNOWN_TYPE) { - nsRefPtr downLoader = new PSMContentDownloader(type); - downLoader.forget(aContentHandler); + if (gPIPNSSLog) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n")); + } + if (type != UNKNOWN_TYPE) { + nsCOMPtr downloader; + if (XRE_GetProcessType() == GeckoProcessType_Default) { + downloader = new PSMContentStreamListener(type); + } else { + downloader = static_cast( + dom::ContentChild::GetSingleton()->SendPPSMContentDownloaderConstructor(type)); + } + + downloader.forget(aContentHandler); return NS_OK; } return NS_ERROR_FAILURE; } NS_IMETHODIMP -PSMContentListener::GetLoadCookie(nsISupports * *aLoadCookie) +PSMContentListener::GetLoadCookie(nsISupports** aLoadCookie) { - *aLoadCookie = mLoadCookie; - NS_IF_ADDREF(*aLoadCookie); + nsCOMPtr loadCookie(mLoadCookie); + loadCookie.forget(aLoadCookie); return NS_OK; } NS_IMETHODIMP -PSMContentListener::SetLoadCookie(nsISupports * aLoadCookie) +PSMContentListener::SetLoadCookie(nsISupports* aLoadCookie) { mLoadCookie = aLoadCookie; return NS_OK; } NS_IMETHODIMP -PSMContentListener::GetParentContentListener(nsIURIContentListener ** aContentListener) +PSMContentListener::GetParentContentListener(nsIURIContentListener** aContentListener) { - *aContentListener = mParentContentListener; - NS_IF_ADDREF(*aContentListener); + nsCOMPtr listener(mParentContentListener); + listener.forget(aContentListener); return NS_OK; } NS_IMETHODIMP -PSMContentListener::SetParentContentListener(nsIURIContentListener * aContentListener) +PSMContentListener::SetParentContentListener(nsIURIContentListener* aContentListener) { mParentContentListener = aContentListener; return NS_OK; diff --git a/security/manager/ssl/src/PSMContentListener.h b/security/manager/ssl/src/PSMContentListener.h index 49239029bfc8..13bff90b7c49 100644 --- a/security/manager/ssl/src/PSMContentListener.h +++ b/security/manager/ssl/src/PSMContentListener.h @@ -10,12 +10,84 @@ #include "nsCOMPtr.h" #include "nsIURIContentListener.h" #include "nsWeakReference.h" +#include "mozilla/psm/PPSMContentDownloaderChild.h" +#include "mozilla/psm/PPSMContentDownloaderParent.h" #define NS_PSMCONTENTLISTEN_CID {0xc94f4a30, 0x64d7, 0x11d4, {0x99, 0x60, 0x00, 0xb0, 0xd0, 0x23, 0x54, 0xa0}} #define NS_PSMCONTENTLISTEN_CONTRACTID "@mozilla.org/security/psmdownload;1" +namespace mozilla { +namespace net { + +class PChannelDiverterParent; + +} +} + namespace mozilla { namespace psm { +// PSMContentStreamListener for parent-process downloading. +class PSMContentStreamListener : public nsIStreamListener +{ +public: + explicit PSMContentStreamListener(uint32_t type); + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + + void ImportCertificate(); + +protected: + virtual ~PSMContentStreamListener(); + + nsCString mByteData; + uint32_t mType; +}; + +// Parent actor for importing a remote cert when the load was started by the +// child. +class PSMContentDownloaderParent : public PPSMContentDownloaderParent + , public PSMContentStreamListener +{ +public: + explicit PSMContentDownloaderParent(uint32_t type); + + virtual bool RecvOnStartRequest(const uint32_t &contentLength) override; + virtual bool RecvOnDataAvailable(const nsCString &data, + const uint64_t &offset, + const uint32_t &count) override; + virtual bool RecvOnStopRequest(const nsresult &code) override; + + // We inherit most of nsIStreamListener from PSMContentStreamListener, but + // we have to override OnStopRequest to know when we're done with our IPC + // ref. + NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *aContext, nsresult code) override; + + virtual bool RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent *diverter) override; + +protected: + virtual ~PSMContentDownloaderParent(); + + virtual void ActorDestroy(ActorDestroyReason why) override; + bool mIPCOpen; +}; + +// Child actor for importing a cert. +class PSMContentDownloaderChild : public nsIStreamListener + , public PPSMContentDownloaderChild +{ +public: + PSMContentDownloaderChild(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + +private: + ~PSMContentDownloaderChild(); +}; + + class PSMContentListener : public nsIURIContentListener, public nsSupportsWeakReference { diff --git a/security/manager/ssl/src/moz.build b/security/manager/ssl/src/moz.build index 75276a43d168..2efc4a6ae4f9 100644 --- a/security/manager/ssl/src/moz.build +++ b/security/manager/ssl/src/moz.build @@ -23,6 +23,10 @@ EXPORTS.mozilla += [ 'PublicSSL.h', ] +EXPORTS.mozilla.psm += [ + 'PSMContentListener.h', +] + UNIFIED_SOURCES += [ 'CryptoTask.cpp', 'nsCertOverrideService.cpp', @@ -74,6 +78,10 @@ SOURCES += [ 'nsNSSCertificateDB.cpp', ] +IPDL_SOURCES += [ + 'PPSMContentDownloader.ipdl', +] + LOCAL_INCLUDES += [ '/security/manager/boot/src', ] diff --git a/security/manager/ssl/src/nsNSSModule.cpp b/security/manager/ssl/src/nsNSSModule.cpp index c407d91be05e..8ec8fe936a2f 100644 --- a/security/manager/ssl/src/nsNSSModule.cpp +++ b/security/manager/ssl/src/nsNSSModule.cpp @@ -135,14 +135,20 @@ _InstanceClassChrome##Constructor(nsISupports *aOuter, REFNSIID aIID, \ { \ nsresult rv; \ \ - *aResult = nullptr; \ - if (nullptr != aOuter) { \ + *aResult = nullptr; \ + if (nullptr != aOuter) { \ rv = NS_ERROR_NO_AGGREGATION; \ return rv; \ } \ \ - if (!EnsureNSSInitialized(ensureOperator)) \ + if (!NS_IS_PROCESS_DEFAULT && \ + ensureOperator == nssEnsureChromeOrContent) { \ + if (!EnsureNSSInitializedChromeOrContent()) { \ + return NS_ERROR_FAILURE; \ + } \ + } else if (!EnsureNSSInitialized(ensureOperator)) { \ return NS_ERROR_FAILURE; \ + } \ \ if (NS_IS_PROCESS_DEFAULT) \ NS_NSS_INSTANTIATE_INIT(ensureOperator, \ @@ -182,7 +188,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsTLSSocketProvider) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsSecretDecoderRing) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPK11TokenDB) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPKCS11ModuleDB) -NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, PSMContentListener, init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PSMContentListener, init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly, nsNSSCertificate, nsNSSCertificateFakeTransport) From b07b0bc85e652432f546858350cfd4fedf1ec2c3 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 22 Apr 2015 13:04:01 -0700 Subject: [PATCH 232/241] Bug 1068881 (Part 2) - Add reftests for rounding image dest rects to zero size. r=roc --- .../image-scrolling-zoom-1-notref.html | 36 +++++++++++++ .../image-scrolling-zoom-1-ref.html | 36 +++++++++++++ .../invalidation/image-scrolling-zoom-1.html | 51 ++++++++++++++++++ .../one-pixel-wide-background.png | Bin 0 -> 1059 bytes layout/reftests/invalidation/reftest.list | 2 + 5 files changed, 125 insertions(+) create mode 100644 layout/reftests/invalidation/image-scrolling-zoom-1-notref.html create mode 100644 layout/reftests/invalidation/image-scrolling-zoom-1-ref.html create mode 100644 layout/reftests/invalidation/image-scrolling-zoom-1.html create mode 100644 layout/reftests/invalidation/one-pixel-wide-background.png diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1-notref.html b/layout/reftests/invalidation/image-scrolling-zoom-1-notref.html new file mode 100644 index 000000000000..524109ff9651 --- /dev/null +++ b/layout/reftests/invalidation/image-scrolling-zoom-1-notref.html @@ -0,0 +1,36 @@ + + + + + + + +
    +
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    +
    + + diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html b/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html new file mode 100644 index 000000000000..e989d0e86376 --- /dev/null +++ b/layout/reftests/invalidation/image-scrolling-zoom-1-ref.html @@ -0,0 +1,36 @@ + + + + + + + +
    +
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    +
    + + diff --git a/layout/reftests/invalidation/image-scrolling-zoom-1.html b/layout/reftests/invalidation/image-scrolling-zoom-1.html new file mode 100644 index 000000000000..85a2753b0367 --- /dev/null +++ b/layout/reftests/invalidation/image-scrolling-zoom-1.html @@ -0,0 +1,51 @@ + + + + + + + +
    +
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    Item
    +
    +
    + + + diff --git a/layout/reftests/invalidation/one-pixel-wide-background.png b/layout/reftests/invalidation/one-pixel-wide-background.png new file mode 100644 index 0000000000000000000000000000000000000000..09f59e39ac05bad3f390aeecd72bf750069b738a GIT binary patch literal 1059 zcmZ{jPm9w)7{+G}ENhlMErO^EA$mXzscg4K{K770hfbumQjoG;W1Wie71~YPk%{)%I z8vr*){4>TZ(DFD+GL(1p!h!g=kfE*>7WTTMkNX3yODNV_X4ABEPt`QdrL#F2`j0D| zk2?A*#!>{~VzDq64U^E9&~CTe&~l*T7~ElGX9){(BgyWTi!9giaWUSLs1kK6y#>i#Z?Q;M@p_*<1<*6RKt&Pa4BmVcgv%yTNFCfBLSYTkRW zWMr`pjMo9OC;{RiP*JI|AI3N-a^bnJ)$3fBM1(#|gDDo}DiBGkyNf6jDT*bBktQn8 zh2mG1e(kbv3Y9mGr}6_`Hle5fdUx*!@5>uKe}A;KH~oEa@o-mB6las#0MIYW=Iyti Q6w$f8N5}s8!HYM40j82W^#A|> literal 0 HcmV?d00001 diff --git a/layout/reftests/invalidation/reftest.list b/layout/reftests/invalidation/reftest.list index 3b626718c186..17d14b33b632 100644 --- a/layout/reftests/invalidation/reftest.list +++ b/layout/reftests/invalidation/reftest.list @@ -64,3 +64,5 @@ pref(layout.animated-image-layers.enabled,true) skip-if(Android||gtk2Widget) == != layer-splitting-5.html about:blank != layer-splitting-6.html about:blank != layer-splitting-7.html about:blank +fuzzy-if(gtk2Widget,2,4) == image-scrolling-zoom-1.html image-scrolling-zoom-1-ref.html +!= image-scrolling-zoom-1-ref.html image-scrolling-zoom-1-notref.html From 8b1d7b5a59530574a069f4b93dae316f6e135923 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 22 Apr 2015 13:04:04 -0700 Subject: [PATCH 233/241] Bug 1085783 (Part 1) - Snap both the fill and dest rects using UserToDeviceSnapped() when pixel snapping images. r=roc --- layout/base/nsLayoutUtils.cpp | 74 +++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 204c1676fd6a..b22e5cad1b3e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5831,11 +5831,12 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, // Avoid unnecessarily large offsets. bool doTile = !aDest.Contains(aFill); - nsRect dest = doTile ? TileNearRect(aDest, aFill.Intersect(aDirty)) : aDest; - nsPoint anchor = aAnchor + (dest.TopLeft() - aDest.TopLeft()); + nsRect appUnitDest = doTile ? TileNearRect(aDest, aFill.Intersect(aDirty)) + : aDest; + nsPoint anchor = aAnchor + (appUnitDest.TopLeft() - aDest.TopLeft()); gfxRect devPixelDest = - nsLayoutUtils::RectToGfxRect(dest, aAppUnitsPerDevPixel); + nsLayoutUtils::RectToGfxRect(appUnitDest, aAppUnitsPerDevPixel); gfxRect devPixelFill = nsLayoutUtils::RectToGfxRect(aFill, aAppUnitsPerDevPixel); gfxRect devPixelDirty = @@ -5843,52 +5844,57 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, gfxMatrix currentMatrix = aCtx->CurrentMatrix(); gfxRect fill = devPixelFill; + gfxRect dest = devPixelDest; bool didSnap; // Snap even if we have a scale in the context. But don't snap if // we have something that's not translation+scale, or if the scale flips in // the X or Y direction, because snapped image drawing can't handle that yet. if (!currentMatrix.HasNonAxisAlignedTransform() && currentMatrix._11 > 0.0 && currentMatrix._22 > 0.0 && - aCtx->UserToDevicePixelSnapped(fill, true)) { + aCtx->UserToDevicePixelSnapped(fill, true) && + aCtx->UserToDevicePixelSnapped(dest, true)) { + // We snapped. On this code path, |fill| and |dest| take into account + // currentMatrix's transform. didSnap = true; - if (fill.IsEmpty()) { - return SnappedImageDrawingParameters(); - } } else { + // We didn't snap. On this code path, |fill| and |dest| do not take into + // account currentMatrix's transform. didSnap = false; fill = devPixelFill; + dest = devPixelDest; } - // Apply the context's scale to the dest rect. - gfxSize destScale = didSnap ? gfxSize(currentMatrix._11, currentMatrix._22) - : currentMatrix.ScaleFactors(true); - gfxSize appUnitScaledDest(dest.width * destScale.width, - dest.height * destScale.height); - gfxSize scaledDest = appUnitScaledDest / aAppUnitsPerDevPixel; - if (scaledDest.IsEmpty()) { + // If we snapped above, |dest| already takes into account |currentMatrix|'s scale + // and has integer coordinates. If not, we need these properties to compute + // the optimal drawn image size, so compute |snappedDestSize| here. + gfxSize snappedDestSize = dest.Size(); + if (!didSnap) { + gfxSize scaleFactors = currentMatrix.ScaleFactors(true); + snappedDestSize.Scale(scaleFactors.width, scaleFactors.height); + snappedDestSize.width = NS_round(snappedDestSize.width); + snappedDestSize.height = NS_round(snappedDestSize.height); + } + + // We need to be sure that this is at least one pixel in width and height, + // or we'll end up drawing nothing even if we have a nonempty fill. + snappedDestSize.width = std::max(snappedDestSize.width, 1.0); + snappedDestSize.height = std::max(snappedDestSize.height, 1.0); + + // Bail if we're not going to end up drawing anything. + if (fill.IsEmpty() || snappedDestSize.IsEmpty()) { return SnappedImageDrawingParameters(); } - // Compute a snapped version of the scaled dest rect, which we'll use to - // determine the optimal image size to draw with. We need to be sure that - // this rect is at least one pixel in width and height, or we'll end up - // drawing nothing even if we have a nonempty fill. - gfxSize snappedScaledDest = - gfxSize(NSAppUnitsToIntPixels(appUnitScaledDest.width, aAppUnitsPerDevPixel), - NSAppUnitsToIntPixels(appUnitScaledDest.height, aAppUnitsPerDevPixel)); - snappedScaledDest.width = std::max(snappedScaledDest.width, 1.0); - snappedScaledDest.height = std::max(snappedScaledDest.height, 1.0); - nsIntSize intImageSize = - aImage->OptimalImageSizeForDest(snappedScaledDest, + aImage->OptimalImageSizeForDest(snappedDestSize, imgIContainer::FRAME_CURRENT, aGraphicsFilter, aImageFlags); gfxSize imageSize(intImageSize.width, intImageSize.height); + // XXX(seth): May be buggy; see bug 1151016. CSSIntSize svgViewportSize = currentMatrix.IsIdentity() ? CSSIntSize(intImageSize.width, intImageSize.height) - : CSSIntSize(NSAppUnitsToIntPixels(dest.width, aAppUnitsPerDevPixel), //XXX BUG! - NSAppUnitsToIntPixels(dest.height, aAppUnitsPerDevPixel)); //XXX BUG! + : CSSIntSize(devPixelDest.width, devPixelDest.height); // Compute the set of pixels that would be sampled by an ideal rendering gfxPoint subimageTopLeft = @@ -5904,8 +5910,9 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, gfxMatrix transform; gfxMatrix invTransform; - bool anchorAtUpperLeft = anchor.x == dest.x && anchor.y == dest.y; - bool exactlyOneImageCopy = aFill.IsEqualEdges(dest); + bool anchorAtUpperLeft = anchor.x == appUnitDest.x && + anchor.y == appUnitDest.y; + bool exactlyOneImageCopy = aFill.IsEqualEdges(appUnitDest); if (anchorAtUpperLeft && exactlyOneImageCopy) { // The simple case: we can ignore the anchor point and compute the // transformation from the sampled region (the subimage) to the fill rect. @@ -5933,7 +5940,14 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx, anchorPoint = StableRound(anchorPoint); } - gfxRect anchoredDestRect(anchorPoint, scaledDest); + // Compute an unsnapped version of the dest rect's size. We continue to + // follow the pattern that we take |currentMatrix| into account only if + // |didSnap| is true. + gfxSize unsnappedDestSize + = didSnap ? devPixelDest.Size() * currentMatrix.ScaleFactors(true) + : devPixelDest.Size(); + + gfxRect anchoredDestRect(anchorPoint, unsnappedDestSize); gfxRect anchoredImageRect(imageSpaceAnchorPoint, imageSize); // Calculate anchoredDestRect with snapped fill rect when the devPixelFill rect From 3656603a558a19bfcbca204a8eb50e2805c5e485 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Wed, 22 Apr 2015 13:04:06 -0700 Subject: [PATCH 234/241] Bug 1085783 (Part 2) - Add a test for rounding behavior when high-quality downscaling. r=roc --- .../green-circle-with-blue-border.png | Bin 0 -> 12279 bytes .../image-high-quality-scaling-1-ref.html | 22 ++++++++++++++++++ .../image-high-quality-scaling-1.html | 22 ++++++++++++++++++ layout/reftests/pixel-rounding/reftest.list | 4 ++++ 4 files changed, 48 insertions(+) create mode 100644 layout/reftests/pixel-rounding/green-circle-with-blue-border.png create mode 100644 layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html create mode 100644 layout/reftests/pixel-rounding/image-high-quality-scaling-1.html diff --git a/layout/reftests/pixel-rounding/green-circle-with-blue-border.png b/layout/reftests/pixel-rounding/green-circle-with-blue-border.png new file mode 100644 index 0000000000000000000000000000000000000000..570fd24944a815efd7026eea8df31326a206e52d GIT binary patch literal 12279 zcmZ{K1z42ZxBd(`AVVr30)n)3Nq2V)-O>Wm-8hJZbc1w?bTdHn~kFb#eKb|W{&P|!cl;wa(rxFrcP`etn6(68_CV)^?!Hof3WUL{!f~vm(Bk{yD#~R_D30i^-&0^Q2}K~ z3!B&8Ql@T}BAo0T+$`)|ES&6`9Q*?8Tmn4<vxS{Pzg|uq9nAP2C(_G#wr7L?AX^ zmUi~{uM{s?U$S!i#r-GZALRRS2&lT)SRxgCuSO9h{Qr~v8!zc-@8n|X>Uxjo{u}>K z*}w7XmadL=?)TMeIoP;~aQ;pCm-yc-z5gy3;r$QipTd6=bpJQPKZXAw+)sqSA5G~> z+1Oh;{22=;7jiWJYstTvl8$zcE*egz=9c#g`$PGM=-=o+?dbh?J1^PU|JlwzO8#aF zvE5tqKdk#N*ZCtw`i=+~Ij8^eLlLmWHvrPTnbzf{#5KKuyO|h%1k$s2t-dZ|k5MRT z=75iX3qD+WEDlPPRzszC@n(*AcX_7!#M#)${lrMmEy-UCV&Mq_>PbTqrGdc!;N!%r zkOvPjV&Bu?#fwF6-HNt<=wX)?{vj-U_U*Zdr0Ne1RpFD;J-3$9(o$(@wFk3?8aXn_ zp05TKMGc%v_GkN+)2_{`3;0&w$lru7)4N)x8WMlf3}w(-QqW3;kkP%@{$RRasg6}1 z-(9M-r1dCjn55S*!p87hUG-#{v)onFWe~g<*KUDRD&8<6LIIQNpgajB=OXl_6-?OA z^sV-2bA}HszjDc;KE{tF{TqtY+$2*LSM$fL^(svZObn|F4x@W-;K^aKQnkZ$uw5GG zM5lfAu8vcST|PtiZMpo(6?p~eL~5q9Pahsxe$A|z^=udVY%pW)AMeBU!PC(nxRiPB zF&h;;JtTU0F*rLCo=?oeR0|iZKT?| z^jo60V!qq#V|C7bLt8SC3*TeTdf6taQ2T`S93vyIYs~ZONq7p+FTE4@o>KH{B3s{Q zNoc~jQLT4F2Gm!*QxR3;I9Z8{YrbpM=8okIe3$+;>I)Q*D}%_k*|p#8Y{Gb=xvm>x z_SCIL;sc)2$|pxVFSRQo%lQ_9S(GW(WZVP{ZJm1DqX-;`oZjY)mm8*iCy%m%KC-{tS%5HQj zB`{i9-)n*EvvZTSGshUub#O(b&)di;6MK6^ABjYymt+UC^tqC~$K0JGbvmyPz~71ajrO{wWL zs~&i+0^vXB`>1c;*Y+E;cUE7IG5Dq^D`0##O$Mx9wKTt;-6k_;{Y^u}&HcFfz4@U% zg8qhwVV?7SSgDN9`mxqmF`+r*Ibp+DpX^xkRj)9DbkTs>gTCUR?T-?C<_AQzVk=ic z!dDw3QC#~TEu4$KmNPns_Qse|tQU}?R}NJ6?Z$JQ+H>xWYHD5Bcg?Ot*}uOH(}%(q zUpSqIL=1kvc%f4H+%BwasPm5Avn<}xcr8(a;QF-s-8{Je@*^RBD&NUM7t61%gl z$<9&3<=zh~#Kpl$P=b9E@sB$fMj$LLm3`_1vErAUX4x9kFdvyBMlnt=VfnxRP)Rm3^SiVg>U`6%48aG zjhS`H==?7tefY**ffH3b`Pn17+}>e#B05Wzeno5R1u&mxx3{YEb__-@2`PM!i&})w zrNwRL^Ow_zm*WWLzsj5mR9&9PNE*;?o-X#i3;1$IZESz#7f|D(ydlZuv`b&as)_b? zLwa7=us$^)rp_niw=JYP;AhYHt`Vn4SZI$&yMX8l>3S@dpZQ&LRM2s~A+7Hm`cUV| zW%!jZgYyQx&5v&_435HP17kWq7t?cuZ7ti0;b|N|G4)ZC*dodRG6h#__=lqqQeLS~rU^*S>?uzkO$8 zjMp9~2t2g&Dv?}y@`~do##i*2{fIwWl)Ej@87geJq!euo?rt|~pGNxP;UVUDC&q{9 zcjD>~RCEeF5z}91#>C`F+JSty80GvY3~5{H#)v3$8^rhF*>GMkR^wtZuO}k)3&~ zE59vM6#8nQfBdP*yl!fdlx}bQ+Cak0EpqBzR^6Emj5kyGqg?4r(afTlrUXYLqo;y>z zk;3L&2p{_LF+Xk|m$o+kBUVVP1V(5q>dx@eQ{(xy<6bhlvK$X;#9ty&JP@ zkar#+u>Qw|3&@;^jK&wW@q%)HDT7Lz!^-iQjdSt_6U9r>P@6ZALN-~~-y_n(V>wEo z$4kbAYqe@GZG*aE9Dj1Urn-kupZSM5>Zx7c+3&!T^rL~;3L~|z8L72>j0T`sVsm_5 z$2b|K)=dw#g(+E9&Kl+ODwzT6OnyBUov$1}W$TtMeM;jzH#kv`ACsTEguinoY}!=n zNa=`=HgDK{>s=M2#D9zdTLK2NvRSR#O|X|rHDA3v$~Meg9zj@%JJ?(vsUKW1TvO3R z&N&~C-op01-k%}x07bO(#`A?34i~u>4|qlGD-7Pv=J0ns-&Eez*wnkFa;P~LL40v- zwDGZ4&$`IF{&nOKA2cVR0pLPk%Uqi+lFXJEpDps`>l@y9fx1z2(-wL4E?%ZdSSi%V zU0-(KN<{^J@yzpXR%^rO9d8VR`icElfG3=Ky}8)!s{e%5vk!F>x1FL+xO?ltC6Uj^ zZ!=`CU#5D&f3H*MZE~UB!I#oz6E=9W6KlM6Dt}0{b}Ay*S=dz)E$`%(XL&J zYg3M+wb^)ShU^VLS4ROLR&L(WE8V#r}&$ zdd^CL($yafw~gPUlX3PP;fL1WcCwwvG~-B!9B%90Kq8W}>}q7kRmYN&qWw-u*ye(! zKHhCOzk?@mSywRC5L`Yar(I%rc!Sf9i?#oh)N+L%W~w(0t5wy?TKD17+R8-3S9~8L zEmNOx-J}>8BE3zJvtXzbJ8{(sh+V8O`E~6Ry+^rMNMv!ESruMlPO_pmj!%-Ut`|ECE;g1)IDD25*Y3<1`Xms&xN8{gp{qRAk zzhb88<{XYgJ$w(;1ds|PBkM|WY~o12S`o`SH}Pkp!jH2mnoYM*OC0J-EKw(J1OywJC?;;KCE*m_{mkywmACzT*iO#g&DtRo;AP zE40t+*eLxtw7T* zsoN0Vw$qdbF-?F^^3fuw4)F5#MCbWYLak1vo6qMt!wD2@ovicd>*ME;mz?{ypaR^5 zWbF}&bdzw=x7Ua`dlD`w7H;CFZ?DNY_V94$wiPun9F+anvim27C#J1`bz;Q^rP*+^ zr|vZi1}ypL^3fR^wY+awgoy3#JoW3-pg=$8(0)vP!CKLFdO63Jb$$z9L?KtK!FT{N z1M}fpb>c!SOcJ72ud-q|ZO2~ZbbU#{fz_WKRWB;?o$N{M~ZpNt$ zHkkK8FTY7IzQE7(OccX*M;u@>lwMNb3JakDn|tM4$3zl)eau{#?wOS@V@{2VOAkOA zeGVZ|QH@V5D$;$l?*|vH zUld*<2)Tb`-{A|s3>;Q?cSV=Eg{cT6*M|z2#H{tHWxa+O>t^e@<|a|=Xxogc4#!;g zZ42(kqcDRs_0zIn>pet)p#Q42|K-Yk)NZHO)=rd8kd>XU{OFQo6}->h(~}hyIeQ*p zJHU3H>e=n={W!`SzNuvV2&DP?add4IRG1>x-aMf+YVRz0`BX?$DxG4Ji2(rKkL{7n zsZZsre6o`?5S?_LVRy0ZRV3YTy@(*QQe$N3)D)vFlIHm)1waXuY>0BNK!e>`*;KpB zhh7PZiid(2;s^jBuk)p)2`ak1>ymcR1;bfCm8$L(Q{@H2&~loG9FPqBeol?fFvfzA z>xV^vLE9p*lri%c-jw!{v1e9pPPTZw+yd)V|)Xq6}twG-27g=qi zh%c3TQyO8;?h*pVGZutR;KbfgB@v3mDxC2uUDKbQqh55QE@T~dHU79Lp1WP?i#Uec zLen*=D93m>T(IU$+nm^lJ=OiSN1(zx+^huX8?ZIVOLy7yu~hfPf;(lU33|^!qz)|vC=l)QJEHIO*)qdK zuV5is{HxN5jE(+LGY}qz935a%MVPwBR^g5wZaM#2>%RU)b9wvEinZ3{T5S3h0w*pH$}>zM>?AIYgy^}~@UQuvJhAJ`q1#Bx+ESTQ z=VUO6L}4_aQK-ezCOg8$M;kBjG)1S6xlObeYc7CNf(JYFx=&Hd1PnSyIS>)2WD>F} ziI13O>eX2pOu|rxuYyW#{HCzSiJ~6`5rihhhhUEI@S^rxre-!cr_& zXW{dSDAX^=&K43SjOBoyj5&uPQF(l;Q$U0u=T5a`QfP%KDFj(x6AHb%phqZN=gly0 zWG%t3Ejvf6%si~z1bkazYXm+x=R4u`vPt4Z^4?l#48z*jGOr${#Kb6O)FEonTn<#h z$P3iN;e>fS`*h~8oil%;zk9vZWyh0;;W&w4KN5xB_w;!7u-(d2(xVKyo3cY4q6N(r z0EV)J+j$R+^tHS%#B@BITtt`C%kkD)6oJP^eqwCwc1AbKes8^h6+m_usg7j=Kk-Xo zT4dgk_SeaRpO!!;ISl|P#K@EGP}L6)e8e3;#3E_UgvkHZpg6Gt6(~{zKsyn#lzzV8 z${tCEk(p6-l56P61buAXv#;!D%=foM?t?#vYJV)BRKj`9EKEviCn-?F83GS^D&VRZTeC+Z^dM}G~W}jYXcJ{ZQ~vH zjamde8nvtX5Sbjlcy@Tl!$G3J5~N zA~b#Aze->m=fn*b2-x|B$+(UNV*ew~ObKp-ip#sS!QPXay+|nlqvjX1?>RhM{ zi$8fU_Lg;wDeswjCkvQ7`d8AFi{Th=x!5~B}37<5J`&| z73vCLY6&WMR{#|OO{{pb{9r^_xhTt#_3~2TS^63RBfsdEXu&WKt3GP&&ym^}K-m~_ zL?XV-y(!kdVC{Hch7rhm(_a?GDG%hOhqB1(D%KBqx|`yA+<@03j51v0fjxwfw5qJ- z!0i&YV#x({=QVCS@djIo?}R-o)S(4XMX;37lkQ3mA$m*fK>IBdN{^M0izd>1lp!k6 zTq!_?u8M`M_5HJS!jTAHxY&X`@C7)>0tG%Z{xXbNKI474wRzBopJE#L_@n@1NlBjL_!867{ zUTIYad7#uEatX8K0-78z+oL1~xB=M2>PcsVrjhn@4BVr41Vwi0oyuSnWY6ObgEO+} zO$Wc>I)Jn0;_p`vWOw9?#Vgo?W8Zji-}hVgzP|MHQA8tlwyFwry*YZ0=Xd{}1h;tO_>av+GP32ag{)yea$!xj(7&L-zPM0dYX zD7==#e%A59k@t(L!+aT_pSMccueBL>u>FdF0yba7;(ZE35%NAoc}`Javwf zvrCE9`9|HxkWS!~@E5WfgY){ulSc@L?dL8#@klKp+0?8!#qZB$9^~1v{bdbNJv$L` zg=GMyoo_5Y$s&mxgdh_qyg@e@@JDBZfY;;M)p*yJ+~_xwovbRzShNJrQJPXOKO`d# zZO_fEDqK2XA~!WXmIU;e)7$Qa{Oc0OmEx zZ<6*X%j1S+j~kZ{`qhHFDgZ+k_ukDyO)3`^uKO-Y7Bi(9E>?D!c)zd%CLSsYAfQ$` zB!^ls(+F$#T#tdDMRF;rV+FZxG5=ZNo_rWoZ0h^vK<)_Ak^}Q;0}8)(yOJU11x!@= zGq$&y7!_ziLX`lSKMPr?n?>fR*tOY{gWU^<0ur+SRPvQOn6`~cNdF4O(1sBKzD(LkZdung+v!LJ$af$2f~7g_43u- zi*ZlH=(@r~(VyaxHB*2LH2`Z9X~;10Vt|*Md(>RZzc@HHyOT3VNWF6&8HPG@kFcMj z#j{-So`)2y&$}`c<9PN4p^|;lpki1g{wsui*jptZ)UTNw_w@Nhtcl662mvOFk%l-f z`?`(mhN`f9FzYu;_MfG^*N#FCb`S4?Fw7O5vM!#GE8}LOHkCP$emoNl@cqTqIiZkb zTDnUI%kSwXJrOcX+A$%zL0!thqK!k5p@-I>AEWe4Y0dZYS{!eMmJw3^CO0+8I+X{; zFhFapR4Z8!xSzO8Lzx^pLjTxQI)T{F+M?;?J%;&Kli_;lu#avJJvDIS4T`{@ziY|x zjfPyP#TANGMg_7UOye0~;~b>a>6Oc;9DjBZPK_wb4OcT-fJP)DiUkoXT=o1=M#)C8 zB#P)#0o-H&WY`6I5aKi=H%0lV`n6J zZ~5SJOb=(|R)mWIdWhDG(s(LDwvR0%9Fo<*TdxuqkZO06gd9#IBlK`RQg^^ll{mbu zPHIq5BKxbSZO|9*efpgEkn(;W_tX_`G_s=`DHmLhmelf`CTA)*6d7(L3B=@4wTsSv z|E^*k@ay4Igm=l3J*lEm*ded~^$mw%Q3M2;glb*IbLTD5?&xd&4W<+Kl>*`O@I}1n}p?$FYAeWO_y=yj_{2F zO`{sAzjv%+#Hb2^T2?1~YouVMX2D*)>XzehYv-MtFl@^N6dyv!R*9H4j)lh1@>O5g zmreR`O@E80tsrDwJ-w;Bib@J6aDgCRCMXR>b& zs+yB%+PzE~KKgXcYi4dXziwTAr?O5J{4@`Mt3#iimsh2In@mW%yl}K0F+y}KWmNGK z&s;8H5QD))jl#m>1EgP|EiG+L%MUK`SX%MX71`=Jb};(&dVzm+y7~~whxCE@Kl|2c z0>}rmZtUNIN<4EWLHpQGT%T`JgmDV$9}7VL1a?x8Q=XI_Ek4`{hR)?k%)3d{@cbY} zuvfB9fYN|wXiW>Ci;_1p)kzckr6JHT!;w8r)<;hQ)Xk+5^f2+=sNhQ-gJ9ufs)+FO4*;TuaJ! zo1+nnn^RXRx=*x9I3wiBe!|HL=1l3|>A|67NMc#flZ)nO&Aa)n;C8_LqAz z)AuJt1x16wWP&O!iq&Y&rIv3OG$r-LbVqQi9qCwmBVGRufq)?4CdH7xi1)y39Au^TA>p&3q+No{^XTX!m!?R6zQetx>4r5`N_3c&mOJw3V7BG`Va zn{)i1_FgH<4+w7H7qVr!XGj+p05pI}8Al(K@PQ8>;QZv7Y9=`kF&kHvb~uJ&kE>1y zpv=Aiy&+tr3=I{t6|O(HnanZhPN;&P@Mmr^&*_`ZZm5Y_(iP#uAJ3qo{N&+jo;?rg zPI$3GJ$HYy=G(N5W$Ns~!u93he6xNvug1XcINTqxtHXzBd?*W-x>N!4AvFUMJi@Wb z!u-YWyvU{Z62YG7x9nJ(d3nVhw6Sqs%5wAk7kGc-aDS!fXACDFf!a&NqGeZV;3i72 zgeg;24q3m{2k}Daki03AM?xTPPPF|ByACemM2Rv+NpNE#(><@wq{68>${oC$fYJaq zw99vSXWvN*3Dx5tobKUmy6E_d+Wk0|n{Vlh)we50!Oscta)HK#5R9&@SoBF~qp_m( zmGKJ%d+VC#H?|xtq$NfiE9h!|GT{dBK=JBM#7H*m7=3jFF3@E6BA-EHf_rweEV+s& zUU?{}5iXjdK1H2$+bPW6!;|+pxhS>nGg~*BoL0?wZGmS81`u|l&Au_gl9L?GAl@H~ zao2{e)wW_zUhxl?D>}Ns)@!pQdZ>CMYl370nW`x@aB?uM`f(RB&pabpKUrVCC9Ze4 zJCVr1Qy(ppfWA&$cmI0?PV5(tdIK0>ewx$fx<+O^tf^2#!w6>r|qh4u}bFkjsr6@LQeHa@_4N zsHth!im~Eup5D$?mGJlV7N2W0HoV@M7qOP$F03?~@^fKTB@6scFaVW)Zo-dZ$i1m6 z1~}ljuTDK&9rLV|ZCp?+Lyq6vf7qy|Nf(3U&}1E-B@7&lU%C>#^2J-@%W~Jax%&qSTR> zo|n+q<9PxX?Z9KsWA0fj6SP6`(K?c+Uh=cEnhQ9V&K~CY^rc#1L}1pQ;PW| zJ#7%gbNn$i`2Yo-Wj5XR`k<93BuW+c^EA1E%M&HjFA^k=rWfo3)FgKG>^Q`&A3CAb zH5E($UKSK!zOLn^rL21#WpM4?v{k=`oS^d*l!>B=TCb7Zq)v>9cLv)vPDBX2k(*sO z;*2Zc==TF6So+uMm%kh;ko0WwXUQKN5bF(apDK_&EwG@oWF!Royg6Q_}DGf*N8nL{#)vZpDfV*H`5v9={`Wyi^5BF zAA8ixbG35;f3j&76|)t%Ty#*pYPc{sNDUTyTbv&_!)aSzjr`UdB)iPHd4ZOtTbXV< zE99EPho4P}v5>f6vo5Mkn6|d>MMuiUM&)_=-Lueq(Yz5M`a#whz z(3CH|UtR5c6nW)6s8-rz#;fQ(e3}r&OW5=nQ@9U<_gI8|k)uic$@l?wQhjvz!v5K% zx_JeE-E#ETPj@#(5c1v8vHX^w;6z!;=i;i>9-iT&Rz1RwLta6-Pm!WO zP+PYFVeuDlcx(vlBfB&}0NGFx?{LCd59d7QJ8m85uGL&Uy%J1Lv-9X@QN3Chu3&mh z|IoH*@NH_b+pPJ@dzg(qgRy2*fj;kMF4MSc!UY}ZQ zwV+HQ5DB+8&pNU_@+V_%yklv?uchZqk%U|=t(xZHVPbw#w1Y+n^4{|V?S(zLniv`5 zMF9A%76!HFGymF--znkyI`8#;O#LQA=

    5X^8m zePq^Tf5o6-v(tE6dyE3L~eL1W!;7?BQjji;t>T&Xu_AmUQ@Rnfg zgfpvK7D^6%_;X!bT=JPScbNFQn(dOnBM&lz{0)`L>+Y9_O}Iii`Ptf(5SsWs*kv1~9E1udPhNba zGmckV&nExu@5G1Q2%Useqjg?C$xYi@6=5NR5`lDU1QwU{R4xr9nEi#2=l{453om}KdR7R)pv6;*e|upNGq|faWg9DQKt=F zppA>P@jX?M>&@)=I=wnY?eWX6Fa`a|+E=2i9`%5JWLL>A-oQ7G5|V7yaMIt?F``bD z4jdYENVA~!iy7&Gqkp!_Y}r0y<~`YW^-YN+%d2c6QoNu=`O z_@cVy2Xuh?Q$QTd$JDX!qz|f}sgAp0{sc3wuw~^yrR&hzW|!*(nz^&R81hsvO~4#6 ziH?3X_{>4)`1oq2vG5=?9IUaCJ#n0oURZX66Iu6H4ic@DVg2|?ZelpvWW)T z_)Hxri^<@|aNu{fGtXAQCAZUg#V#NWPnMgbyMr5k zWAk0>cc8ya5uGYEa-%-eUe($Ij(L_hIBoGC9rd(oH*e_v{&D+FjsICKdL+DcamfMb z`sfQDCH;AYz37OM_hD)FbmgWsE7l|^McJ81Mp@|K>kRCcJM?`ZTN=zSbD@4{jsj(v+sK0(or5kpKdWWKh_U0?SSk`B?5 zdjarA)Ri91zI%$ez4u3^&b0oY8H;PJ+7wS;d)xG6X&Ljj`2b#D`g&Ijjft$VYmgiZ zas9q!a*XqJmr~(ZGaBE;r1#cuzGgiml}3a@A3wt*UFHuW7jU= zw9s}V;tg1#cR4S%l=g%vJbxs~)J5yFI$?!oa90t83=J3j!8FM%^^zf2E4{mviX??Q zta*yBflfrm<`HT9Ou=m|kMb3-qd1qKR)*lp9jc$9Re*E~%lG?ie0gaVsR{{`cmEI6 Cd^~jk literal 0 HcmV?d00001 diff --git a/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html b/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html new file mode 100644 index 000000000000..62df7fa51163 --- /dev/null +++ b/layout/reftests/pixel-rounding/image-high-quality-scaling-1-ref.html @@ -0,0 +1,22 @@ + + + + + + + +

    + +
    + + diff --git a/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html b/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html new file mode 100644 index 000000000000..e3d14a61f930 --- /dev/null +++ b/layout/reftests/pixel-rounding/image-high-quality-scaling-1.html @@ -0,0 +1,22 @@ + + + + + + + +
    + +
    + + diff --git a/layout/reftests/pixel-rounding/reftest.list b/layout/reftests/pixel-rounding/reftest.list index 5a775b41570f..42b9bfda5397 100644 --- a/layout/reftests/pixel-rounding/reftest.list +++ b/layout/reftests/pixel-rounding/reftest.list @@ -123,6 +123,10 @@ fails == collapsed-border-top-6.html border-top-10-ref.html == image-width-left-5.html image-width-5.html == image-width-left-6.html image-width-6.html + +skip pref(image.high_quality_downscaling.enabled,true) == image-high-quality-scaling-1.html image-high-quality-scaling-1-ref.html + + != offscreen-0-ref.html offscreen-10-ref.html == offscreen-background-color-pos-4.html offscreen-0-ref.html == offscreen-background-color-pos-5.html offscreen-10-ref.html From 9b739f4fd0c6a85f65bd2090a56f54feea74088a Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 22 Apr 2015 13:19:48 -0700 Subject: [PATCH 235/241] Bug 1024774 - Followup: Don't redefine the Debugger property in xpcshell tests on a CLOSED TREE; r=jorendorff --- .../devtools/server/tests/unit/test_ReadHeapSnapshot.js | 7 ++++--- .../devtools/server/tests/unit/test_SaveHeapSnapshot.js | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js b/toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js index 44e91a209a9b..21500da3f115 100644 --- a/toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js +++ b/toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js @@ -3,9 +3,10 @@ // Test that we can read core dumps into HeapSnapshot instances. -const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {}); -var Debugger; -addDebuggerToGlobal(this); +if (typeof Debugger != "function") { + const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {}); + addDebuggerToGlobal(this); +} function run_test() { const filePath = getFilePath("core-dump.tmp", true, true); diff --git a/toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js b/toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js index ef37383ac3d7..3d46e3b1056d 100644 --- a/toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js +++ b/toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js @@ -3,9 +3,10 @@ // Test the ChromeUtils interface. -const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {}); -var Debugger; -addDebuggerToGlobal(this); +if (typeof Debugger != "function") { + const { addDebuggerToGlobal } = Cu.import("resource://gre/modules/jsdebugger.jsm", {}); + addDebuggerToGlobal(this); +} function run_test() { ok(ChromeUtils, "Should be able to get the ChromeUtils interface"); From c2e52c59729cd098dc6cb5c0605106afe2b1e78b Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Wed, 22 Apr 2015 14:06:39 -0700 Subject: [PATCH 236/241] Backed out changeset 89e5f92e26d7 (bug 1155634) for being a possible cause of frequent gij(8) orange CLOSED TREE --- dom/indexedDB/ActorsParent.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index ad44a4eddb68..66ffc5ed672a 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -11070,6 +11070,10 @@ Factory::Create(const LoggingInfo& aLoggingInfo) // If this is the first instance then we need to do some initialization. if (!sFactoryInstanceCount) { + if (!gConnectionPool) { + gConnectionPool = new ConnectionPool(); + } + MOZ_ASSERT(!gLiveDatabaseHashtable); gLiveDatabaseHashtable = new DatabaseActorHashtable(); @@ -11901,10 +11905,6 @@ Database::RecvPBackgroundIDBTransactionConstructor( return true; } - if (!gConnectionPool) { - gConnectionPool = new ConnectionPool(); - } - auto* transaction = static_cast(aActor); nsRefPtr startOp = new StartTransactionOp(transaction); @@ -17775,10 +17775,6 @@ OpenDatabaseOp::DispatchToWorkThread() return NS_ERROR_OUT_OF_MEMORY; } - if (!gConnectionPool) { - gConnectionPool = new ConnectionPool(); - } - nsRefPtr versionChangeOp = new VersionChangeOp(this); uint64_t transactionId = From cf6a17b8638089d59098d0f464703af04aaafd10 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Wed, 22 Apr 2015 14:06:52 -0700 Subject: [PATCH 237/241] Backed out changeset 78aab1149276 (bug 1154426) for being a likely cause of gij(8) orange on a CLOSED TREE --- netwerk/streamconv/converters/nsHTTPCompressConv.cpp | 3 ++- netwerk/test/unit/test_content_length_underrun.js | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp index be6504276406..a5dfadaf8f4e 100644 --- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp +++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp @@ -40,7 +40,8 @@ nsHTTPCompressConv::nsHTTPCompressConv() { if (NS_IsMainThread()) { mFailUncleanStops = - Preferences::GetBool("network.http.enforce-framing.http", false); + (Preferences::GetBool("network.http.enforce-framing.soft", false) || + Preferences::GetBool("network.http.enforce-framing.http", false)); } else { mFailUncleanStops = false; } diff --git a/netwerk/test/unit/test_content_length_underrun.js b/netwerk/test/unit/test_content_length_underrun.js index 701b71dc5972..deca6a78df95 100644 --- a/netwerk/test/unit/test_content_length_underrun.js +++ b/netwerk/test/unit/test_content_length_underrun.js @@ -218,8 +218,6 @@ function handler4(metadata, response) function completeTest4(request, data, ctx) { do_check_eq(request.status, Components.results.NS_OK); - - prefs.setBoolPref("network.http.enforce-framing.http1", true); run_gzip_test(99); } From bcd09a7c72ca27d810129fd3990dd42e179f609a Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Thu, 23 Apr 2015 00:10:43 +0300 Subject: [PATCH 238/241] Bug 1135354 - Fix comment regarding URL max length r=me DONTBUILD CLOSED TREE --- netwerk/base/nsURLHelper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwerk/base/nsURLHelper.h b/netwerk/base/nsURLHelper.h index b4a897382b41..94ee2b184190 100644 --- a/netwerk/base/nsURLHelper.h +++ b/netwerk/base/nsURLHelper.h @@ -229,7 +229,7 @@ bool net_IsValidIPv6Addr(const char *addr, int32_t addrLen); /** - * Returns the max length of a URL. The default is 2083. + * Returns the max length of a URL. The default is 1048576 (1 MB). * Can be changed by pref "network.standard-url.max-length" */ int32_t net_GetURLMaxLength(); From 5b2b80e960d4300fb60677789c8b8450609ee676 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Wed, 22 Apr 2015 15:56:50 -0700 Subject: [PATCH 239/241] Backed out changeset cc61b087dfb1 (bug 1145680) for possibly breaking gij(8) CLOSED TREE --- testing/mozbase/docs/mozdevice.rst | 74 ++--- .../mozbase/mozdevice/mozdevice/__init__.py | 1 - testing/mozbase/mozdevice/mozdevice/adb.py | 271 ++++-------------- .../mozdevice/mozdevice/adb_android.py | 67 ++++- .../mozbase/mozdevice/mozdevice/adb_b2g.py | 122 -------- 5 files changed, 143 insertions(+), 392 deletions(-) delete mode 100644 testing/mozbase/mozdevice/mozdevice/adb_b2g.py diff --git a/testing/mozbase/docs/mozdevice.rst b/testing/mozbase/docs/mozdevice.rst index 5e18b56d25b9..eb4325815958 100644 --- a/testing/mozbase/docs/mozdevice.rst +++ b/testing/mozbase/docs/mozdevice.rst @@ -169,39 +169,31 @@ Device Shell methods Informational methods +++++++++++++++++++++ -.. automethod:: ADBDevice.clear_logcat -.. automethod:: ADBDevice.get_battery_percentage -.. automethod:: ADBDevice.get_info -.. automethod:: ADBDevice.get_logcat -.. automethod:: ADBDevice.get_prop -.. automethod:: ADBDevice.get_state - -System control methods -++++++++++++++++++++++ -.. automethod:: ADBDevice.is_device_ready -.. automethod:: ADBDevice.reboot +.. automethod:: ADBDevice.clear_logcat(self, timeout=None) +.. automethod:: ADBDevice.get_logcat(self, filterSpecs=["dalvikvm:I", "ConnectivityService:S", "WifiMonitor:S", "WifiStateTracker:S", "wpa_supplicant:S", "NetworkStateTracker:S"], format="time", filter_out_regexps=[], timeout=None) +.. automethod:: ADBDevice.get_prop(self, prop, timeout=None) +.. automethod:: ADBDevice.get_state(self, timeout=None) File management methods +++++++++++++++++++++++ -.. automethod:: ADBDevice.chmod -.. automethod:: ADBDevice.cp -.. automethod:: ADBDevice.exists -.. automethod:: ADBDevice.is_dir -.. automethod:: ADBDevice.is_file -.. automethod:: ADBDevice.list_files -.. automethod:: ADBDevice.mkdir -.. automethod:: ADBDevice.mv -.. automethod:: ADBDevice.push -.. automethod:: ADBDevice.rm -.. automethod:: ADBDevice.rmdir +.. automethod:: ADBDevice.chmod(self, path, recursive=False, mask="777", timeout=None, root=False) +.. automethod:: ADBDevice.exists(self, path, timeout=None, root=False) +.. automethod:: ADBDevice.is_dir(self, path, timeout=None, root=False) +.. automethod:: ADBDevice.is_file(self, path, timeout=None, root=False) +.. automethod:: ADBDevice.list_files(self, path, timeout=None, root=False) +.. automethod:: ADBDevice.mkdir(self, path, parents=False, timeout=None, root=False) +.. automethod:: ADBDevice.push(self, local, remote, timeout=None) +.. automethod:: ADBDevice.rm(self, path, recursive=False, force=False, timeout=None, root=False) +.. automethod:: ADBDevice.rmdir(self, path, timeout=None, root=False) .. autoattribute:: ADBDevice.test_root Process management methods ++++++++++++++++++++++++++ -.. automethod:: ADBDevice.get_process_list -.. automethod:: ADBDevice.kill -.. automethod:: ADBDevice.pkill -.. automethod:: ADBDevice.process_exist +.. automethod:: ADBDevice.get_process_list(self, timeout=None) +.. automethod:: ADBDevice.kill(self, pids, sig=None, attempts=3, wait=5, timeout=None, root=False) +.. automethod:: ADBDevice.pkill(self, appname, sig=None, attempts=3, wait=5, timeout=None, root=False) +.. automethod:: ADBDevice.process_exist(self, process_name, timeout=None) + ADBAndroid `````````` @@ -209,32 +201,24 @@ ADBAndroid Informational methods +++++++++++++++++++++ -.. automethod:: ADBAndroid.get_battery_percentage +.. automethod:: ADBAndroid.get_battery_percentage(self, timeout=None) System control methods ++++++++++++++++++++++ -.. automethod:: ADBAndroid.is_device_ready -.. automethod:: ADBAndroid.power_on +.. automethod:: ADBAndroid.is_device_ready(self, timeout=None) +.. automethod:: ADBAndroid.power_on(self, timeout=None) +.. automethod:: ADBAndroid.reboot(self, timeout=None) Application management methods ++++++++++++++++++++++++++++++ -.. automethod:: ADBAndroid.install_app -.. automethod:: ADBAndroid.is_app_installed -.. automethod:: ADBAndroid.launch_application -.. automethod:: ADBAndroid.launch_fennec -.. automethod:: ADBAndroid.stop_application -.. automethod:: ADBAndroid.uninstall_app -.. automethod:: ADBAndroid.update_app +.. automethod:: ADBAndroid.install_app(self, apk_path, timeout=None) +.. automethod:: ADBAndroid.is_app_installed(self, app_name, timeout=None) +.. automethod:: ADBAndroid.launch_application(self, app_name, activity_name, intent, url=None, extras=None, wait=True, fail_if_running=True, timeout=None) +.. automethod:: ADBAndroid.launch_fennec(self, app_name, intent="android.intent.action.VIEW", moz_env=None, extra_args=None, url=None, wait=True, fail_if_running=True, timeout=None) +.. automethod:: ADBAndroid.stop_application(self, app_name, timeout=None, root=False) +.. automethod:: ADBAndroid.uninstall_app(self, app_name, reboot=False, timeout=None) +.. automethod:: ADBAndroid.update_app(self, apk_path, timeout=None) -ADBB2G -`````` -.. autoclass:: ADBB2G - -Informational methods -+++++++++++++++++++++ -.. automethod:: ADBB2G.get_battery_percentage -.. automethod:: ADBB2G.get_info -.. automethod:: ADBB2G.get_memory_total ADBProcess `````````` diff --git a/testing/mozbase/mozdevice/mozdevice/__init__.py b/testing/mozbase/mozdevice/mozdevice/__init__.py index a30e7cd56af4..a33bad2c9fc3 100644 --- a/testing/mozbase/mozdevice/mozdevice/__init__.py +++ b/testing/mozbase/mozdevice/mozdevice/__init__.py @@ -4,7 +4,6 @@ from adb import ADBError, ADBRootError, ADBTimeoutError, ADBProcess, ADBCommand, ADBHost, ADBDevice from adb_android import ADBAndroid -from adb_b2g import ADBB2G from devicemanager import DeviceManager, DMError, ZeroconfListener from devicemanagerADB import DeviceManagerADB from devicemanagerSUT import DeviceManagerSUT diff --git a/testing/mozbase/mozdevice/mozdevice/adb.py b/testing/mozbase/mozdevice/mozdevice/adb.py index b23f1aabc47f..02e0cc5cd000 100644 --- a/testing/mozbase/mozdevice/mozdevice/adb.py +++ b/testing/mozbase/mozdevice/mozdevice/adb.py @@ -2,7 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. -import abc import os import posixpath import re @@ -13,7 +12,9 @@ import traceback class ADBProcess(object): - """ADBProcess encapsulates the data related to executing the adb process.""" + """ADBProcess encapsulates the data related to executing the adb process. + + """ def __init__(self, args): #: command argument argument list. self.args = args @@ -63,6 +64,7 @@ class ADBError(Exception): device either exited with a non-zero exitcode or when an unexpected error condition has occurred. Generally, ADBErrors can be handled and the device can continue to be used. + """ pass @@ -71,6 +73,7 @@ class ADBRootError(Exception): root but the device does not support it. This error is fatal since there is no recovery possible by the script. You must either root your device or change your scripts to not require running as root. + """ pass @@ -91,6 +94,7 @@ class ADBTimeoutError(Exception): * Rebooting the device manually. * Rebooting the host. + """ pass @@ -113,6 +117,7 @@ class ADBCommand(object): adbcommand = ADBCommand() except NotImplementedError: print "ADBCommand can not be instantiated." + """ def __init__(self, @@ -131,6 +136,7 @@ class ADBCommand(object): :raises: * ADBError * ADBTimeoutError + """ if self.__class__ == ADBCommand: raise NotImplementedError @@ -201,6 +207,7 @@ class ADBCommand(object): It is the caller's responsibilty to clean up by closing the stdout and stderr temporary files. + """ args = [self._adb_path] if self._adb_host: @@ -250,6 +257,7 @@ class ADBCommand(object): :raises: * ADBTimeoutError * ADBError + """ adb_process = None try: @@ -292,6 +300,7 @@ class ADBHost(ADBCommand): adbhost = ADBHost() adbhost.start_server() + """ def __init__(self, adb='adb', @@ -309,6 +318,7 @@ class ADBHost(ADBCommand): :raises: * ADBError * ADBTimeoutError + """ ADBCommand.__init__(self, adb=adb, adb_host=adb_host, adb_port=adb_port, logger_name=logger_name, @@ -343,6 +353,7 @@ class ADBHost(ADBCommand): It is the caller's responsibilty to clean up by closing the stdout and stderr temporary files. + """ return ADBCommand.command(self, cmds, timeout=timeout) @@ -361,6 +372,7 @@ class ADBHost(ADBCommand): :raises: * ADBTimeoutError * ADBError + """ return ADBCommand.command_output(self, cmds, timeout=timeout) @@ -392,6 +404,7 @@ class ADBHost(ADBCommand): while true; do adb -a fork-server server done + """ self.command_output(["start-server"], timeout=timeout) @@ -405,6 +418,7 @@ class ADBHost(ADBCommand): specified, the value set in the ADBHost constructor is used. :raises: * ADBTimeoutError * ADBError + """ self.command_output(["kill-server"], timeout=timeout) @@ -430,6 +444,7 @@ class ADBHost(ADBCommand): [{'device_serial': 'b313b945', 'state': 'device', 'product': 'd2vzw', 'usb': '1-7', 'device': 'd2vzw', 'model': 'SCH_I535' }] + """ # b313b945 device usb:1-7 product:d2vzw model:SCH_I535 device:d2vzw # from Android system/core/adb/transport.c statename() @@ -458,12 +473,22 @@ class ADBHost(ADBCommand): class ADBDevice(ADBCommand): - """ADBDevice is an abstract base class which provides methods which - can be used to interact with the associated Android or B2G based - device. It must be used via one of the concrete implementations in - :class:`ADBAndroid` or :class:`ADBB2G`. + """ADBDevice provides methods which can be used to interact with + the associated Android-based device. + + Android specific features such as Application management are not + included but are provided via the ADBAndroid interface. + + :: + + from mozdevice import ADBDevice + + adbdevice = ADBDevice() + print adbdevice.list_files("/mnt/sdcard") + if adbdevice.process_exist("org.mozilla.fennec"): + print "Fennec is running" + """ - __metaclass__ = abc.ABCMeta def __init__(self, device=None, @@ -507,6 +532,8 @@ class ADBDevice(ADBCommand): :raises: * ADBError * ADBTimeoutError * ValueError + + """ ADBCommand.__init__(self, adb=adb, adb_host=adb_host, adb_port=adb_port, logger_name=logger_name, @@ -562,9 +589,6 @@ class ADBDevice(ADBCommand): except ADBError: self._ls += " -a" - # Do we have cp? - self._have_cp = self.shell_bool("type cp") - self._logger.debug("ADBDevice: %s" % self.__dict__) def _get_device_serial(self, device): @@ -605,6 +629,7 @@ class ADBDevice(ADBCommand): def _escape_command_line(cmd): """Utility function to return escaped and quoted version of command line. + """ quoted_cmd = [] @@ -627,6 +652,7 @@ class ADBDevice(ADBCommand): def _get_exitcode(file_obj): """Get the exitcode from the last line of the file_obj for shell commands. + """ file_obj.seek(0, os.SEEK_END) @@ -764,6 +790,7 @@ class ADBDevice(ADBCommand): It is the caller's responsibilty to clean up by closing the stdout and stderr temporary files. + """ return ADBCommand.command(self, cmds, @@ -786,6 +813,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBError + """ return ADBCommand.command_output(self, cmds, device_serial=self._device_serial, @@ -933,6 +961,7 @@ class ADBDevice(ADBCommand): It is the caller's responsibilty to clean up by closing the stdout and stderr temporary files. + """ if root: ld_library_path='LD_LIBRARY_PATH=/vendor/lib:/system/lib' @@ -1008,6 +1037,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError + """ adb_process = None try: @@ -1041,6 +1071,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError * ADBError + """ adb_process = None try: @@ -1084,6 +1115,7 @@ class ADBDevice(ADBCommand): in the ADBDevice constructor is used. :raises: * ADBTimeoutError * ADBError + """ self.command_output(["logcat", "-c"], timeout=timeout) @@ -1114,6 +1146,7 @@ class ADBDevice(ADBCommand): :returns: list of lines logcat output. :raises: * ADBTimeoutError * ADBError + """ cmds = ["logcat", "-v", format, "-d"] + filter_specs lines = self.command_output(cmds, timeout=timeout).split('\r') @@ -1136,6 +1169,7 @@ class ADBDevice(ADBCommand): :returns: string value of property. :raises: * ADBTimeoutError * ADBError + """ output = self.shell_output('getprop %s' % prop, timeout=timeout) return output @@ -1152,6 +1186,7 @@ class ADBDevice(ADBCommand): :returns: string value of adb get-state. :raises: * ADBTimeoutError * ADBError + """ output = self.command_output(["get-state"], timeout=timeout).strip() return output @@ -1171,6 +1206,7 @@ class ADBDevice(ADBCommand): be found. :raises: * ADBTimeoutError * ADBError + """ ip_regexp = re.compile(r'(\w+)\s+UP\s+([1-9]\d{0,2}\.\d{1,3}\.\d{1,3}\.\d{1,3})') data = self.shell_output('netcfg') @@ -1224,6 +1260,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError * ADBError + """ path = posixpath.normpath(path.strip()) self._logger.debug('chmod: path=%s, recursive=%s, mask=%s, root=%s' % @@ -1269,6 +1306,7 @@ class ADBDevice(ADBCommand): :returns: boolean - True if path exists. :raises: * ADBTimeoutError * ADBRootError + """ path = posixpath.normpath(path) return self.shell_bool('ls -a %s' % path, timeout=timeout, root=root) @@ -1289,6 +1327,7 @@ class ADBDevice(ADBCommand): directory. :raises: * ADBTimeoutError * ADBRootError + """ path = posixpath.normpath(path) return self.shell_bool('ls -a %s/' % path, timeout=timeout, root=root) @@ -1309,6 +1348,7 @@ class ADBDevice(ADBCommand): file. :raises: * ADBTimeoutError * ADBRootError + """ path = posixpath.normpath(path) return ( @@ -1331,6 +1371,7 @@ class ADBDevice(ADBCommand): :returns: list of files/directories contained in the directory. :raises: * ADBTimeoutError * ADBRootError + """ path = posixpath.normpath(path.strip()) data = [] @@ -1366,6 +1407,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError * ADBError + """ path = posixpath.normpath(path) if parents: @@ -1407,6 +1449,7 @@ class ADBDevice(ADBCommand): set in the ADBDevice constructor is used. :raises: * ADBTimeoutError * ADBError + """ self.command_output(["push", os.path.realpath(local), remote], timeout=timeout) @@ -1426,6 +1469,7 @@ class ADBDevice(ADBCommand): set in the ADBDevice constructor is used. :raises: * ADBTimeoutError * ADBError + """ self.command_output(["pull", remote, os.path.realpath(local)], timeout=timeout) @@ -1451,6 +1495,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError * ADBError + """ cmd = "rm" if recursive: @@ -1478,6 +1523,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError * ADBError + """ self.shell_output("rmdir %s" % path, timeout=timeout, root=root) if self.is_dir(path, timeout=timeout, root=root): @@ -1499,6 +1545,7 @@ class ADBDevice(ADBCommand): on the device. :raises: * ADBTimeoutError * ADBError + """ adb_process = None try: @@ -1560,6 +1607,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError * ADBError + """ pid_list = [str(pid) for pid in pids] for attempt in range(attempts): @@ -1607,6 +1655,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBRootError * ADBError + """ procs = self.get_process_list(timeout=timeout) # limit the comparion to the first 75 characters due to a @@ -1639,6 +1688,7 @@ class ADBDevice(ADBCommand): :raises: * ADBTimeoutError * ADBError + """ if not isinstance(process_name, basestring): raise ADBError("Process name %s is not a string" % process_name) @@ -1668,204 +1718,3 @@ class ADBDevice(ADBCommand): if proc_name == app[:75]: return True return False - - def cp(self, source, destination, recursive=False, timeout=None, - root=False): - """Copies a file or directory on the device. - - :param source: string containing the path of the source file or - directory. - :param destination: string containing the path of the destination file - or directory. - :param recursive: optional boolean indicating if a recursive copy is to - be performed. Required if the source is a directory. Defaults to - False. Think cp -R source destination. - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADBDevice constructor is used. - :raises: * ADBTimeoutError - * ADBRootError - * ADBError - """ - source = posixpath.normpath(source) - destination = posixpath.normpath(destination) - if self._have_cp: - r = '-R' if recursive else '' - self.shell_output('cp %s %s %s' % (r, source, destination), - timeout=timeout, root=root) - return - - # Emulate cp behavior depending on if source and destination - # already exists and whether they are a directory or file. - if not self.exists(source, timeout=timeout, root=root): - raise ADBError("cp: can't stat '%s': No such file or directory" % - source) - - if self.is_file(source, timeout=timeout, root=root): - if self.is_dir(destination, timeout=timeout, root=root): - # Copy the source file into the destination directory - destination = posixpath.join(destination, - posixpath.basename(source)) - self.shell_output('dd if=%s of=%s' % (source, destination), - timeout=timeout, root=root) - return - - if self.is_file(destination, timeout=timeout, root=root): - raise ADBError('cp: %s: Not a directory' % destination) - - if not recursive: - raise ADBError("cp: omitting directory '%s'" % source) - - if self.is_dir(destination, timeout=timeout, root=root): - # Copy the source directory into the destination directory. - destination_dir = posixpath.join(destination, - posixpath.basename(source)) - else: - # Copy the contents of the source directory into the - # destination directory. - destination_dir = destination - - try: - # Do not create parent directories since cp does not. - self.mkdir(destination_dir, timeout=timeout, root=root) - except ADBError as e: - if 'File exists' not in e.message: - raise - - for i in self.list_files(source, timeout=timeout, root=root): - self.cp(posixpath.join(source, i), - posixpath.join(destination_dir, i), - recursive=recursive, - timeout=timeout, root=root) - - def mv(self, source, destination, timeout=None, root=False): - """Moves a file or directory on the device. - - :param source: string containing the path of the source file or - directory. - :param destination: string containing the path of the destination file - or directory. - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADBDevice constructor is used. - :raises: * ADBTimeoutError - * ADBRootError - * ADBError - """ - source = posixpath.normpath(source) - destination = posixpath.normpath(destination) - self.shell_output('mv %s %s' % (source, destination), timeout=timeout, - root=root) - - def reboot(self, timeout=None): - """Reboots the device. - - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADB constructor is used. - :raises: * ADBTimeoutError - * ADBError - - reboot() reboots the device, issues an adb wait-for-device in order to - wait for the device to complete rebooting, then calls is_device_ready() - to determine if the device has completed booting. - """ - self.command_output(["reboot"], timeout=timeout) - self.command_output(["wait-for-device"], timeout=timeout) - return self.is_device_ready(timeout=timeout) - - @abc.abstractmethod - def is_device_ready(self, timeout=None): - """Abstract class that returns True if the device is ready. - - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADB constructor is used. - :raises: * ADBTimeoutError - * ADBError - """ - return - - @abc.abstractmethod - def get_battery_percentage(self, timeout=None): - """Abstract class that returns the battery charge as a percentage. - - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADBDevice constructor is used. - :returns: battery charge as a percentage. - :raises: * ADBTimeoutError - * ADBError - """ - return - - def get_info(self, directive=None, timeout=None): - """ - Returns a dictionary of information strings about the device. - - :param directive: information you want to get. Options are: - - `battery` - battery charge as a percentage - - `disk` - total, free, available bytes on disk - - `id` - unique id of the device - - `os` - name of the os - - `process` - list of running processes (same as ps) - - `systime` - system time of the device - - `uptime` - uptime of the device - - If `directive` is `None`, will return all available information - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADB constructor is used. - :raises: * ADBTimeoutError - * ADBError - """ - directives = ['battery', 'disk', 'id', 'os', 'process', 'systime', - 'uptime'] - - if (directive in directives): - directives = [directive] - - info = {} - if 'battery' in directives: - info['battery'] = self.get_battery_percentage(timeout=timeout) - if 'disk' in directives: - info['disk'] = self.shell_output('df /data /system /sdcard', - timeout=timeout).splitlines() - if 'id' in directives: - info['id'] = self.command_output(['get-serialno'], timeout=timeout) - if 'os' in directives: - info['os'] = self.shell_output('getprop ro.build.display.id', - timeout=timeout) - if 'process' in directives: - ps = self.shell_output('ps', timeout=timeout) - info['process'] = ps.splitlines() - if 'systime' in directives: - info['systime'] = self.shell_output('date', timeout=timeout) - if 'uptime' in directives: - uptime = self.shell_output('uptime', timeout=timeout) - if uptime: - m = re.match('up time: ((\d+) days, )*(\d{2}):(\d{2}):(\d{2})', - uptime) - if m: - uptime = '%d days %d hours %d minutes %d seconds' % tuple( - [int(g or 0) for g in m.groups()[1:]]) - info['uptime'] = uptime - return info diff --git a/testing/mozbase/mozdevice/mozdevice/adb_android.py b/testing/mozbase/mozdevice/mozdevice/adb_android.py index 0ee03c6eeedb..c519299aad62 100644 --- a/testing/mozbase/mozdevice/mozdevice/adb_android.py +++ b/testing/mozbase/mozdevice/mozdevice/adb_android.py @@ -10,19 +10,8 @@ from adb import ADBDevice, ADBError from distutils.version import StrictVersion -class ADBAndroid(ADBDevice): - """ADBAndroid implements :class:`ADBDevice` providing Android-specific - functionality. - - :: - - from mozdevice import ADBAndroid - - adbdevice = ADBAndroid() - print adbdevice.list_files("/mnt/sdcard") - if adbdevice.process_exist("org.mozilla.fennec"): - print "Fennec is running" - """ +class ADBAndroidMixin(object): + """Mixin to extend ADB with Android-specific functionality""" # Informational methods @@ -38,6 +27,7 @@ class ADBAndroid(ADBDevice): :returns: battery charge as a percentage. :raises: * ADBTimeoutError * ADBError + """ level = None scale = None @@ -75,6 +65,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ self.command_output(["wait-for-device"], timeout=timeout) pm_error_string = "Error: Could not access the Package Manager" @@ -126,6 +117,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ try: self.shell_output('svc power stayon true', timeout=timeout) @@ -136,6 +128,30 @@ class ADBAndroid(ADBDevice): raise self._logger.warning('Unable to set power stayon true: %s' % e) + def reboot(self, timeout=None): + """Reboots the device. + + This method uses the Android only package manager to determine + if the device is ready after the reboot. + + :param timeout: optional integer specifying the maximum time in + seconds for any spawned adb process to complete before + throwing an ADBTimeoutError. + This timeout is per adb call. The total time spent + may exceed this value. If it is not specified, the value + set in the ADB constructor is used. + :raises: * ADBTimeoutError + * ADBError + + reboot() reboots the device, issues an adb wait-for-device in order to + wait for the device to complete rebooting, then calls is_device_ready() + to determine if the device has completed booting. + + """ + self.command_output(["reboot"], timeout=timeout) + self.command_output(["wait-for-device"], timeout=timeout) + return self.is_device_ready(timeout=timeout) + # Application management methods def install_app(self, apk_path, timeout=None): @@ -151,6 +167,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ data = self.command_output(["install", apk_path], timeout=timeout) if data.find('Success') == -1: @@ -170,6 +187,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ pm_error_string = 'Error: Could not access the Package Manager' data = self.shell_output("pm list package %s" % app_name, timeout=timeout) @@ -201,6 +219,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ # If fail_if_running is True, we throw an exception here. Only one # instance of an application can be running at once on Android, @@ -257,6 +276,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ extras = {} @@ -293,6 +313,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ version = self.shell_output("getprop ro.build.version.release", timeout=timeout, root=root) @@ -331,6 +352,7 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ if self.is_app_installed(app_name, timeout=timeout): data = self.command_output(["uninstall", app_name], timeout=timeout) @@ -353,8 +375,27 @@ class ADBAndroid(ADBDevice): set in the ADB constructor is used. :raises: * ADBTimeoutError * ADBError + """ output = self.command_output(["install", "-r", apk_path], timeout=timeout) self.reboot(timeout=timeout) return output + + +class ADBAndroid(ADBDevice, ADBAndroidMixin): + """ADBAndroid provides all of the methods of :class:`mozdevice.ADB` with + Android specific extensions useful for that platform. + + :: + + from mozdevice import ADBAndroid as ADBDevice + + adb = ADBDevice(...) + + if adb.is_device_ready(): + adb.install_app("/tmp/build.apk") + adb.launch_fennec("org.mozilla.fennec") + + """ + pass diff --git a/testing/mozbase/mozdevice/mozdevice/adb_b2g.py b/testing/mozbase/mozdevice/mozdevice/adb_b2g.py deleted file mode 100644 index 69facebe3dd8..000000000000 --- a/testing/mozbase/mozdevice/mozdevice/adb_b2g.py +++ /dev/null @@ -1,122 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this file, -# You can obtain one at http://mozilla.org/MPL/2.0/. - -import traceback - -import mozfile - -from adb import ADBDevice, ADBError - - -class ADBB2G(ADBDevice): - """ADBB2G implements :class:`ADBDevice` providing B2G-specific - functionality. - - :: - - from mozdevice import ADBB2G - - adbdevice = ADBB2G() - print adbdevice.list_files("/mnt/sdcard") - if adbdevice.process_exist("b2g"): - print "B2G is running" - """ - - def get_battery_percentage(self, timeout=None): - """Returns the battery charge as a percentage. - - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADBDevice constructor is used. - :returns: battery charge as a percentage. - :raises: * ADBTimeoutError - * ADBError - """ - with mozfile.NamedTemporaryFile() as tf: - self.pull('/sys/class/power_supply/battery/capacity', tf.name, - timeout=timeout) - try: - with open(tf.name) as tf2: - return tf2.read().splitlines()[0] - except Exception as e: - raise ADBError(traceback.format_exception_only( - type(e), e)[0].strip()) - - def get_memory_total(self, timeout=None): - """Returns the total memory available with units. - - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADBDevice constructor is used. - :returns: memory total with units. - :raises: * ADBTimeoutError - * ADBError - """ - meminfo = {} - with mozfile.NamedTemporaryFile() as tf: - self.pull('/proc/meminfo', tf.name, timeout=timeout) - try: - with open(tf.name) as tf2: - for line in tf2.read().splitlines(): - key, value = line.split(':') - meminfo[key] = value.strip() - except Exception as e: - raise ADBError(traceback.format_exception_only( - type(e), e)[0].strip()) - return meminfo['MemTotal'] - - def get_info(self, directive=None, timeout=None): - """ - Returns a dictionary of information strings about the device. - - :param directive: information you want to get. Options are: - - `battery` - battery charge as a percentage - - `disk` - total, free, available bytes on disk - - `id` - unique id of the device - - `memtotal` - total memory available on the device - - `os` - name of the os - - `process` - list of running processes (same as ps) - - `systime` - system time of the device - - `uptime` - uptime of the device - - If `directive` is `None`, will return all available information - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADB constructor is used. - :raises: * ADBTimeoutError - * ADBError - """ - info = super(ADBB2G, self).get_info(directive=directive, - timeout=timeout) - - directives = ['memtotal'] - if (directive in directives): - directives = [directive] - - if 'memtotal' in directives: - info['memtotal'] = self.get_memory_total(timeout=timeout) - return info - - def is_device_ready(self, timeout=None): - """Returns True if the device is ready. - - :param timeout: optional integer specifying the maximum time in - seconds for any spawned adb process to complete before - throwing an ADBTimeoutError. - This timeout is per adb call. The total time spent - may exceed this value. If it is not specified, the value - set in the ADB constructor is used. - :raises: * ADBTimeoutError - * ADBError - """ - return self.shell_bool('ls /sbin', timeout=timeout) From c45d6ca104f4420ceb35dea3eb4cd0fba2e663f0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 22 Apr 2015 17:13:57 -0700 Subject: [PATCH 240/241] Bug 1154426 - Ignore gzip problems if only soft-enforcing. r=mcmanus --- netwerk/streamconv/converters/nsHTTPCompressConv.cpp | 3 +-- netwerk/test/unit/test_content_length_underrun.js | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp index a5dfadaf8f4e..be6504276406 100644 --- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp +++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp @@ -40,8 +40,7 @@ nsHTTPCompressConv::nsHTTPCompressConv() { if (NS_IsMainThread()) { mFailUncleanStops = - (Preferences::GetBool("network.http.enforce-framing.soft", false) || - Preferences::GetBool("network.http.enforce-framing.http", false)); + Preferences::GetBool("network.http.enforce-framing.http", false); } else { mFailUncleanStops = false; } diff --git a/netwerk/test/unit/test_content_length_underrun.js b/netwerk/test/unit/test_content_length_underrun.js index deca6a78df95..701b71dc5972 100644 --- a/netwerk/test/unit/test_content_length_underrun.js +++ b/netwerk/test/unit/test_content_length_underrun.js @@ -218,6 +218,8 @@ function handler4(metadata, response) function completeTest4(request, data, ctx) { do_check_eq(request.status, Components.results.NS_OK); + + prefs.setBoolPref("network.http.enforce-framing.http1", true); run_gzip_test(99); } From 6ee41913fbff4603319b9122cf85e46c0df5f0ae Mon Sep 17 00:00:00 2001 From: Ben Turner Date: Wed, 22 Apr 2015 17:14:44 -0700 Subject: [PATCH 241/241] Bug 1155634 - Move ConnectionPool creation closer to where we actually use it and at a point guaranteed to be after QuotaManager has been started. r=khuey relanding CLOSED TREE --- dom/indexedDB/ActorsParent.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 66ffc5ed672a..ad44a4eddb68 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -11070,10 +11070,6 @@ Factory::Create(const LoggingInfo& aLoggingInfo) // If this is the first instance then we need to do some initialization. if (!sFactoryInstanceCount) { - if (!gConnectionPool) { - gConnectionPool = new ConnectionPool(); - } - MOZ_ASSERT(!gLiveDatabaseHashtable); gLiveDatabaseHashtable = new DatabaseActorHashtable(); @@ -11905,6 +11901,10 @@ Database::RecvPBackgroundIDBTransactionConstructor( return true; } + if (!gConnectionPool) { + gConnectionPool = new ConnectionPool(); + } + auto* transaction = static_cast(aActor); nsRefPtr startOp = new StartTransactionOp(transaction); @@ -17775,6 +17775,10 @@ OpenDatabaseOp::DispatchToWorkThread() return NS_ERROR_OUT_OF_MEMORY; } + if (!gConnectionPool) { + gConnectionPool = new ConnectionPool(); + } + nsRefPtr versionChangeOp = new VersionChangeOp(this); uint64_t transactionId =