diff --git a/Makefile b/Makefile
index 0123e00..3fdb95e 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,15 @@
 WEBPACK := ./node_modules/webpack-cli/bin/cli.js
 RELEASE_SCRIPT := bash tools/release.bash
 
+# The sed command and the third_party/google-protobuf-commonjs_strict folder are
+# needed because of https://github.com/protocolbuffers/protobuf/issues/7778.
+grpc_proto_gen:
+	(cd src/killSwitch && \
+		protoc -I=. --js_out=import_style=commonjs_strict:. api_proto/*.proto && \
+		protoc -I. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. api_proto/*.proto && \
+		(cd api_proto && \
+			sed -i -E "s/require\('google-protobuf\//require('..\/..\/third_party\/google-protobuf-commonjs_strict\//" *_pb.js ))
+
 node_deps:
 	npm ci --no-save
 
diff --git a/package-lock.json b/package-lock.json
index 21767d8..82db829 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,8 +9,12 @@
       "version": "0.0.0",
       "license": "MIT",
       "dependencies": {
+        "google-protobuf": "^3.18.0-rc.2",
+        "grpc-web": "^1.2.1",
         "idb": "^6.1.2",
-        "poll-until-promise": "^3.6.1"
+        "poll-until-promise": "^3.6.1",
+        "semver": "^7.3.5",
+        "sw-xhr": "^0.0.3"
       },
       "devDependencies": {
         "copy-webpack-plugin": "^9.0.1",
@@ -737,12 +741,22 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/google-protobuf": {
+      "version": "3.18.0-rc.2",
+      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.18.0-rc.2.tgz",
+      "integrity": "sha512-mKZG5WYrwR/y1mA8xB+qI1O/6Pmvu4V6zldf+dpHdx6zoyVWT5lJTyXU8rAlpL7jtbe47e6M9L4PyWnKsYMOXQ=="
+    },
     "node_modules/graceful-fs": {
       "version": "4.2.6",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
       "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
       "dev": true
     },
+    "node_modules/grpc-web": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/grpc-web/-/grpc-web-1.2.1.tgz",
+      "integrity": "sha512-ibBaJPzfMVuLPgaST9w0kZl60s+SnkPBQp6QKdpEr85tpc1gXW2QDqSne9xiyiym0logDfdUSm4aX5h9YBA2mw=="
+    },
     "node_modules/has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -967,6 +981,17 @@
         "node": ">=8"
       }
     },
+    "node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -1366,6 +1391,20 @@
         "url": "https://opencollective.com/webpack"
       }
     },
+    "node_modules/semver": {
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/serialize-javascript": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
@@ -1472,6 +1511,11 @@
         "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
+    "node_modules/sw-xhr": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/sw-xhr/-/sw-xhr-0.0.3.tgz",
+      "integrity": "sha1-S+YUuwnEQhNfecxXhWKsm+wYE6Q="
+    },
     "node_modules/tapable": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
@@ -1735,6 +1779,11 @@
       "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
       "dev": true
     },
+    "node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    },
     "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@@ -2330,12 +2379,22 @@
         "slash": "^3.0.0"
       }
     },
+    "google-protobuf": {
+      "version": "3.18.0-rc.2",
+      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.18.0-rc.2.tgz",
+      "integrity": "sha512-mKZG5WYrwR/y1mA8xB+qI1O/6Pmvu4V6zldf+dpHdx6zoyVWT5lJTyXU8rAlpL7jtbe47e6M9L4PyWnKsYMOXQ=="
+    },
     "graceful-fs": {
       "version": "4.2.6",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
       "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
       "dev": true
     },
+    "grpc-web": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/grpc-web/-/grpc-web-1.2.1.tgz",
+      "integrity": "sha512-ibBaJPzfMVuLPgaST9w0kZl60s+SnkPBQp6QKdpEr85tpc1gXW2QDqSne9xiyiym0logDfdUSm4aX5h9YBA2mw=="
+    },
     "has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -2500,6 +2559,14 @@
         "p-locate": "^4.1.0"
       }
     },
+    "lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "requires": {
+        "yallist": "^4.0.0"
+      }
+    },
     "merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -2767,6 +2834,14 @@
         "ajv-keywords": "^3.5.2"
       }
     },
+    "semver": {
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "requires": {
+        "lru-cache": "^6.0.0"
+      }
+    },
     "serialize-javascript": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
@@ -2849,6 +2924,11 @@
         "has-flag": "^4.0.0"
       }
     },
+    "sw-xhr": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/sw-xhr/-/sw-xhr-0.0.3.tgz",
+      "integrity": "sha1-S+YUuwnEQhNfecxXhWKsm+wYE6Q="
+    },
     "tapable": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
@@ -3033,6 +3113,11 @@
       "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
       "dev": true
     },
+    "yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    },
     "yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 33e929e..bd3086e 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,11 @@
   },
   "private": true,
   "dependencies": {
+    "google-protobuf": "^3.18.0-rc.2",
+    "grpc-web": "^1.2.1",
     "idb": "^6.1.2",
-    "poll-until-promise": "^3.6.1"
+    "poll-until-promise": "^3.6.1",
+    "semver": "^7.3.5",
+    "sw-xhr": "^0.0.3"
   }
 }
diff --git a/src/background.js b/src/background.js
index 15f62b9..a2bb071 100644
--- a/src/background.js
+++ b/src/background.js
@@ -1,15 +1,35 @@
 // IMPORTANT: keep this file in sync with sw.js
-import {cleanUpOptions} from './common/optionsUtils.js'
-
-// When the extension gets updated, set new options to their default value.
-chrome.runtime.onInstalled.addListener(function(details) {
-  if (details.reason == 'install' || details.reason == 'update') {
-    chrome.storage.sync.get(null, function(options) {
-      cleanUpOptions(options, false);
-    });
-  }
-});
+import {cleanUpOptions} from './common/optionsUtils.js';
+import KillSwitchMechanism from './killSwitch/index.js';
 
 chrome.browserAction.onClicked.addListener(function() {
   chrome.runtime.openOptionsPage();
 });
+
+const killSwitchMechanism = new KillSwitchMechanism();
+
+chrome.alarms.create('updateKillSwitchStatus', {
+  periodInMinutes: PRODUCTION ? 30 : 1,
+});
+
+chrome.alarms.onAlarm.addListener(alarm => {
+  if (alarm.name === 'updateKillSwitchStatus')
+    killSwitchMechanism.updateKillSwitchStatus();
+});
+
+// When the profile is first started, update the kill switch status.
+chrome.runtime.onStartup.addListener(() => {
+  killSwitchMechanism.updateKillSwitchStatus();
+});
+
+// When the extension is first installed or gets updated, set new options to
+// their default value and update the kill switch status.
+chrome.runtime.onInstalled.addListener(details => {
+  if (details.reason == 'install' || details.reason == 'update') {
+    chrome.storage.sync.get(null, options => {
+      cleanUpOptions(options, false);
+    });
+
+    killSwitchMechanism.updateKillSwitchStatus();
+  }
+});
diff --git a/src/common/optionsUtils.js b/src/common/optionsUtils.js
index 16294ab..bfcb92c 100644
--- a/src/common/optionsUtils.js
+++ b/src/common/optionsUtils.js
@@ -6,7 +6,7 @@
 // Adds missing options with their default value. If |dryRun| is set to false,
 // they are also saved to the sync storage area.
 export function cleanUpOptions(options, dryRun = false) {
-  console.log('[cleanUpOptions] Previous options', JSON.stringify(options));
+  console.debug('[cleanUpOptions] Previous options', JSON.stringify(options));
 
   if (typeof options !== 'object' || options === null) options = {};
 
@@ -18,7 +18,7 @@
     }
   }
 
-  console.log('[cleanUpOptions] New options', JSON.stringify(options));
+  console.debug('[cleanUpOptions] New options', JSON.stringify(options));
 
   if (!ok && !dryRun) {
     chrome.storage.sync.set(options);
@@ -31,12 +31,29 @@
 // stored in the sync storage area.
 export function getOptions(options) {
   // Once we only target MV3, this can be greatly simplified.
-  return new Promise(
-      (resolve, reject) => {chrome.storage.sync.get(options, items => {
-        if (chrome.runtime.lastError) return reject(chrome.runtime.lastError);
+  return new Promise((resolve, reject) => {
+    if (typeof options === 'string')
+      options = [options, '_forceDisabledFeatures'];
+    else if (typeof options === 'array')
+      options = [...options, '_forceDisabledFeatures'];
+    else if (options !== null)
+      console.error('Unexpected |options| parameter (expected: string, array, or null).');
 
-        resolve(items);
-      })});
+    chrome.storage.sync.get(options, items => {
+      if (chrome.runtime.lastError) return reject(chrome.runtime.lastError);
+
+      // Handle applicable kill switches which force disable features
+      if (items?._forceDisabledFeatures) {
+        for (let feature of items?._forceDisabledFeatures) {
+          items[feature] = false;
+        }
+
+        delete items._forceDisabledFeatures;
+      }
+
+      resolve(items);
+    });
+  });
 }
 
 // Returns a promise which returns whether the |option| option/feature is
diff --git a/src/killSwitch/README.md b/src/killSwitch/README.md
new file mode 100644
index 0000000..40eb335
--- /dev/null
+++ b/src/killSwitch/README.md
@@ -0,0 +1,23 @@
+# Kill Switch
+The "Kill Switch" is a system which allows the extension maintainer and some
+authorized people to remotely disable a specific feature which is misbehaving
+to everyone.
+
+This folder contains the code that the extension uses to interact with the Kill
+Swtich server to determine whether a feature should be disabled or not.
+
+## Explanation
+The kill switch mechanism works as follows:
+
+1. There's a dashboard available at https://twpt-dashboard.avm99963.com/. There,
+some authorized users can set some features to be disabled for everyone,
+according to some criteria (it might be specified that only some versions of the
+extension or some browsers are affected by this).
+1. When a feature is set from the dashboard as force disabled (what we call
+"enable a kill switch"), an entry is added to the server's database.
+1. Every 30 minutes, the extension queries the server behind the dashboard, to
+retrieve a list of force disabled features from the database.
+1. The extension processes this list, and if any of the features in the list
+apply to the extension according to the linked criteria, it force disables
+those. If, on the contrary, a feature which was force disabled is no longer
+force disabled, the previous status is restored.
diff --git a/src/killSwitch/api_proto/README.md b/src/killSwitch/api_proto/README.md
new file mode 100644
index 0000000..ea2416e
--- /dev/null
+++ b/src/killSwitch/api_proto/README.md
@@ -0,0 +1,4 @@
+`*.proto` files have been retrieved from
+https://gerrit.avm99963.com/plugins/gitiles/gomodules/twpt-server/+/63f9486f7b00b35b05115a730648164864aa37cc/api\_proto/kill\_switch.proto.
+
+To generate the Javascript code, run `make grpc_proto_gen` in the project root.
diff --git a/src/killSwitch/api_proto/common.proto b/src/killSwitch/api_proto/common.proto
new file mode 100644
index 0000000..fd5867e
--- /dev/null
+++ b/src/killSwitch/api_proto/common.proto
@@ -0,0 +1,21 @@
+syntax = "proto3";
+
+option go_package = "gomodules.avm99963.com/twpt-server/api_proto";
+
+message Environment {
+  enum Browser {
+    BROWSER_UNKNOWN = 0;
+    BROWSER_CHROMIUM = 1;
+    BROWSER_GECKO = 2;
+  }
+
+  enum VersionChannel {
+    CHANNEL_UNKNOWN = 0;
+    CHANNEL_STABLE = 1;
+    CHANNEL_BETA = 2;
+  }
+
+  Browser browser = 1;
+  string version = 2;
+  VersionChannel version_channel = 3;
+}
diff --git a/src/killSwitch/api_proto/common_pb.js b/src/killSwitch/api_proto/common_pb.js
new file mode 100644
index 0000000..d9150b2
--- /dev/null
+++ b/src/killSwitch/api_proto/common_pb.js
@@ -0,0 +1,250 @@
+// source: api_proto/common.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('Environment', null, proto);
+goog.exportSymbol('Environment.Browser', null, proto);
+goog.exportSymbol('Environment.VersionChannel', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.Environment = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.Environment, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.Environment.displayName = 'proto.Environment';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.Environment.prototype.toObject = function(opt_includeInstance) {
+  return proto.Environment.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.Environment} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Environment.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    browser: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    version: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    versionChannel: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.Environment}
+ */
+proto.Environment.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.Environment;
+  return proto.Environment.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.Environment} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.Environment}
+ */
+proto.Environment.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.Environment.Browser} */ (reader.readEnum());
+      msg.setBrowser(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setVersion(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.Environment.VersionChannel} */ (reader.readEnum());
+      msg.setVersionChannel(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.Environment.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.Environment.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.Environment} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Environment.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getBrowser();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getVersionChannel();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.Environment.Browser = {
+  BROWSER_UNKNOWN: 0,
+  BROWSER_CHROMIUM: 1,
+  BROWSER_GECKO: 2
+};
+
+/**
+ * @enum {number}
+ */
+proto.Environment.VersionChannel = {
+  CHANNEL_UNKNOWN: 0,
+  CHANNEL_STABLE: 1,
+  CHANNEL_BETA: 2
+};
+
+/**
+ * optional Browser browser = 1;
+ * @return {!proto.Environment.Browser}
+ */
+proto.Environment.prototype.getBrowser = function() {
+  return /** @type {!proto.Environment.Browser} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.Environment.Browser} value
+ * @return {!proto.Environment} returns this
+ */
+proto.Environment.prototype.setBrowser = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional string version = 2;
+ * @return {string}
+ */
+proto.Environment.prototype.getVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.Environment} returns this
+ */
+proto.Environment.prototype.setVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional VersionChannel version_channel = 3;
+ * @return {!proto.Environment.VersionChannel}
+ */
+proto.Environment.prototype.getVersionChannel = function() {
+  return /** @type {!proto.Environment.VersionChannel} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.Environment.VersionChannel} value
+ * @return {!proto.Environment} returns this
+ */
+proto.Environment.prototype.setVersionChannel = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/killSwitch/api_proto/kill_switch.proto b/src/killSwitch/api_proto/kill_switch.proto
new file mode 100644
index 0000000..b3ffb70
--- /dev/null
+++ b/src/killSwitch/api_proto/kill_switch.proto
@@ -0,0 +1,94 @@
+syntax = "proto3";
+
+import "api_proto/common.proto";
+import "api_proto/kill_switch_objects.proto";
+
+option go_package = "gomodules.avm99963.com/twpt-server/api_proto";
+
+service KillSwitchService {
+  rpc GetKillSwitchStatus (GetKillSwitchStatusRequest) returns (GetKillSwitchStatusResponse) {}
+  rpc GetKillSwitchOverview (GetKillSwitchOverviewRequest) returns (GetKillSwitchOverviewResponse) {}
+  rpc ListFeatures (ListFeaturesRequest) returns (ListFeaturesResponse) {}
+  rpc SyncFeatures (SyncFeaturesRequest) returns (SyncFeaturesResponse) {}
+  rpc EnableKillSwitch (EnableKillSwitchRequest) returns (EnableKillSwitchResponse) {}
+  rpc DisableKillSwitch (DisableKillSwitchRequest) returns (DisableKillSwitchResponse) {}
+  rpc ListAuthorizedUsers (ListAuthorizedUsersRequest) returns (ListAuthorizedUsersResponse) {}
+  rpc AddAuthorizedUser (AddAuthorizedUserRequest) returns (AddAuthorizedUserResponse) {}
+  rpc UpdateAuthorizedUser (UpdateAuthorizedUserRequest) returns (UpdateAuthorizedUserResponse) {}
+  rpc DeleteAuthorizedUser (DeleteAuthorizedUserRequest) returns (DeleteAuthorizedUserResponse) {}
+}
+
+// Retrieve kill switch status depending on the environment.
+message GetKillSwitchStatusRequest {
+  Environment environment = 1;
+}
+
+message GetKillSwitchStatusResponse {
+  repeated KillSwitch kill_switches = 1;
+}
+
+message GetKillSwitchOverviewRequest {
+  bool with_nonactive_kill_switches = 1;
+}
+
+message GetKillSwitchOverviewResponse {
+  repeated KillSwitch kill_switches = 1;
+}
+
+message ListFeaturesRequest {
+  bool with_deprecated_features = 1;
+}
+
+message ListFeaturesResponse {
+  repeated Feature features = 1;
+}
+
+message SyncFeaturesRequest {
+  repeated Feature features = 1;
+}
+
+message SyncFeaturesResponse {
+}
+
+message EnableKillSwitchRequest {
+  KillSwitch kill_switch = 1;
+}
+
+message EnableKillSwitchResponse {
+}
+
+message DisableKillSwitchRequest {
+  int32 kill_switch_id = 1;
+}
+
+message DisableKillSwitchResponse {
+}
+
+message ListAuthorizedUsersRequest {
+}
+
+message ListAuthorizedUsersResponse {
+  repeated KillSwitchAuthorizedUser users = 1;
+}
+
+message AddAuthorizedUserRequest {
+  KillSwitchAuthorizedUser user = 1;
+}
+
+message AddAuthorizedUserResponse {
+}
+
+message UpdateAuthorizedUserRequest {
+  int32 user_id = 1;
+  KillSwitchAuthorizedUser user = 2;
+}
+
+message UpdateAuthorizedUserResponse {
+}
+
+message DeleteAuthorizedUserRequest {
+  int32 user_id = 1;
+}
+
+message DeleteAuthorizedUserResponse {
+}
diff --git a/src/killSwitch/api_proto/kill_switch_grpc_web_pb.js b/src/killSwitch/api_proto/kill_switch_grpc_web_pb.js
new file mode 100644
index 0000000..0c5f28a
--- /dev/null
+++ b/src/killSwitch/api_proto/kill_switch_grpc_web_pb.js
@@ -0,0 +1,877 @@
+/**
+ * @fileoverview gRPC-Web generated client stub for 
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+var api_proto_common_pb = require('../api_proto/common_pb.js')
+
+var api_proto_kill_switch_objects_pb = require('../api_proto/kill_switch_objects_pb.js')
+const proto = require('./kill_switch_pb.js');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.KillSwitchServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.KillSwitchServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.GetKillSwitchStatusRequest,
+ *   !proto.GetKillSwitchStatusResponse>}
+ */
+const methodDescriptor_KillSwitchService_GetKillSwitchStatus = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/GetKillSwitchStatus',
+  grpc.web.MethodType.UNARY,
+  proto.GetKillSwitchStatusRequest,
+  proto.GetKillSwitchStatusResponse,
+  /**
+   * @param {!proto.GetKillSwitchStatusRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchStatusResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.GetKillSwitchStatusRequest,
+ *   !proto.GetKillSwitchStatusResponse>}
+ */
+const methodInfo_KillSwitchService_GetKillSwitchStatus = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.GetKillSwitchStatusResponse,
+  /**
+   * @param {!proto.GetKillSwitchStatusRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchStatusResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.GetKillSwitchStatusRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.GetKillSwitchStatusResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.GetKillSwitchStatusResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.getKillSwitchStatus =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchStatus',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchStatus,
+      callback);
+};
+
+
+/**
+ * @param {!proto.GetKillSwitchStatusRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.GetKillSwitchStatusResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.getKillSwitchStatus =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchStatus',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchStatus);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.GetKillSwitchOverviewRequest,
+ *   !proto.GetKillSwitchOverviewResponse>}
+ */
+const methodDescriptor_KillSwitchService_GetKillSwitchOverview = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/GetKillSwitchOverview',
+  grpc.web.MethodType.UNARY,
+  proto.GetKillSwitchOverviewRequest,
+  proto.GetKillSwitchOverviewResponse,
+  /**
+   * @param {!proto.GetKillSwitchOverviewRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchOverviewResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.GetKillSwitchOverviewRequest,
+ *   !proto.GetKillSwitchOverviewResponse>}
+ */
+const methodInfo_KillSwitchService_GetKillSwitchOverview = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.GetKillSwitchOverviewResponse,
+  /**
+   * @param {!proto.GetKillSwitchOverviewRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchOverviewResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.GetKillSwitchOverviewRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.GetKillSwitchOverviewResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.GetKillSwitchOverviewResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.getKillSwitchOverview =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchOverview',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchOverview,
+      callback);
+};
+
+
+/**
+ * @param {!proto.GetKillSwitchOverviewRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.GetKillSwitchOverviewResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.getKillSwitchOverview =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchOverview',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchOverview);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.ListFeaturesRequest,
+ *   !proto.ListFeaturesResponse>}
+ */
+const methodDescriptor_KillSwitchService_ListFeatures = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/ListFeatures',
+  grpc.web.MethodType.UNARY,
+  proto.ListFeaturesRequest,
+  proto.ListFeaturesResponse,
+  /**
+   * @param {!proto.ListFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.ListFeaturesRequest,
+ *   !proto.ListFeaturesResponse>}
+ */
+const methodInfo_KillSwitchService_ListFeatures = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.ListFeaturesResponse,
+  /**
+   * @param {!proto.ListFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.ListFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.ListFeaturesResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.ListFeaturesResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.listFeatures =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/ListFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListFeatures,
+      callback);
+};
+
+
+/**
+ * @param {!proto.ListFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.ListFeaturesResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.listFeatures =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/ListFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListFeatures);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.SyncFeaturesRequest,
+ *   !proto.SyncFeaturesResponse>}
+ */
+const methodDescriptor_KillSwitchService_SyncFeatures = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/SyncFeatures',
+  grpc.web.MethodType.UNARY,
+  proto.SyncFeaturesRequest,
+  proto.SyncFeaturesResponse,
+  /**
+   * @param {!proto.SyncFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.SyncFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.SyncFeaturesRequest,
+ *   !proto.SyncFeaturesResponse>}
+ */
+const methodInfo_KillSwitchService_SyncFeatures = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.SyncFeaturesResponse,
+  /**
+   * @param {!proto.SyncFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.SyncFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.SyncFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.SyncFeaturesResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.SyncFeaturesResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.syncFeatures =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/SyncFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_SyncFeatures,
+      callback);
+};
+
+
+/**
+ * @param {!proto.SyncFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.SyncFeaturesResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.syncFeatures =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/SyncFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_SyncFeatures);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.EnableKillSwitchRequest,
+ *   !proto.EnableKillSwitchResponse>}
+ */
+const methodDescriptor_KillSwitchService_EnableKillSwitch = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/EnableKillSwitch',
+  grpc.web.MethodType.UNARY,
+  proto.EnableKillSwitchRequest,
+  proto.EnableKillSwitchResponse,
+  /**
+   * @param {!proto.EnableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.EnableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.EnableKillSwitchRequest,
+ *   !proto.EnableKillSwitchResponse>}
+ */
+const methodInfo_KillSwitchService_EnableKillSwitch = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.EnableKillSwitchResponse,
+  /**
+   * @param {!proto.EnableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.EnableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.EnableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.EnableKillSwitchResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.EnableKillSwitchResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.enableKillSwitch =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/EnableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_EnableKillSwitch,
+      callback);
+};
+
+
+/**
+ * @param {!proto.EnableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.EnableKillSwitchResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.enableKillSwitch =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/EnableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_EnableKillSwitch);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.DisableKillSwitchRequest,
+ *   !proto.DisableKillSwitchResponse>}
+ */
+const methodDescriptor_KillSwitchService_DisableKillSwitch = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/DisableKillSwitch',
+  grpc.web.MethodType.UNARY,
+  proto.DisableKillSwitchRequest,
+  proto.DisableKillSwitchResponse,
+  /**
+   * @param {!proto.DisableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DisableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.DisableKillSwitchRequest,
+ *   !proto.DisableKillSwitchResponse>}
+ */
+const methodInfo_KillSwitchService_DisableKillSwitch = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.DisableKillSwitchResponse,
+  /**
+   * @param {!proto.DisableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DisableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.DisableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.DisableKillSwitchResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.DisableKillSwitchResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.disableKillSwitch =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/DisableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DisableKillSwitch,
+      callback);
+};
+
+
+/**
+ * @param {!proto.DisableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.DisableKillSwitchResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.disableKillSwitch =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/DisableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DisableKillSwitch);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.ListAuthorizedUsersRequest,
+ *   !proto.ListAuthorizedUsersResponse>}
+ */
+const methodDescriptor_KillSwitchService_ListAuthorizedUsers = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/ListAuthorizedUsers',
+  grpc.web.MethodType.UNARY,
+  proto.ListAuthorizedUsersRequest,
+  proto.ListAuthorizedUsersResponse,
+  /**
+   * @param {!proto.ListAuthorizedUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListAuthorizedUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.ListAuthorizedUsersRequest,
+ *   !proto.ListAuthorizedUsersResponse>}
+ */
+const methodInfo_KillSwitchService_ListAuthorizedUsers = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.ListAuthorizedUsersResponse,
+  /**
+   * @param {!proto.ListAuthorizedUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListAuthorizedUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.ListAuthorizedUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.ListAuthorizedUsersResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.ListAuthorizedUsersResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.listAuthorizedUsers =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/ListAuthorizedUsers',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListAuthorizedUsers,
+      callback);
+};
+
+
+/**
+ * @param {!proto.ListAuthorizedUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.ListAuthorizedUsersResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.listAuthorizedUsers =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/ListAuthorizedUsers',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListAuthorizedUsers);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.AddAuthorizedUserRequest,
+ *   !proto.AddAuthorizedUserResponse>}
+ */
+const methodDescriptor_KillSwitchService_AddAuthorizedUser = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/AddAuthorizedUser',
+  grpc.web.MethodType.UNARY,
+  proto.AddAuthorizedUserRequest,
+  proto.AddAuthorizedUserResponse,
+  /**
+   * @param {!proto.AddAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.AddAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.AddAuthorizedUserRequest,
+ *   !proto.AddAuthorizedUserResponse>}
+ */
+const methodInfo_KillSwitchService_AddAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.AddAuthorizedUserResponse,
+  /**
+   * @param {!proto.AddAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.AddAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.AddAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.AddAuthorizedUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.AddAuthorizedUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.addAuthorizedUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/AddAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_AddAuthorizedUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.AddAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.AddAuthorizedUserResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.addAuthorizedUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/AddAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_AddAuthorizedUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.UpdateAuthorizedUserRequest,
+ *   !proto.UpdateAuthorizedUserResponse>}
+ */
+const methodDescriptor_KillSwitchService_UpdateAuthorizedUser = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/UpdateAuthorizedUser',
+  grpc.web.MethodType.UNARY,
+  proto.UpdateAuthorizedUserRequest,
+  proto.UpdateAuthorizedUserResponse,
+  /**
+   * @param {!proto.UpdateAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.UpdateAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.UpdateAuthorizedUserRequest,
+ *   !proto.UpdateAuthorizedUserResponse>}
+ */
+const methodInfo_KillSwitchService_UpdateAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.UpdateAuthorizedUserResponse,
+  /**
+   * @param {!proto.UpdateAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.UpdateAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.UpdateAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.UpdateAuthorizedUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.UpdateAuthorizedUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.updateAuthorizedUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/UpdateAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_UpdateAuthorizedUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.UpdateAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.UpdateAuthorizedUserResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.updateAuthorizedUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/UpdateAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_UpdateAuthorizedUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.DeleteAuthorizedUserRequest,
+ *   !proto.DeleteAuthorizedUserResponse>}
+ */
+const methodDescriptor_KillSwitchService_DeleteAuthorizedUser = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/DeleteAuthorizedUser',
+  grpc.web.MethodType.UNARY,
+  proto.DeleteAuthorizedUserRequest,
+  proto.DeleteAuthorizedUserResponse,
+  /**
+   * @param {!proto.DeleteAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DeleteAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.DeleteAuthorizedUserRequest,
+ *   !proto.DeleteAuthorizedUserResponse>}
+ */
+const methodInfo_KillSwitchService_DeleteAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.DeleteAuthorizedUserResponse,
+  /**
+   * @param {!proto.DeleteAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DeleteAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.DeleteAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.DeleteAuthorizedUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.DeleteAuthorizedUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.deleteAuthorizedUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/DeleteAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DeleteAuthorizedUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.DeleteAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.DeleteAuthorizedUserResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.deleteAuthorizedUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/DeleteAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DeleteAuthorizedUser);
+};
+
+
+module.exports = proto;
+
diff --git a/src/killSwitch/api_proto/kill_switch_objects.proto b/src/killSwitch/api_proto/kill_switch_objects.proto
new file mode 100644
index 0000000..041291f
--- /dev/null
+++ b/src/killSwitch/api_proto/kill_switch_objects.proto
@@ -0,0 +1,87 @@
+syntax = "proto3";
+
+import "api_proto/common.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "gomodules.avm99963.com/twpt-server/api_proto";
+
+message Feature {
+  int32 id = 1;
+  string codename = 2;
+  enum Type {
+    TYPE_UNKNOWN = 0;
+    TYPE_EXPERIMENT = 1;
+    TYPE_OPTION = 2;
+    TYPE_DEPRECATED = 10;
+  }
+  Type type = 3;
+}
+
+message KillSwitch {
+  int32 id = 1;
+  Feature feature = 2;
+  string min_version = 3;
+  string max_version = 4;
+  repeated Environment.Browser browsers = 5;
+  bool active = 6;
+}
+
+message KillSwitchAuthorizedUser {
+  int32 id = 1;
+  string google_uid = 2;
+  string email = 3;
+  enum AccessLevel {
+    ACCESS_LEVEL_NONE = 0;
+    ACCESS_LEVEL_ACTIVATOR = 5; // The user may enable/disable kill switches.
+    ACCESS_LEVEL_ADMIN = 10; // The user may perform any action.
+  }
+  AccessLevel access_level = 4;
+}
+
+message KillSwitchTransformation {
+  KillSwitch old = 1;
+  KillSwitch new = 2;
+}
+
+message AuthorizedUserTransformation {
+  KillSwitchAuthorizedUser old = 1;
+  KillSwitchAuthorizedUser new = 2;
+}
+
+// Log entry which describes an action which has taken place.
+message KillSwitchAuditLogEntry {
+  // Timestamp in which the action was taken.
+  google.protobuf.Timestamp timestamp = 1;
+
+  // User who/which performed the action.
+  KillSwitchAuthorizedUser user = 2;
+
+  message KillSwitchEnabled {
+    KillSwitch kill_switch = 1;
+  }
+
+  message KillSwitchDisabled {
+    KillSwitchTransformation transformation = 1;
+  }
+
+  message AuthorizedUserAdded {
+    KillSwitchAuthorizedUser user = 1;
+  }
+
+  message AuthorizedUserUpdated {
+    AuthorizedUserTransformation transformation = 1;
+  }
+
+  message AuthorizedUserDeleted {
+    KillSwitchAuthorizedUser old_user = 1;
+  }
+
+  // Description of the action taken
+  oneof description {
+    KillSwitchEnabled kill_switch_enabled = 3;
+    KillSwitchDisabled kill_switch_disabled = 4;
+    AuthorizedUserAdded authorized_user_added = 5;
+    AuthorizedUserUpdated authorized_user_updated = 6;
+    AuthorizedUserDeleted authorized_user_deleted  = 7;
+  }
+}
diff --git a/src/killSwitch/api_proto/kill_switch_objects_pb.js b/src/killSwitch/api_proto/kill_switch_objects_pb.js
new file mode 100644
index 0000000..4b3d6e6
--- /dev/null
+++ b/src/killSwitch/api_proto/kill_switch_objects_pb.js
@@ -0,0 +1,2670 @@
+// source: api_proto/kill_switch_objects.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+var api_proto_common_pb = require('../api_proto/common_pb.js');
+goog.object.extend(proto, api_proto_common_pb);
+var google_protobuf_timestamp_pb = require('../../third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js');
+goog.object.extend(proto, google_protobuf_timestamp_pb);
+goog.exportSymbol('AuthorizedUserTransformation', null, proto);
+goog.exportSymbol('Feature', null, proto);
+goog.exportSymbol('Feature.Type', null, proto);
+goog.exportSymbol('KillSwitch', null, proto);
+goog.exportSymbol('KillSwitchAuditLogEntry', null, proto);
+goog.exportSymbol('KillSwitchAuditLogEntry.AuthorizedUserAdded', null, proto);
+goog.exportSymbol('KillSwitchAuditLogEntry.AuthorizedUserDeleted', null, proto);
+goog.exportSymbol('KillSwitchAuditLogEntry.AuthorizedUserUpdated', null, proto);
+goog.exportSymbol('KillSwitchAuditLogEntry.DescriptionCase', null, proto);
+goog.exportSymbol('KillSwitchAuditLogEntry.KillSwitchDisabled', null, proto);
+goog.exportSymbol('KillSwitchAuditLogEntry.KillSwitchEnabled', null, proto);
+goog.exportSymbol('KillSwitchAuthorizedUser', null, proto);
+goog.exportSymbol('KillSwitchAuthorizedUser.AccessLevel', null, proto);
+goog.exportSymbol('KillSwitchTransformation', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.Feature = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.Feature, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.Feature.displayName = 'proto.Feature';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitch = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.KillSwitch.repeatedFields_, null);
+};
+goog.inherits(proto.KillSwitch, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitch.displayName = 'proto.KillSwitch';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuthorizedUser = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuthorizedUser, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuthorizedUser.displayName = 'proto.KillSwitchAuthorizedUser';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchTransformation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchTransformation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchTransformation.displayName = 'proto.KillSwitchTransformation';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.AuthorizedUserTransformation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.AuthorizedUserTransformation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.AuthorizedUserTransformation.displayName = 'proto.AuthorizedUserTransformation';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.KillSwitchAuditLogEntry.oneofGroups_);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.displayName = 'proto.KillSwitchAuditLogEntry';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.KillSwitchEnabled, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.KillSwitchEnabled.displayName = 'proto.KillSwitchAuditLogEntry.KillSwitchEnabled';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.KillSwitchDisabled, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.KillSwitchDisabled.displayName = 'proto.KillSwitchAuditLogEntry.KillSwitchDisabled';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserAdded, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserAdded';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.Feature.prototype.toObject = function(opt_includeInstance) {
+  return proto.Feature.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.Feature} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Feature.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    codename: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    type: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.Feature}
+ */
+proto.Feature.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.Feature;
+  return proto.Feature.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.Feature} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.Feature}
+ */
+proto.Feature.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCodename(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.Feature.Type} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.Feature.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.Feature.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.Feature} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Feature.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getCodename();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.Feature.Type = {
+  TYPE_UNKNOWN: 0,
+  TYPE_EXPERIMENT: 1,
+  TYPE_OPTION: 2,
+  TYPE_DEPRECATED: 10
+};
+
+/**
+ * optional int32 id = 1;
+ * @return {number}
+ */
+proto.Feature.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.Feature} returns this
+ */
+proto.Feature.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string codename = 2;
+ * @return {string}
+ */
+proto.Feature.prototype.getCodename = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.Feature} returns this
+ */
+proto.Feature.prototype.setCodename = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional Type type = 3;
+ * @return {!proto.Feature.Type}
+ */
+proto.Feature.prototype.getType = function() {
+  return /** @type {!proto.Feature.Type} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.Feature.Type} value
+ * @return {!proto.Feature} returns this
+ */
+proto.Feature.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.KillSwitch.repeatedFields_ = [5];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitch.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitch.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitch} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitch.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    feature: (f = msg.getFeature()) && proto.Feature.toObject(includeInstance, f),
+    minVersion: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    maxVersion: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    browsersList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
+    active: jspb.Message.getBooleanFieldWithDefault(msg, 6, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitch}
+ */
+proto.KillSwitch.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitch;
+  return proto.KillSwitch.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitch} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitch}
+ */
+proto.KillSwitch.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = new proto.Feature;
+      reader.readMessage(value,proto.Feature.deserializeBinaryFromReader);
+      msg.setFeature(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMinVersion(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMaxVersion(value);
+      break;
+    case 5:
+      var values = /** @type {!Array<!proto.Environment.Browser>} */ (reader.isDelimited() ? reader.readPackedEnum() : [reader.readEnum()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addBrowsers(values[i]);
+      }
+      break;
+    case 6:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setActive(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitch.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitch.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitch} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitch.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getFeature();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.Feature.serializeBinaryToWriter
+    );
+  }
+  f = message.getMinVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getMaxVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getBrowsersList();
+  if (f.length > 0) {
+    writer.writePackedEnum(
+      5,
+      f
+    );
+  }
+  f = message.getActive();
+  if (f) {
+    writer.writeBool(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 id = 1;
+ * @return {number}
+ */
+proto.KillSwitch.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional Feature feature = 2;
+ * @return {?proto.Feature}
+ */
+proto.KillSwitch.prototype.getFeature = function() {
+  return /** @type{?proto.Feature} */ (
+    jspb.Message.getWrapperField(this, proto.Feature, 2));
+};
+
+
+/**
+ * @param {?proto.Feature|undefined} value
+ * @return {!proto.KillSwitch} returns this
+*/
+proto.KillSwitch.prototype.setFeature = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.clearFeature = function() {
+  return this.setFeature(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitch.prototype.hasFeature = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string min_version = 3;
+ * @return {string}
+ */
+proto.KillSwitch.prototype.getMinVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setMinVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string max_version = 4;
+ * @return {string}
+ */
+proto.KillSwitch.prototype.getMaxVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setMaxVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * repeated Environment.Browser browsers = 5;
+ * @return {!Array<!proto.Environment.Browser>}
+ */
+proto.KillSwitch.prototype.getBrowsersList = function() {
+  return /** @type {!Array<!proto.Environment.Browser>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<!proto.Environment.Browser>} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setBrowsersList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {!proto.Environment.Browser} value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.addBrowsers = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.clearBrowsersList = function() {
+  return this.setBrowsersList([]);
+};
+
+
+/**
+ * optional bool active = 6;
+ * @return {boolean}
+ */
+proto.KillSwitch.prototype.getActive = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setActive = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuthorizedUser.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuthorizedUser.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuthorizedUser} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuthorizedUser.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    googleUid: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    email: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    accessLevel: jspb.Message.getFieldWithDefault(msg, 4, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuthorizedUser.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuthorizedUser;
+  return proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuthorizedUser} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGoogleUid(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmail(value);
+      break;
+    case 4:
+      var value = /** @type {!proto.KillSwitchAuthorizedUser.AccessLevel} */ (reader.readEnum());
+      msg.setAccessLevel(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuthorizedUser.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuthorizedUser.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuthorizedUser} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuthorizedUser.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getGoogleUid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getAccessLevel();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.KillSwitchAuthorizedUser.AccessLevel = {
+  ACCESS_LEVEL_NONE: 0,
+  ACCESS_LEVEL_ACTIVATOR: 5,
+  ACCESS_LEVEL_ADMIN: 10
+};
+
+/**
+ * optional int32 id = 1;
+ * @return {number}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string google_uid = 2;
+ * @return {string}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getGoogleUid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setGoogleUid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string email = 3;
+ * @return {string}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional AccessLevel access_level = 4;
+ * @return {!proto.KillSwitchAuthorizedUser.AccessLevel}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getAccessLevel = function() {
+  return /** @type {!proto.KillSwitchAuthorizedUser.AccessLevel} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {!proto.KillSwitchAuthorizedUser.AccessLevel} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setAccessLevel = function(value) {
+  return jspb.Message.setProto3EnumField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchTransformation.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchTransformation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchTransformation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchTransformation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    old: (f = msg.getOld()) && proto.KillSwitch.toObject(includeInstance, f),
+    pb_new: (f = msg.getNew()) && proto.KillSwitch.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchTransformation}
+ */
+proto.KillSwitchTransformation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchTransformation;
+  return proto.KillSwitchTransformation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchTransformation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchTransformation}
+ */
+proto.KillSwitchTransformation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitch;
+      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
+      msg.setOld(value);
+      break;
+    case 2:
+      var value = new proto.KillSwitch;
+      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
+      msg.setNew(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchTransformation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchTransformation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchTransformation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchTransformation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOld();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitch.serializeBinaryToWriter
+    );
+  }
+  f = message.getNew();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitch old = 1;
+ * @return {?proto.KillSwitch}
+ */
+proto.KillSwitchTransformation.prototype.getOld = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitch, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.KillSwitchTransformation} returns this
+*/
+proto.KillSwitchTransformation.prototype.setOld = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchTransformation} returns this
+ */
+proto.KillSwitchTransformation.prototype.clearOld = function() {
+  return this.setOld(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchTransformation.prototype.hasOld = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional KillSwitch new = 2;
+ * @return {?proto.KillSwitch}
+ */
+proto.KillSwitchTransformation.prototype.getNew = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitch, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.KillSwitchTransformation} returns this
+*/
+proto.KillSwitchTransformation.prototype.setNew = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchTransformation} returns this
+ */
+proto.KillSwitchTransformation.prototype.clearNew = function() {
+  return this.setNew(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchTransformation.prototype.hasNew = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.AuthorizedUserTransformation.prototype.toObject = function(opt_includeInstance) {
+  return proto.AuthorizedUserTransformation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.AuthorizedUserTransformation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AuthorizedUserTransformation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    old: (f = msg.getOld()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f),
+    pb_new: (f = msg.getNew()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.AuthorizedUserTransformation}
+ */
+proto.AuthorizedUserTransformation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.AuthorizedUserTransformation;
+  return proto.AuthorizedUserTransformation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.AuthorizedUserTransformation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.AuthorizedUserTransformation}
+ */
+proto.AuthorizedUserTransformation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setOld(value);
+      break;
+    case 2:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setNew(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.AuthorizedUserTransformation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.AuthorizedUserTransformation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.AuthorizedUserTransformation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AuthorizedUserTransformation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOld();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+  f = message.getNew();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser old = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.AuthorizedUserTransformation.prototype.getOld = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.AuthorizedUserTransformation} returns this
+*/
+proto.AuthorizedUserTransformation.prototype.setOld = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.AuthorizedUserTransformation} returns this
+ */
+proto.AuthorizedUserTransformation.prototype.clearOld = function() {
+  return this.setOld(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.AuthorizedUserTransformation.prototype.hasOld = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser new = 2;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.AuthorizedUserTransformation.prototype.getNew = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.AuthorizedUserTransformation} returns this
+*/
+proto.AuthorizedUserTransformation.prototype.setNew = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.AuthorizedUserTransformation} returns this
+ */
+proto.AuthorizedUserTransformation.prototype.clearNew = function() {
+  return this.setNew(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.AuthorizedUserTransformation.prototype.hasNew = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
+ * @const
+ */
+proto.KillSwitchAuditLogEntry.oneofGroups_ = [[3,4,5,6,7]];
+
+/**
+ * @enum {number}
+ */
+proto.KillSwitchAuditLogEntry.DescriptionCase = {
+  DESCRIPTION_NOT_SET: 0,
+  KILL_SWITCH_ENABLED: 3,
+  KILL_SWITCH_DISABLED: 4,
+  AUTHORIZED_USER_ADDED: 5,
+  AUTHORIZED_USER_UPDATED: 6,
+  AUTHORIZED_USER_DELETED: 7
+};
+
+/**
+ * @return {proto.KillSwitchAuditLogEntry.DescriptionCase}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getDescriptionCase = function() {
+  return /** @type {proto.KillSwitchAuditLogEntry.DescriptionCase} */(jspb.Message.computeOneofCase(this, proto.KillSwitchAuditLogEntry.oneofGroups_[0]));
+};
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    timestamp: (f = msg.getTimestamp()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f),
+    user: (f = msg.getUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f),
+    killSwitchEnabled: (f = msg.getKillSwitchEnabled()) && proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject(includeInstance, f),
+    killSwitchDisabled: (f = msg.getKillSwitchDisabled()) && proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject(includeInstance, f),
+    authorizedUserAdded: (f = msg.getAuthorizedUserAdded()) && proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject(includeInstance, f),
+    authorizedUserUpdated: (f = msg.getAuthorizedUserUpdated()) && proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject(includeInstance, f),
+    authorizedUserDeleted: (f = msg.getAuthorizedUserDeleted()) && proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry}
+ */
+proto.KillSwitchAuditLogEntry.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry;
+  return proto.KillSwitchAuditLogEntry.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry}
+ */
+proto.KillSwitchAuditLogEntry.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new google_protobuf_timestamp_pb.Timestamp;
+      reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader);
+      msg.setTimestamp(value);
+      break;
+    case 2:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    case 3:
+      var value = new proto.KillSwitchAuditLogEntry.KillSwitchEnabled;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader);
+      msg.setKillSwitchEnabled(value);
+      break;
+    case 4:
+      var value = new proto.KillSwitchAuditLogEntry.KillSwitchDisabled;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader);
+      msg.setKillSwitchDisabled(value);
+      break;
+    case 5:
+      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserAdded;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader);
+      msg.setAuthorizedUserAdded(value);
+      break;
+    case 6:
+      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader);
+      msg.setAuthorizedUserUpdated(value);
+      break;
+    case 7:
+      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader);
+      msg.setAuthorizedUserDeleted(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTimestamp();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter
+    );
+  }
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+  f = message.getKillSwitchEnabled();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter
+    );
+  }
+  f = message.getKillSwitchDisabled();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter
+    );
+  }
+  f = message.getAuthorizedUserAdded();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter
+    );
+  }
+  f = message.getAuthorizedUserUpdated();
+  if (f != null) {
+    writer.writeMessage(
+      6,
+      f,
+      proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter
+    );
+  }
+  f = message.getAuthorizedUserDeleted();
+  if (f != null) {
+    writer.writeMessage(
+      7,
+      f,
+      proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter
+    );
+  }
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitch: (f = msg.getKillSwitch()) && proto.KillSwitch.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.KillSwitchEnabled;
+  return proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitch;
+      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
+      msg.setKillSwitch(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitch();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitch kill_switch = 1;
+ * @return {?proto.KillSwitch}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.getKillSwitch = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitch, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} returns this
+*/
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.setKillSwitch = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} returns this
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.clearKillSwitch = function() {
+  return this.setKillSwitch(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.hasKillSwitch = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    transformation: (f = msg.getTransformation()) && proto.KillSwitchTransformation.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.KillSwitchDisabled;
+  return proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchTransformation;
+      reader.readMessage(value,proto.KillSwitchTransformation.deserializeBinaryFromReader);
+      msg.setTransformation(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTransformation();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchTransformation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchTransformation transformation = 1;
+ * @return {?proto.KillSwitchTransformation}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.getTransformation = function() {
+  return /** @type{?proto.KillSwitchTransformation} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchTransformation, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchTransformation|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} returns this
+*/
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.setTransformation = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} returns this
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.clearTransformation = function() {
+  return this.setTransformation(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.hasTransformation = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    user: (f = msg.getUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserAdded;
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} returns this
+*/
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} returns this
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    transformation: (f = msg.getTransformation()) && proto.AuthorizedUserTransformation.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated;
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.AuthorizedUserTransformation;
+      reader.readMessage(value,proto.AuthorizedUserTransformation.deserializeBinaryFromReader);
+      msg.setTransformation(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTransformation();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.AuthorizedUserTransformation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional AuthorizedUserTransformation transformation = 1;
+ * @return {?proto.AuthorizedUserTransformation}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.getTransformation = function() {
+  return /** @type{?proto.AuthorizedUserTransformation} */ (
+    jspb.Message.getWrapperField(this, proto.AuthorizedUserTransformation, 1));
+};
+
+
+/**
+ * @param {?proto.AuthorizedUserTransformation|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} returns this
+*/
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.setTransformation = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} returns this
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.clearTransformation = function() {
+  return this.setTransformation(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.hasTransformation = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    oldUser: (f = msg.getOldUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted;
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setOldUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOldUser();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser old_user = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.getOldUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} returns this
+*/
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.setOldUser = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} returns this
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.clearOldUser = function() {
+  return this.setOldUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.hasOldUser = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional google.protobuf.Timestamp timestamp = 1;
+ * @return {?proto.google.protobuf.Timestamp}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getTimestamp = function() {
+  return /** @type{?proto.google.protobuf.Timestamp} */ (
+    jspb.Message.getWrapperField(this, google_protobuf_timestamp_pb.Timestamp, 1));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.Timestamp|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setTimestamp = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearTimestamp = function() {
+  return this.setTimestamp(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasTimestamp = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 2;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional KillSwitchEnabled kill_switch_enabled = 3;
+ * @return {?proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getKillSwitchEnabled = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.KillSwitchEnabled} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.KillSwitchEnabled, 3));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.KillSwitchEnabled|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setKillSwitchEnabled = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 3, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearKillSwitchEnabled = function() {
+  return this.setKillSwitchEnabled(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasKillSwitchEnabled = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional KillSwitchDisabled kill_switch_disabled = 4;
+ * @return {?proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getKillSwitchDisabled = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.KillSwitchDisabled} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.KillSwitchDisabled, 4));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.KillSwitchDisabled|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setKillSwitchDisabled = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 4, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearKillSwitchDisabled = function() {
+  return this.setKillSwitchDisabled(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasKillSwitchDisabled = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional AuthorizedUserAdded authorized_user_added = 5;
+ * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserAdded = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserAdded, 5));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserAdded = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 5, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserAdded = function() {
+  return this.setAuthorizedUserAdded(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserAdded = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional AuthorizedUserUpdated authorized_user_updated = 6;
+ * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserUpdated = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated, 6));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserUpdated = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 6, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserUpdated = function() {
+  return this.setAuthorizedUserUpdated(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserUpdated = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional AuthorizedUserDeleted authorized_user_deleted = 7;
+ * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserDeleted = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted, 7));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserDeleted = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 7, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserDeleted = function() {
+  return this.setAuthorizedUserDeleted(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserDeleted = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/killSwitch/api_proto/kill_switch_pb.js b/src/killSwitch/api_proto/kill_switch_pb.js
new file mode 100644
index 0000000..586f08e
--- /dev/null
+++ b/src/killSwitch/api_proto/kill_switch_pb.js
@@ -0,0 +1,3123 @@
+// source: api_proto/kill_switch.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+var api_proto_common_pb = require('../api_proto/common_pb.js');
+goog.object.extend(proto, api_proto_common_pb);
+var api_proto_kill_switch_objects_pb = require('../api_proto/kill_switch_objects_pb.js');
+goog.object.extend(proto, api_proto_kill_switch_objects_pb);
+goog.exportSymbol('AddAuthorizedUserRequest', null, proto);
+goog.exportSymbol('AddAuthorizedUserResponse', null, proto);
+goog.exportSymbol('DeleteAuthorizedUserRequest', null, proto);
+goog.exportSymbol('DeleteAuthorizedUserResponse', null, proto);
+goog.exportSymbol('DisableKillSwitchRequest', null, proto);
+goog.exportSymbol('DisableKillSwitchResponse', null, proto);
+goog.exportSymbol('EnableKillSwitchRequest', null, proto);
+goog.exportSymbol('EnableKillSwitchResponse', null, proto);
+goog.exportSymbol('GetKillSwitchOverviewRequest', null, proto);
+goog.exportSymbol('GetKillSwitchOverviewResponse', null, proto);
+goog.exportSymbol('GetKillSwitchStatusRequest', null, proto);
+goog.exportSymbol('GetKillSwitchStatusResponse', null, proto);
+goog.exportSymbol('ListAuthorizedUsersRequest', null, proto);
+goog.exportSymbol('ListAuthorizedUsersResponse', null, proto);
+goog.exportSymbol('ListFeaturesRequest', null, proto);
+goog.exportSymbol('ListFeaturesResponse', null, proto);
+goog.exportSymbol('SyncFeaturesRequest', null, proto);
+goog.exportSymbol('SyncFeaturesResponse', null, proto);
+goog.exportSymbol('UpdateAuthorizedUserRequest', null, proto);
+goog.exportSymbol('UpdateAuthorizedUserResponse', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchStatusRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.GetKillSwitchStatusRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchStatusRequest.displayName = 'proto.GetKillSwitchStatusRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchStatusResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.GetKillSwitchStatusResponse.repeatedFields_, null);
+};
+goog.inherits(proto.GetKillSwitchStatusResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchStatusResponse.displayName = 'proto.GetKillSwitchStatusResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchOverviewRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.GetKillSwitchOverviewRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchOverviewRequest.displayName = 'proto.GetKillSwitchOverviewRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchOverviewResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.GetKillSwitchOverviewResponse.repeatedFields_, null);
+};
+goog.inherits(proto.GetKillSwitchOverviewResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchOverviewResponse.displayName = 'proto.GetKillSwitchOverviewResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListFeaturesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.ListFeaturesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListFeaturesRequest.displayName = 'proto.ListFeaturesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListFeaturesResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.ListFeaturesResponse.repeatedFields_, null);
+};
+goog.inherits(proto.ListFeaturesResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListFeaturesResponse.displayName = 'proto.ListFeaturesResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.SyncFeaturesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.SyncFeaturesRequest.repeatedFields_, null);
+};
+goog.inherits(proto.SyncFeaturesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.SyncFeaturesRequest.displayName = 'proto.SyncFeaturesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.SyncFeaturesResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.SyncFeaturesResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.SyncFeaturesResponse.displayName = 'proto.SyncFeaturesResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.EnableKillSwitchRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.EnableKillSwitchRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.EnableKillSwitchRequest.displayName = 'proto.EnableKillSwitchRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.EnableKillSwitchResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.EnableKillSwitchResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.EnableKillSwitchResponse.displayName = 'proto.EnableKillSwitchResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DisableKillSwitchRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DisableKillSwitchRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DisableKillSwitchRequest.displayName = 'proto.DisableKillSwitchRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DisableKillSwitchResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DisableKillSwitchResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DisableKillSwitchResponse.displayName = 'proto.DisableKillSwitchResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListAuthorizedUsersRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.ListAuthorizedUsersRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListAuthorizedUsersRequest.displayName = 'proto.ListAuthorizedUsersRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListAuthorizedUsersResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.ListAuthorizedUsersResponse.repeatedFields_, null);
+};
+goog.inherits(proto.ListAuthorizedUsersResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListAuthorizedUsersResponse.displayName = 'proto.ListAuthorizedUsersResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.AddAuthorizedUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.AddAuthorizedUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.AddAuthorizedUserRequest.displayName = 'proto.AddAuthorizedUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.AddAuthorizedUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.AddAuthorizedUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.AddAuthorizedUserResponse.displayName = 'proto.AddAuthorizedUserResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.UpdateAuthorizedUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.UpdateAuthorizedUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.UpdateAuthorizedUserRequest.displayName = 'proto.UpdateAuthorizedUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.UpdateAuthorizedUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.UpdateAuthorizedUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.UpdateAuthorizedUserResponse.displayName = 'proto.UpdateAuthorizedUserResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DeleteAuthorizedUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DeleteAuthorizedUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DeleteAuthorizedUserRequest.displayName = 'proto.DeleteAuthorizedUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DeleteAuthorizedUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DeleteAuthorizedUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DeleteAuthorizedUserResponse.displayName = 'proto.DeleteAuthorizedUserResponse';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchStatusRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchStatusRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchStatusRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    environment: (f = msg.getEnvironment()) && api_proto_common_pb.Environment.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchStatusRequest}
+ */
+proto.GetKillSwitchStatusRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchStatusRequest;
+  return proto.GetKillSwitchStatusRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchStatusRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchStatusRequest}
+ */
+proto.GetKillSwitchStatusRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_common_pb.Environment;
+      reader.readMessage(value,api_proto_common_pb.Environment.deserializeBinaryFromReader);
+      msg.setEnvironment(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchStatusRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchStatusRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchStatusRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getEnvironment();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      api_proto_common_pb.Environment.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional Environment environment = 1;
+ * @return {?proto.Environment}
+ */
+proto.GetKillSwitchStatusRequest.prototype.getEnvironment = function() {
+  return /** @type{?proto.Environment} */ (
+    jspb.Message.getWrapperField(this, api_proto_common_pb.Environment, 1));
+};
+
+
+/**
+ * @param {?proto.Environment|undefined} value
+ * @return {!proto.GetKillSwitchStatusRequest} returns this
+*/
+proto.GetKillSwitchStatusRequest.prototype.setEnvironment = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.GetKillSwitchStatusRequest} returns this
+ */
+proto.GetKillSwitchStatusRequest.prototype.clearEnvironment = function() {
+  return this.setEnvironment(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.GetKillSwitchStatusRequest.prototype.hasEnvironment = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.GetKillSwitchStatusResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchStatusResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchStatusResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchStatusResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitchesList: jspb.Message.toObjectList(msg.getKillSwitchesList(),
+    api_proto_kill_switch_objects_pb.KillSwitch.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchStatusResponse}
+ */
+proto.GetKillSwitchStatusResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchStatusResponse;
+  return proto.GetKillSwitchStatusResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchStatusResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchStatusResponse}
+ */
+proto.GetKillSwitchStatusResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitch;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitch.deserializeBinaryFromReader);
+      msg.addKillSwitches(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchStatusResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchStatusResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchStatusResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitchesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated KillSwitch kill_switches = 1;
+ * @return {!Array<!proto.KillSwitch>}
+ */
+proto.GetKillSwitchStatusResponse.prototype.getKillSwitchesList = function() {
+  return /** @type{!Array<!proto.KillSwitch>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitch, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.KillSwitch>} value
+ * @return {!proto.GetKillSwitchStatusResponse} returns this
+*/
+proto.GetKillSwitchStatusResponse.prototype.setKillSwitchesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.KillSwitch=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitch}
+ */
+proto.GetKillSwitchStatusResponse.prototype.addKillSwitches = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.KillSwitch, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.GetKillSwitchStatusResponse} returns this
+ */
+proto.GetKillSwitchStatusResponse.prototype.clearKillSwitchesList = function() {
+  return this.setKillSwitchesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchOverviewRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchOverviewRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchOverviewRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    withNonactiveKillSwitches: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchOverviewRequest}
+ */
+proto.GetKillSwitchOverviewRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchOverviewRequest;
+  return proto.GetKillSwitchOverviewRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchOverviewRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchOverviewRequest}
+ */
+proto.GetKillSwitchOverviewRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setWithNonactiveKillSwitches(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchOverviewRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchOverviewRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchOverviewRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getWithNonactiveKillSwitches();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool with_nonactive_kill_switches = 1;
+ * @return {boolean}
+ */
+proto.GetKillSwitchOverviewRequest.prototype.getWithNonactiveKillSwitches = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.GetKillSwitchOverviewRequest} returns this
+ */
+proto.GetKillSwitchOverviewRequest.prototype.setWithNonactiveKillSwitches = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.GetKillSwitchOverviewResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchOverviewResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchOverviewResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitchesList: jspb.Message.toObjectList(msg.getKillSwitchesList(),
+    api_proto_kill_switch_objects_pb.KillSwitch.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchOverviewResponse}
+ */
+proto.GetKillSwitchOverviewResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchOverviewResponse;
+  return proto.GetKillSwitchOverviewResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchOverviewResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchOverviewResponse}
+ */
+proto.GetKillSwitchOverviewResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitch;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitch.deserializeBinaryFromReader);
+      msg.addKillSwitches(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchOverviewResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchOverviewResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitchesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated KillSwitch kill_switches = 1;
+ * @return {!Array<!proto.KillSwitch>}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.getKillSwitchesList = function() {
+  return /** @type{!Array<!proto.KillSwitch>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitch, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.KillSwitch>} value
+ * @return {!proto.GetKillSwitchOverviewResponse} returns this
+*/
+proto.GetKillSwitchOverviewResponse.prototype.setKillSwitchesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.KillSwitch=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitch}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.addKillSwitches = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.KillSwitch, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.GetKillSwitchOverviewResponse} returns this
+ */
+proto.GetKillSwitchOverviewResponse.prototype.clearKillSwitchesList = function() {
+  return this.setKillSwitchesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListFeaturesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListFeaturesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListFeaturesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    withDeprecatedFeatures: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListFeaturesRequest}
+ */
+proto.ListFeaturesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListFeaturesRequest;
+  return proto.ListFeaturesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListFeaturesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListFeaturesRequest}
+ */
+proto.ListFeaturesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setWithDeprecatedFeatures(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListFeaturesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListFeaturesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListFeaturesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getWithDeprecatedFeatures();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool with_deprecated_features = 1;
+ * @return {boolean}
+ */
+proto.ListFeaturesRequest.prototype.getWithDeprecatedFeatures = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.ListFeaturesRequest} returns this
+ */
+proto.ListFeaturesRequest.prototype.setWithDeprecatedFeatures = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.ListFeaturesResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListFeaturesResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListFeaturesResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListFeaturesResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    featuresList: jspb.Message.toObjectList(msg.getFeaturesList(),
+    api_proto_kill_switch_objects_pb.Feature.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListFeaturesResponse}
+ */
+proto.ListFeaturesResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListFeaturesResponse;
+  return proto.ListFeaturesResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListFeaturesResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListFeaturesResponse}
+ */
+proto.ListFeaturesResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.Feature;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.Feature.deserializeBinaryFromReader);
+      msg.addFeatures(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListFeaturesResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListFeaturesResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListFeaturesResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFeaturesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.Feature.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Feature features = 1;
+ * @return {!Array<!proto.Feature>}
+ */
+proto.ListFeaturesResponse.prototype.getFeaturesList = function() {
+  return /** @type{!Array<!proto.Feature>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.Feature, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.Feature>} value
+ * @return {!proto.ListFeaturesResponse} returns this
+*/
+proto.ListFeaturesResponse.prototype.setFeaturesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.Feature=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.Feature}
+ */
+proto.ListFeaturesResponse.prototype.addFeatures = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.Feature, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.ListFeaturesResponse} returns this
+ */
+proto.ListFeaturesResponse.prototype.clearFeaturesList = function() {
+  return this.setFeaturesList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.SyncFeaturesRequest.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.SyncFeaturesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.SyncFeaturesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.SyncFeaturesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    featuresList: jspb.Message.toObjectList(msg.getFeaturesList(),
+    api_proto_kill_switch_objects_pb.Feature.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.SyncFeaturesRequest}
+ */
+proto.SyncFeaturesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.SyncFeaturesRequest;
+  return proto.SyncFeaturesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.SyncFeaturesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.SyncFeaturesRequest}
+ */
+proto.SyncFeaturesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.Feature;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.Feature.deserializeBinaryFromReader);
+      msg.addFeatures(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.SyncFeaturesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.SyncFeaturesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.SyncFeaturesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFeaturesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.Feature.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Feature features = 1;
+ * @return {!Array<!proto.Feature>}
+ */
+proto.SyncFeaturesRequest.prototype.getFeaturesList = function() {
+  return /** @type{!Array<!proto.Feature>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.Feature, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.Feature>} value
+ * @return {!proto.SyncFeaturesRequest} returns this
+*/
+proto.SyncFeaturesRequest.prototype.setFeaturesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.Feature=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.Feature}
+ */
+proto.SyncFeaturesRequest.prototype.addFeatures = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.Feature, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.SyncFeaturesRequest} returns this
+ */
+proto.SyncFeaturesRequest.prototype.clearFeaturesList = function() {
+  return this.setFeaturesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.SyncFeaturesResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.SyncFeaturesResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.SyncFeaturesResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.SyncFeaturesResponse}
+ */
+proto.SyncFeaturesResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.SyncFeaturesResponse;
+  return proto.SyncFeaturesResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.SyncFeaturesResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.SyncFeaturesResponse}
+ */
+proto.SyncFeaturesResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.SyncFeaturesResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.SyncFeaturesResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.SyncFeaturesResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.EnableKillSwitchRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.EnableKillSwitchRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.EnableKillSwitchRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitch: (f = msg.getKillSwitch()) && api_proto_kill_switch_objects_pb.KillSwitch.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.EnableKillSwitchRequest}
+ */
+proto.EnableKillSwitchRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.EnableKillSwitchRequest;
+  return proto.EnableKillSwitchRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.EnableKillSwitchRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.EnableKillSwitchRequest}
+ */
+proto.EnableKillSwitchRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitch;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitch.deserializeBinaryFromReader);
+      msg.setKillSwitch(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.EnableKillSwitchRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.EnableKillSwitchRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.EnableKillSwitchRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitch();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitch kill_switch = 1;
+ * @return {?proto.KillSwitch}
+ */
+proto.EnableKillSwitchRequest.prototype.getKillSwitch = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitch, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.EnableKillSwitchRequest} returns this
+*/
+proto.EnableKillSwitchRequest.prototype.setKillSwitch = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.EnableKillSwitchRequest} returns this
+ */
+proto.EnableKillSwitchRequest.prototype.clearKillSwitch = function() {
+  return this.setKillSwitch(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.EnableKillSwitchRequest.prototype.hasKillSwitch = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.EnableKillSwitchResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.EnableKillSwitchResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.EnableKillSwitchResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.EnableKillSwitchResponse}
+ */
+proto.EnableKillSwitchResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.EnableKillSwitchResponse;
+  return proto.EnableKillSwitchResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.EnableKillSwitchResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.EnableKillSwitchResponse}
+ */
+proto.EnableKillSwitchResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.EnableKillSwitchResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.EnableKillSwitchResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.EnableKillSwitchResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DisableKillSwitchRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.DisableKillSwitchRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DisableKillSwitchRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitchId: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DisableKillSwitchRequest}
+ */
+proto.DisableKillSwitchRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DisableKillSwitchRequest;
+  return proto.DisableKillSwitchRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DisableKillSwitchRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DisableKillSwitchRequest}
+ */
+proto.DisableKillSwitchRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setKillSwitchId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DisableKillSwitchRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DisableKillSwitchRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DisableKillSwitchRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitchId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 kill_switch_id = 1;
+ * @return {number}
+ */
+proto.DisableKillSwitchRequest.prototype.getKillSwitchId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.DisableKillSwitchRequest} returns this
+ */
+proto.DisableKillSwitchRequest.prototype.setKillSwitchId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DisableKillSwitchResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.DisableKillSwitchResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DisableKillSwitchResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DisableKillSwitchResponse}
+ */
+proto.DisableKillSwitchResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DisableKillSwitchResponse;
+  return proto.DisableKillSwitchResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DisableKillSwitchResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DisableKillSwitchResponse}
+ */
+proto.DisableKillSwitchResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DisableKillSwitchResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DisableKillSwitchResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DisableKillSwitchResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListAuthorizedUsersRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListAuthorizedUsersRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListAuthorizedUsersRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListAuthorizedUsersRequest}
+ */
+proto.ListAuthorizedUsersRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListAuthorizedUsersRequest;
+  return proto.ListAuthorizedUsersRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListAuthorizedUsersRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListAuthorizedUsersRequest}
+ */
+proto.ListAuthorizedUsersRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListAuthorizedUsersRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListAuthorizedUsersRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListAuthorizedUsersRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.ListAuthorizedUsersResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListAuthorizedUsersResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListAuthorizedUsersResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListAuthorizedUsersResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    usersList: jspb.Message.toObjectList(msg.getUsersList(),
+    api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListAuthorizedUsersResponse}
+ */
+proto.ListAuthorizedUsersResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListAuthorizedUsersResponse;
+  return proto.ListAuthorizedUsersResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListAuthorizedUsersResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListAuthorizedUsersResponse}
+ */
+proto.ListAuthorizedUsersResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.addUsers(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListAuthorizedUsersResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListAuthorizedUsersResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListAuthorizedUsersResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated KillSwitchAuthorizedUser users = 1;
+ * @return {!Array<!proto.KillSwitchAuthorizedUser>}
+ */
+proto.ListAuthorizedUsersResponse.prototype.getUsersList = function() {
+  return /** @type{!Array<!proto.KillSwitchAuthorizedUser>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.KillSwitchAuthorizedUser>} value
+ * @return {!proto.ListAuthorizedUsersResponse} returns this
+*/
+proto.ListAuthorizedUsersResponse.prototype.setUsersList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.KillSwitchAuthorizedUser=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitchAuthorizedUser}
+ */
+proto.ListAuthorizedUsersResponse.prototype.addUsers = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.KillSwitchAuthorizedUser, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.ListAuthorizedUsersResponse} returns this
+ */
+proto.ListAuthorizedUsersResponse.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.AddAuthorizedUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.AddAuthorizedUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.AddAuthorizedUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    user: (f = msg.getUser()) && api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.AddAuthorizedUserRequest}
+ */
+proto.AddAuthorizedUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.AddAuthorizedUserRequest;
+  return proto.AddAuthorizedUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.AddAuthorizedUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.AddAuthorizedUserRequest}
+ */
+proto.AddAuthorizedUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.AddAuthorizedUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.AddAuthorizedUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.AddAuthorizedUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.AddAuthorizedUserRequest.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.AddAuthorizedUserRequest} returns this
+*/
+proto.AddAuthorizedUserRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.AddAuthorizedUserRequest} returns this
+ */
+proto.AddAuthorizedUserRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.AddAuthorizedUserRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.AddAuthorizedUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.AddAuthorizedUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.AddAuthorizedUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.AddAuthorizedUserResponse}
+ */
+proto.AddAuthorizedUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.AddAuthorizedUserResponse;
+  return proto.AddAuthorizedUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.AddAuthorizedUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.AddAuthorizedUserResponse}
+ */
+proto.AddAuthorizedUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.AddAuthorizedUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.AddAuthorizedUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.AddAuthorizedUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.UpdateAuthorizedUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.UpdateAuthorizedUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    userId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    user: (f = msg.getUser()) && api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.UpdateAuthorizedUserRequest}
+ */
+proto.UpdateAuthorizedUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.UpdateAuthorizedUserRequest;
+  return proto.UpdateAuthorizedUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.UpdateAuthorizedUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.UpdateAuthorizedUserRequest}
+ */
+proto.UpdateAuthorizedUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setUserId(value);
+      break;
+    case 2:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.UpdateAuthorizedUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.UpdateAuthorizedUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUserId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional int32 user_id = 1;
+ * @return {number}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.getUserId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.UpdateAuthorizedUserRequest} returns this
+ */
+proto.UpdateAuthorizedUserRequest.prototype.setUserId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 2;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.UpdateAuthorizedUserRequest} returns this
+*/
+proto.UpdateAuthorizedUserRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.UpdateAuthorizedUserRequest} returns this
+ */
+proto.UpdateAuthorizedUserRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.UpdateAuthorizedUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.UpdateAuthorizedUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.UpdateAuthorizedUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.UpdateAuthorizedUserResponse}
+ */
+proto.UpdateAuthorizedUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.UpdateAuthorizedUserResponse;
+  return proto.UpdateAuthorizedUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.UpdateAuthorizedUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.UpdateAuthorizedUserResponse}
+ */
+proto.UpdateAuthorizedUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.UpdateAuthorizedUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.UpdateAuthorizedUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.UpdateAuthorizedUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DeleteAuthorizedUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.DeleteAuthorizedUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DeleteAuthorizedUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    userId: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DeleteAuthorizedUserRequest}
+ */
+proto.DeleteAuthorizedUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DeleteAuthorizedUserRequest;
+  return proto.DeleteAuthorizedUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DeleteAuthorizedUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DeleteAuthorizedUserRequest}
+ */
+proto.DeleteAuthorizedUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setUserId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DeleteAuthorizedUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DeleteAuthorizedUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DeleteAuthorizedUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUserId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 user_id = 1;
+ * @return {number}
+ */
+proto.DeleteAuthorizedUserRequest.prototype.getUserId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.DeleteAuthorizedUserRequest} returns this
+ */
+proto.DeleteAuthorizedUserRequest.prototype.setUserId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DeleteAuthorizedUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.DeleteAuthorizedUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DeleteAuthorizedUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DeleteAuthorizedUserResponse}
+ */
+proto.DeleteAuthorizedUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DeleteAuthorizedUserResponse;
+  return proto.DeleteAuthorizedUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DeleteAuthorizedUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DeleteAuthorizedUserResponse}
+ */
+proto.DeleteAuthorizedUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DeleteAuthorizedUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DeleteAuthorizedUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DeleteAuthorizedUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/killSwitch/index.js b/src/killSwitch/index.js
new file mode 100644
index 0000000..1456a51
--- /dev/null
+++ b/src/killSwitch/index.js
@@ -0,0 +1,79 @@
+import {compareLoose} from 'semver';
+
+import {getExtVersion, isFirefox} from '../common/extUtils.js';
+
+import * as commonPb from './api_proto/common_pb.js';
+import {KillSwitchServicePromiseClient} from './api_proto/kill_switch_grpc_web_pb.js';
+import * as ksPb from './api_proto/kill_switch_pb.js';
+
+const host =
+    (PRODUCTION ? 'https://twpt-grpc-web.avm99963.com/' :
+                  'http://localhost:8081');
+
+export default class KillSwitchMechanism {
+  constructor() {
+    this.client = new KillSwitchServicePromiseClient(host, null, null);
+  }
+
+  getCurrentBrowser() {
+    if (isFirefox()) return commonPb.Environment.Browser.BROWSER_GECKO;
+    return commonPb.Environment.Browser.BROWSER_CHROMIUM;
+  }
+
+  updateKillSwitchStatus() {
+    let request = new ksPb.GetKillSwitchOverviewRequest();
+    request.setWithNonactiveKillSwitches(false);
+
+    this.client.getKillSwitchOverview(request)
+        .then(res => {
+          let killSwitches = res.getKillSwitchesList();
+          let currentVersion = getExtVersion();
+          if (currentVersion === '0') currentVersion = '0.0.0';
+
+          let forceDisabledFeaturesSet = new Set();
+          for (let killSwitch of killSwitches) {
+            // If it isn't active, this kill switch is not applicable.
+            if (!killSwitch.getActive()) continue;
+
+            // If min_version is set and is greater than the current version,
+            // this kill switch is not applicable.
+            if (killSwitch.getMinVersion() != '' &&
+                compareLoose(killSwitch.getMinVersion(), currentVersion) == 1)
+              continue;
+
+            // If max_version is set and is less than the current version, this
+            // kill switch is not applicable.
+            if (killSwitch.getMaxVersion() != '' &&
+                compareLoose(killSwitch.getMaxVersion(), currentVersion) == -1)
+              continue;
+
+            let browsers = killSwitch.getBrowsersList();
+            let currentBrowser = this.getCurrentBrowser();
+
+            // If this browser isn't included as part of the kill switch, the
+            // kill switch is not applicable.
+            if (!browsers.includes(currentBrowser)) continue;
+
+            console.warn(
+                'Kill switch ' + killSwitch.getId() + ' will be applied!');
+
+            let featureCodename = killSwitch.getFeature()?.getCodename?.();
+            if (featureCodename) forceDisabledFeaturesSet.add(featureCodename);
+          }
+
+          let forceDisabledFeatures = Array.from(forceDisabledFeaturesSet);
+
+          chrome.storage.sync.set(
+              {_forceDisabledFeatures: forceDisabledFeatures}, () => {
+                if (forceDisabledFeatures.length > 0) {
+                  // TODO(avm99963): show a badge to warn that some features
+                  // have been force disabled.
+                }
+              });
+        })
+        .catch(err => {
+          console.error(
+              '[killSwitch] Can\'t retrieve kill switch status: ', err);
+        });
+  }
+};
diff --git a/src/optionsCommon.js b/src/optionsCommon.js
index 42983a5..27db635 100644
--- a/src/optionsCommon.js
+++ b/src/optionsCommon.js
@@ -108,13 +108,26 @@
     var featuresLink = document.querySelector('.features-link');
     featuresLink.href = getDocURL('features.md');
 
-    var profileIndicatorLink = document.getElementById('profileIndicatorMoreInfo');
+    var profileIndicatorLink =
+        document.getElementById('profileIndicatorMoreInfo');
     profileIndicatorLink.href = getDocURL('op_indicator.md');
   }
 
   chrome.storage.sync.get(null, function(items) {
     items = cleanUpOptions(items, false);
 
+    // If some features have been force disabled, communicate this to the user.
+    if (items?._forceDisabledFeatures &&
+        items._forceDisabledFeatures.length > 0) {
+      if (window.CONTEXT == 'options') {
+        document.getElementById('kill-switch-warning')
+            .removeAttribute('hidden');
+      }
+
+      // TODO(avm99963): show a message above each option that has been force
+      // disabled
+    }
+
     for (var entry of Object.entries(optionsPrototype)) {
       var opt = entry[0];
       var optMeta = entry[1];
diff --git a/src/static/_locales/en/messages.json b/src/static/_locales/en/messages.json
index f435664..10781fa 100644
--- a/src/static/_locales/en/messages.json
+++ b/src/static/_locales/en/messages.json
@@ -15,6 +15,10 @@
     "message": "Get infinite scroll and other enhancements in the Google Forums and the Community Console",
     "description": "The extension's description"
   },
+  "options_killswitchwarning": {
+    "message": "One or more options have been force disabled because they might not be working properly. Please go to the <a href='https://groups.google.com/g/twpowertools-discuss' rel='noreferrer noopener' action='_blank'>twpowertools-discuss Google Group</a> to learn more about why some options have been force disabled.",
+    "description": "Warning shown in the options page if a feature has been remotely force disabled via the kill switch mechanism. This happens when a feature doesn't work properly and might be doing dangerous things, and the maintainer or an authorized user remotely force disables the feature."
+  },
   "options_list": {
     "message": "Enable infinite scrolling in thread lists.",
     "description": "Feature checkbox in the options page"
diff --git a/src/static/options/options.css b/src/static/options/options.css
index 4ab69b3..a3cd7ab 100644
--- a/src/static/options/options.css
+++ b/src/static/options/options.css
@@ -24,11 +24,15 @@
   cursor: pointer;
 }
 
-.option {
+.option, .kill-switch-text {
   margin: 4px 0;
   line-height: 1.8em;
 }
 
+.kill-switch-text {
+  color: red;
+}
+
 .help {
   cursor: help;
   border-bottom: dashed 1px gray;
diff --git a/src/static/options/options.html b/src/static/options/options.html
index f22fb30..91a8205 100644
--- a/src/static/options/options.html
+++ b/src/static/options/options.html
@@ -39,6 +39,7 @@
         </a>
       </div>
       <form>
+        <div class="kill-switch-text" id="kill-switch-warning" hidden data-i18n="killswitchwarning"></div>
         <div class="option"><input type="checkbox" id="list"> <label for="list" data-i18n="list"></label></div>
         <div class="option"><input type="checkbox" id="thread"> <label for="thread" data-i18n="thread"></label></div>
         <div class="option"><input type="checkbox" id="threadall"> <label for="threadall" data-i18n="threadall"></label></div>
diff --git a/src/sw.js b/src/sw.js
index b8dccf2..73efa06 100644
--- a/src/sw.js
+++ b/src/sw.js
@@ -1,15 +1,42 @@
 // IMPORTANT: keep this file in sync with background.js
-import {cleanUpOptions} from './common/optionsUtils.js'
+import XMLHttpRequest from 'sw-xhr';
 
-// When the extension gets updated, set new options to their default value.
+import {cleanUpOptions} from './common/optionsUtils.js';
+import KillSwitchMechanism from './killSwitch/index.js';
+
+// XMLHttpRequest is not present in service workers and is required by the
+// grpc-web package. Importing a shim to work around this.
+// https://github.com/grpc/grpc-web/issues/1134
+self.XMLHttpRequest = XMLHttpRequest;
+
+chrome.action.onClicked.addListener(_ => {
+  chrome.runtime.openOptionsPage();
+});
+
+const killSwitchMechanism = new KillSwitchMechanism();
+
+chrome.alarms.create('updateKillSwitchStatus', {
+  periodInMinutes: PRODUCTION ? 30 : 1,
+});
+
+chrome.alarms.onAlarm.addListener(alarm => {
+  if (alarm.name === 'updateKillSwitchStatus')
+    killSwitchMechanism.updateKillSwitchStatus();
+});
+
+// When the profile is first started, update the kill switch status.
+chrome.runtime.onStartup.addListener(() => {
+  killSwitchMechanism.updateKillSwitchStatus();
+});
+
+// When the extension is first installed or gets updated, set new options to
+// their default value and update the kill switch status.
 chrome.runtime.onInstalled.addListener(details => {
   if (details.reason == 'install' || details.reason == 'update') {
     chrome.storage.sync.get(null, options => {
       cleanUpOptions(options, false);
     });
-  }
-});
 
-chrome.action.onClicked.addListener(_ => {
-  chrome.runtime.openOptionsPage();
+    killSwitchMechanism.updateKillSwitchStatus();
+  }
 });
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/any_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/any_pb.js
new file mode 100644
index 0000000..62b1383
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/any_pb.js
@@ -0,0 +1,275 @@
+// source: google/protobuf/any.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.Any', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Any = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Any, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Any.displayName = 'proto.google.protobuf.Any';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Any.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Any.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Any} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Any.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    typeUrl: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    value: msg.getValue_asB64()
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Any}
+ */
+proto.google.protobuf.Any.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Any;
+  return proto.google.protobuf.Any.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Any} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Any}
+ */
+proto.google.protobuf.Any.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTypeUrl(value);
+      break;
+    case 2:
+      var value = /** @type {!Uint8Array} */ (reader.readBytes());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Any.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Any.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Any} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Any.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTypeUrl();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getValue_asU8();
+  if (f.length > 0) {
+    writer.writeBytes(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string type_url = 1;
+ * @return {string}
+ */
+proto.google.protobuf.Any.prototype.getTypeUrl = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Any} returns this
+ */
+proto.google.protobuf.Any.prototype.setTypeUrl = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional bytes value = 2;
+ * @return {!(string|Uint8Array)}
+ */
+proto.google.protobuf.Any.prototype.getValue = function() {
+  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * optional bytes value = 2;
+ * This is a type-conversion wrapper around `getValue()`
+ * @return {string}
+ */
+proto.google.protobuf.Any.prototype.getValue_asB64 = function() {
+  return /** @type {string} */ (jspb.Message.bytesAsB64(
+      this.getValue()));
+};
+
+
+/**
+ * optional bytes value = 2;
+ * Note that Uint8Array is not supported on all browsers.
+ * @see http://caniuse.com/Uint8Array
+ * This is a type-conversion wrapper around `getValue()`
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Any.prototype.getValue_asU8 = function() {
+  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
+      this.getValue()));
+};
+
+
+/**
+ * @param {!(string|Uint8Array)} value
+ * @return {!proto.google.protobuf.Any} returns this
+ */
+proto.google.protobuf.Any.prototype.setValue = function(value) {
+  return jspb.Message.setProto3BytesField(this, 2, value);
+};
+
+
+goog.object.extend(exports, proto);
+/* This code will be inserted into generated code for
+ * google/protobuf/any.proto. */
+
+/**
+ * Returns the type name contained in this instance, if any.
+ * @return {string|undefined}
+ */
+proto.google.protobuf.Any.prototype.getTypeName = function() {
+  return this.getTypeUrl().split('/').pop();
+};
+
+
+/**
+ * Packs the given message instance into this Any.
+ * For binary format usage only.
+ * @param {!Uint8Array} serialized The serialized data to pack.
+ * @param {string} name The type name of this message object.
+ * @param {string=} opt_typeUrlPrefix the type URL prefix.
+ */
+proto.google.protobuf.Any.prototype.pack = function(serialized, name,
+                                                    opt_typeUrlPrefix) {
+  if (!opt_typeUrlPrefix) {
+    opt_typeUrlPrefix = 'type.googleapis.com/';
+  }
+
+  if (opt_typeUrlPrefix.substr(-1) != '/') {
+    this.setTypeUrl(opt_typeUrlPrefix + '/' + name);
+  } else {
+    this.setTypeUrl(opt_typeUrlPrefix + name);
+  }
+
+  this.setValue(serialized);
+};
+
+
+/**
+ * @template T
+ * Unpacks this Any into the given message object.
+ * @param {function(Uint8Array):T} deserialize Function that will deserialize
+ *     the binary data properly.
+ * @param {string} name The expected type name of this message object.
+ * @return {?T} If the name matched the expected name, returns the deserialized
+ *     object, otherwise returns null.
+ */
+proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) {
+  if (this.getTypeName() == name) {
+    return deserialize(this.getValue_asU8());
+  } else {
+    return null;
+  }
+};
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/api_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/api_pb.js
new file mode 100644
index 0000000..2ca9be2
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/api_pb.js
@@ -0,0 +1,995 @@
+// source: google/protobuf/api.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+var google_protobuf_source_context_pb = require('google-protobuf/google/protobuf/source_context_pb.js');
+goog.object.extend(proto, google_protobuf_source_context_pb);
+var google_protobuf_type_pb = require('google-protobuf/google/protobuf/type_pb.js');
+goog.object.extend(proto, google_protobuf_type_pb);
+goog.exportSymbol('google.protobuf.Api', null, proto);
+goog.exportSymbol('google.protobuf.Method', null, proto);
+goog.exportSymbol('google.protobuf.Mixin', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Api = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Api.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.Api, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Api.displayName = 'proto.google.protobuf.Api';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Method = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Method.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.Method, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Method.displayName = 'proto.google.protobuf.Method';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Mixin = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Mixin, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Mixin.displayName = 'proto.google.protobuf.Mixin';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.Api.repeatedFields_ = [2,3,6];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Api.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Api.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Api} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Api.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    methodsList: jspb.Message.toObjectList(msg.getMethodsList(),
+    proto.google.protobuf.Method.toObject, includeInstance),
+    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
+    google_protobuf_type_pb.Option.toObject, includeInstance),
+    version: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    sourceContext: (f = msg.getSourceContext()) && google_protobuf_source_context_pb.SourceContext.toObject(includeInstance, f),
+    mixinsList: jspb.Message.toObjectList(msg.getMixinsList(),
+    proto.google.protobuf.Mixin.toObject, includeInstance),
+    syntax: jspb.Message.getFieldWithDefault(msg, 7, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Api}
+ */
+proto.google.protobuf.Api.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Api;
+  return proto.google.protobuf.Api.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Api} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Api}
+ */
+proto.google.protobuf.Api.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new proto.google.protobuf.Method;
+      reader.readMessage(value,proto.google.protobuf.Method.deserializeBinaryFromReader);
+      msg.addMethods(value);
+      break;
+    case 3:
+      var value = new google_protobuf_type_pb.Option;
+      reader.readMessage(value,google_protobuf_type_pb.Option.deserializeBinaryFromReader);
+      msg.addOptions(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setVersion(value);
+      break;
+    case 5:
+      var value = new google_protobuf_source_context_pb.SourceContext;
+      reader.readMessage(value,google_protobuf_source_context_pb.SourceContext.deserializeBinaryFromReader);
+      msg.setSourceContext(value);
+      break;
+    case 6:
+      var value = new proto.google.protobuf.Mixin;
+      reader.readMessage(value,proto.google.protobuf.Mixin.deserializeBinaryFromReader);
+      msg.addMixins(value);
+      break;
+    case 7:
+      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
+      msg.setSyntax(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Api.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Api.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Api} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Api.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getMethodsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.google.protobuf.Method.serializeBinaryToWriter
+    );
+  }
+  f = message.getOptionsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      3,
+      f,
+      google_protobuf_type_pb.Option.serializeBinaryToWriter
+    );
+  }
+  f = message.getVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getSourceContext();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      google_protobuf_source_context_pb.SourceContext.serializeBinaryToWriter
+    );
+  }
+  f = message.getMixinsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.google.protobuf.Mixin.serializeBinaryToWriter
+    );
+  }
+  f = message.getSyntax();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.Api.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Api} returns this
+ */
+proto.google.protobuf.Api.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated Method methods = 2;
+ * @return {!Array<!proto.google.protobuf.Method>}
+ */
+proto.google.protobuf.Api.prototype.getMethodsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Method>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Method, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Method>} value
+ * @return {!proto.google.protobuf.Api} returns this
+*/
+proto.google.protobuf.Api.prototype.setMethodsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Method=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Method}
+ */
+proto.google.protobuf.Api.prototype.addMethods = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.Method, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Api} returns this
+ */
+proto.google.protobuf.Api.prototype.clearMethodsList = function() {
+  return this.setMethodsList([]);
+};
+
+
+/**
+ * repeated Option options = 3;
+ * @return {!Array<!proto.google.protobuf.Option>}
+ */
+proto.google.protobuf.Api.prototype.getOptionsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
+    jspb.Message.getRepeatedWrapperField(this, google_protobuf_type_pb.Option, 3));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Option>} value
+ * @return {!proto.google.protobuf.Api} returns this
+*/
+proto.google.protobuf.Api.prototype.setOptionsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 3, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Option=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.Api.prototype.addOptions = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.Option, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Api} returns this
+ */
+proto.google.protobuf.Api.prototype.clearOptionsList = function() {
+  return this.setOptionsList([]);
+};
+
+
+/**
+ * optional string version = 4;
+ * @return {string}
+ */
+proto.google.protobuf.Api.prototype.getVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Api} returns this
+ */
+proto.google.protobuf.Api.prototype.setVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional SourceContext source_context = 5;
+ * @return {?proto.google.protobuf.SourceContext}
+ */
+proto.google.protobuf.Api.prototype.getSourceContext = function() {
+  return /** @type{?proto.google.protobuf.SourceContext} */ (
+    jspb.Message.getWrapperField(this, google_protobuf_source_context_pb.SourceContext, 5));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.SourceContext|undefined} value
+ * @return {!proto.google.protobuf.Api} returns this
+*/
+proto.google.protobuf.Api.prototype.setSourceContext = function(value) {
+  return jspb.Message.setWrapperField(this, 5, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.Api} returns this
+ */
+proto.google.protobuf.Api.prototype.clearSourceContext = function() {
+  return this.setSourceContext(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Api.prototype.hasSourceContext = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * repeated Mixin mixins = 6;
+ * @return {!Array<!proto.google.protobuf.Mixin>}
+ */
+proto.google.protobuf.Api.prototype.getMixinsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Mixin>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Mixin, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Mixin>} value
+ * @return {!proto.google.protobuf.Api} returns this
+*/
+proto.google.protobuf.Api.prototype.setMixinsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Mixin=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Mixin}
+ */
+proto.google.protobuf.Api.prototype.addMixins = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.Mixin, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Api} returns this
+ */
+proto.google.protobuf.Api.prototype.clearMixinsList = function() {
+  return this.setMixinsList([]);
+};
+
+
+/**
+ * optional Syntax syntax = 7;
+ * @return {!proto.google.protobuf.Syntax}
+ */
+proto.google.protobuf.Api.prototype.getSyntax = function() {
+  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Syntax} value
+ * @return {!proto.google.protobuf.Api} returns this
+ */
+proto.google.protobuf.Api.prototype.setSyntax = function(value) {
+  return jspb.Message.setProto3EnumField(this, 7, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.Method.repeatedFields_ = [6];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Method.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Method.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Method} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Method.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    requestTypeUrl: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    requestStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
+    responseTypeUrl: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    responseStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
+    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
+    google_protobuf_type_pb.Option.toObject, includeInstance),
+    syntax: jspb.Message.getFieldWithDefault(msg, 7, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Method}
+ */
+proto.google.protobuf.Method.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Method;
+  return proto.google.protobuf.Method.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Method} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Method}
+ */
+proto.google.protobuf.Method.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRequestTypeUrl(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setRequestStreaming(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setResponseTypeUrl(value);
+      break;
+    case 5:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setResponseStreaming(value);
+      break;
+    case 6:
+      var value = new google_protobuf_type_pb.Option;
+      reader.readMessage(value,google_protobuf_type_pb.Option.deserializeBinaryFromReader);
+      msg.addOptions(value);
+      break;
+    case 7:
+      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
+      msg.setSyntax(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Method.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Method.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Method} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Method.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getRequestTypeUrl();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getRequestStreaming();
+  if (f) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+  f = message.getResponseTypeUrl();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getResponseStreaming();
+  if (f) {
+    writer.writeBool(
+      5,
+      f
+    );
+  }
+  f = message.getOptionsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      google_protobuf_type_pb.Option.serializeBinaryToWriter
+    );
+  }
+  f = message.getSyntax();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.Method.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Method} returns this
+ */
+proto.google.protobuf.Method.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string request_type_url = 2;
+ * @return {string}
+ */
+proto.google.protobuf.Method.prototype.getRequestTypeUrl = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Method} returns this
+ */
+proto.google.protobuf.Method.prototype.setRequestTypeUrl = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional bool request_streaming = 3;
+ * @return {boolean}
+ */
+proto.google.protobuf.Method.prototype.getRequestStreaming = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.Method} returns this
+ */
+proto.google.protobuf.Method.prototype.setRequestStreaming = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 3, value);
+};
+
+
+/**
+ * optional string response_type_url = 4;
+ * @return {string}
+ */
+proto.google.protobuf.Method.prototype.getResponseTypeUrl = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Method} returns this
+ */
+proto.google.protobuf.Method.prototype.setResponseTypeUrl = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional bool response_streaming = 5;
+ * @return {boolean}
+ */
+proto.google.protobuf.Method.prototype.getResponseStreaming = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.Method} returns this
+ */
+proto.google.protobuf.Method.prototype.setResponseStreaming = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 5, value);
+};
+
+
+/**
+ * repeated Option options = 6;
+ * @return {!Array<!proto.google.protobuf.Option>}
+ */
+proto.google.protobuf.Method.prototype.getOptionsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
+    jspb.Message.getRepeatedWrapperField(this, google_protobuf_type_pb.Option, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Option>} value
+ * @return {!proto.google.protobuf.Method} returns this
+*/
+proto.google.protobuf.Method.prototype.setOptionsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Option=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.Method.prototype.addOptions = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.Option, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Method} returns this
+ */
+proto.google.protobuf.Method.prototype.clearOptionsList = function() {
+  return this.setOptionsList([]);
+};
+
+
+/**
+ * optional Syntax syntax = 7;
+ * @return {!proto.google.protobuf.Syntax}
+ */
+proto.google.protobuf.Method.prototype.getSyntax = function() {
+  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Syntax} value
+ * @return {!proto.google.protobuf.Method} returns this
+ */
+proto.google.protobuf.Method.prototype.setSyntax = function(value) {
+  return jspb.Message.setProto3EnumField(this, 7, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Mixin.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Mixin.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Mixin} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Mixin.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    root: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Mixin}
+ */
+proto.google.protobuf.Mixin.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Mixin;
+  return proto.google.protobuf.Mixin.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Mixin} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Mixin}
+ */
+proto.google.protobuf.Mixin.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRoot(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Mixin.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Mixin.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Mixin} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Mixin.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getRoot();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.Mixin.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Mixin} returns this
+ */
+proto.google.protobuf.Mixin.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string root = 2;
+ * @return {string}
+ */
+proto.google.protobuf.Mixin.prototype.getRoot = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Mixin} returns this
+ */
+proto.google.protobuf.Mixin.prototype.setRoot = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/compiler/plugin_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/compiler/plugin_pb.js
new file mode 100644
index 0000000..d080473
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/compiler/plugin_pb.js
@@ -0,0 +1,1268 @@
+// source: google/protobuf/compiler/plugin.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+var google_protobuf_descriptor_pb = require('google-protobuf/google/protobuf/descriptor_pb.js');
+goog.object.extend(proto, google_protobuf_descriptor_pb);
+goog.exportSymbol('google.protobuf.compiler.CodeGeneratorRequest', null, proto);
+goog.exportSymbol('google.protobuf.compiler.CodeGeneratorResponse', null, proto);
+goog.exportSymbol('google.protobuf.compiler.CodeGeneratorResponse.Feature', null, proto);
+goog.exportSymbol('google.protobuf.compiler.CodeGeneratorResponse.File', null, proto);
+goog.exportSymbol('google.protobuf.compiler.Version', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.compiler.Version = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.compiler.Version, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.compiler.Version.displayName = 'proto.google.protobuf.compiler.Version';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.compiler.CodeGeneratorRequest.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.compiler.CodeGeneratorRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.compiler.CodeGeneratorRequest.displayName = 'proto.google.protobuf.compiler.CodeGeneratorRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.compiler.CodeGeneratorResponse.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.compiler.CodeGeneratorResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.compiler.CodeGeneratorResponse.displayName = 'proto.google.protobuf.compiler.CodeGeneratorResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.compiler.CodeGeneratorResponse.File, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.compiler.CodeGeneratorResponse.File.displayName = 'proto.google.protobuf.compiler.CodeGeneratorResponse.File';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.compiler.Version.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.compiler.Version.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.compiler.Version} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.Version.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    major: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    minor: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    patch: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    suffix: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.compiler.Version}
+ */
+proto.google.protobuf.compiler.Version.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.compiler.Version;
+  return proto.google.protobuf.compiler.Version.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.compiler.Version} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.compiler.Version}
+ */
+proto.google.protobuf.compiler.Version.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setMajor(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setMinor(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setPatch(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSuffix(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.compiler.Version.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.compiler.Version.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.compiler.Version} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.Version.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {number} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeInt32(
+      3,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 major = 1;
+ * @return {number}
+ */
+proto.google.protobuf.compiler.Version.prototype.getMajor = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.setMajor = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.clearMajor = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.Version.prototype.hasMajor = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int32 minor = 2;
+ * @return {number}
+ */
+proto.google.protobuf.compiler.Version.prototype.getMinor = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.setMinor = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.clearMinor = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.Version.prototype.hasMinor = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional int32 patch = 3;
+ * @return {number}
+ */
+proto.google.protobuf.compiler.Version.prototype.getPatch = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.setPatch = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.clearPatch = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.Version.prototype.hasPatch = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional string suffix = 4;
+ * @return {string}
+ */
+proto.google.protobuf.compiler.Version.prototype.getSuffix = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.setSuffix = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.Version} returns this
+ */
+proto.google.protobuf.compiler.Version.prototype.clearSuffix = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.Version.prototype.hasSuffix = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.repeatedFields_ = [1,15];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.compiler.CodeGeneratorRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    fileToGenerateList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f,
+    parameter: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    protoFileList: jspb.Message.toObjectList(msg.getProtoFileList(),
+    google_protobuf_descriptor_pb.FileDescriptorProto.toObject, includeInstance),
+    compilerVersion: (f = msg.getCompilerVersion()) && proto.google.protobuf.compiler.Version.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.compiler.CodeGeneratorRequest;
+  return proto.google.protobuf.compiler.CodeGeneratorRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addFileToGenerate(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setParameter(value);
+      break;
+    case 15:
+      var value = new google_protobuf_descriptor_pb.FileDescriptorProto;
+      reader.readMessage(value,google_protobuf_descriptor_pb.FileDescriptorProto.deserializeBinaryFromReader);
+      msg.addProtoFile(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.compiler.Version;
+      reader.readMessage(value,proto.google.protobuf.compiler.Version.deserializeBinaryFromReader);
+      msg.setCompilerVersion(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.compiler.CodeGeneratorRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFileToGenerateList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getProtoFileList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      15,
+      f,
+      google_protobuf_descriptor_pb.FileDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getCompilerVersion();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.google.protobuf.compiler.Version.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated string file_to_generate = 1;
+ * @return {!Array<string>}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getFileToGenerateList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setFileToGenerateList = function(value) {
+  return jspb.Message.setField(this, 1, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.addFileToGenerate = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearFileToGenerateList = function() {
+  return this.setFileToGenerateList([]);
+};
+
+
+/**
+ * optional string parameter = 2;
+ * @return {string}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getParameter = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setParameter = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearParameter = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.hasParameter = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * repeated google.protobuf.FileDescriptorProto proto_file = 15;
+ * @return {!Array<!proto.google.protobuf.FileDescriptorProto>}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getProtoFileList = function() {
+  return /** @type{!Array<!proto.google.protobuf.FileDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, google_protobuf_descriptor_pb.FileDescriptorProto, 15));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.FileDescriptorProto>} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+*/
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setProtoFileList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 15, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FileDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FileDescriptorProto}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.addProtoFile = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 15, opt_value, proto.google.protobuf.FileDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearProtoFileList = function() {
+  return this.setProtoFileList([]);
+};
+
+
+/**
+ * optional Version compiler_version = 3;
+ * @return {?proto.google.protobuf.compiler.Version}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.getCompilerVersion = function() {
+  return /** @type{?proto.google.protobuf.compiler.Version} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.compiler.Version, 3));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.compiler.Version|undefined} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+*/
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.setCompilerVersion = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorRequest} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.clearCompilerVersion = function() {
+  return this.setCompilerVersion(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorRequest.prototype.hasCompilerVersion = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.repeatedFields_ = [15];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.compiler.CodeGeneratorResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    error: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    supportedFeatures: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    fileList: jspb.Message.toObjectList(msg.getFileList(),
+    proto.google.protobuf.compiler.CodeGeneratorResponse.File.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.compiler.CodeGeneratorResponse;
+  return proto.google.protobuf.compiler.CodeGeneratorResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setError(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setSupportedFeatures(value);
+      break;
+    case 15:
+      var value = new proto.google.protobuf.compiler.CodeGeneratorResponse.File;
+      reader.readMessage(value,proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinaryFromReader);
+      msg.addFile(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.compiler.CodeGeneratorResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeUint64(
+      2,
+      f
+    );
+  }
+  f = message.getFileList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      15,
+      f,
+      proto.google.protobuf.compiler.CodeGeneratorResponse.File.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.Feature = {
+  FEATURE_NONE: 0,
+  FEATURE_PROTO3_OPTIONAL: 1
+};
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.compiler.CodeGeneratorResponse.File.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    insertionPoint: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    content: (f = jspb.Message.getField(msg, 15)) == null ? undefined : f,
+    generatedCodeInfo: (f = msg.getGeneratedCodeInfo()) && google_protobuf_descriptor_pb.GeneratedCodeInfo.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.compiler.CodeGeneratorResponse.File;
+  return proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInsertionPoint(value);
+      break;
+    case 15:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setContent(value);
+      break;
+    case 16:
+      var value = new google_protobuf_descriptor_pb.GeneratedCodeInfo;
+      reader.readMessage(value,google_protobuf_descriptor_pb.GeneratedCodeInfo.deserializeBinaryFromReader);
+      msg.setGeneratedCodeInfo(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.compiler.CodeGeneratorResponse.File.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 15));
+  if (f != null) {
+    writer.writeString(
+      15,
+      f
+    );
+  }
+  f = message.getGeneratedCodeInfo();
+  if (f != null) {
+    writer.writeMessage(
+      16,
+      f,
+      google_protobuf_descriptor_pb.GeneratedCodeInfo.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string insertion_point = 2;
+ * @return {string}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getInsertionPoint = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setInsertionPoint = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearInsertionPoint = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasInsertionPoint = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string content = 15;
+ * @return {string}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getContent = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 15, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setContent = function(value) {
+  return jspb.Message.setField(this, 15, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearContent = function() {
+  return jspb.Message.setField(this, 15, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasContent = function() {
+  return jspb.Message.getField(this, 15) != null;
+};
+
+
+/**
+ * optional google.protobuf.GeneratedCodeInfo generated_code_info = 16;
+ * @return {?proto.google.protobuf.GeneratedCodeInfo}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.getGeneratedCodeInfo = function() {
+  return /** @type{?proto.google.protobuf.GeneratedCodeInfo} */ (
+    jspb.Message.getWrapperField(this, google_protobuf_descriptor_pb.GeneratedCodeInfo, 16));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.GeneratedCodeInfo|undefined} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+*/
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.setGeneratedCodeInfo = function(value) {
+  return jspb.Message.setWrapperField(this, 16, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.clearGeneratedCodeInfo = function() {
+  return this.setGeneratedCodeInfo(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.File.prototype.hasGeneratedCodeInfo = function() {
+  return jspb.Message.getField(this, 16) != null;
+};
+
+
+/**
+ * optional string error = 1;
+ * @return {string}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.getError = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.setError = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.clearError = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.hasError = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional uint64 supported_features = 2;
+ * @return {number}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.getSupportedFeatures = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.setSupportedFeatures = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.clearSupportedFeatures = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.hasSupportedFeatures = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * repeated File file = 15;
+ * @return {!Array<!proto.google.protobuf.compiler.CodeGeneratorResponse.File>}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.getFileList = function() {
+  return /** @type{!Array<!proto.google.protobuf.compiler.CodeGeneratorResponse.File>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.compiler.CodeGeneratorResponse.File, 15));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.compiler.CodeGeneratorResponse.File>} value
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
+*/
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.setFileList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 15, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.compiler.CodeGeneratorResponse.File=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse.File}
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.addFile = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 15, opt_value, proto.google.protobuf.compiler.CodeGeneratorResponse.File, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.compiler.CodeGeneratorResponse} returns this
+ */
+proto.google.protobuf.compiler.CodeGeneratorResponse.prototype.clearFileList = function() {
+  return this.setFileList([]);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/descriptor_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/descriptor_pb.js
new file mode 100644
index 0000000..b0a9f1f
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/descriptor_pb.js
@@ -0,0 +1,10070 @@
+// source: google/protobuf/descriptor.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.DescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.DescriptorProto.ExtensionRange', null, proto);
+goog.exportSymbol('google.protobuf.DescriptorProto.ReservedRange', null, proto);
+goog.exportSymbol('google.protobuf.EnumDescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.EnumDescriptorProto.EnumReservedRange', null, proto);
+goog.exportSymbol('google.protobuf.EnumOptions', null, proto);
+goog.exportSymbol('google.protobuf.EnumValueDescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.EnumValueOptions', null, proto);
+goog.exportSymbol('google.protobuf.ExtensionRangeOptions', null, proto);
+goog.exportSymbol('google.protobuf.FieldDescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.FieldDescriptorProto.Label', null, proto);
+goog.exportSymbol('google.protobuf.FieldDescriptorProto.Type', null, proto);
+goog.exportSymbol('google.protobuf.FieldOptions', null, proto);
+goog.exportSymbol('google.protobuf.FieldOptions.CType', null, proto);
+goog.exportSymbol('google.protobuf.FieldOptions.JSType', null, proto);
+goog.exportSymbol('google.protobuf.FileDescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.FileDescriptorSet', null, proto);
+goog.exportSymbol('google.protobuf.FileOptions', null, proto);
+goog.exportSymbol('google.protobuf.FileOptions.OptimizeMode', null, proto);
+goog.exportSymbol('google.protobuf.GeneratedCodeInfo', null, proto);
+goog.exportSymbol('google.protobuf.GeneratedCodeInfo.Annotation', null, proto);
+goog.exportSymbol('google.protobuf.MessageOptions', null, proto);
+goog.exportSymbol('google.protobuf.MethodDescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.MethodOptions', null, proto);
+goog.exportSymbol('google.protobuf.MethodOptions.IdempotencyLevel', null, proto);
+goog.exportSymbol('google.protobuf.OneofDescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.OneofOptions', null, proto);
+goog.exportSymbol('google.protobuf.ServiceDescriptorProto', null, proto);
+goog.exportSymbol('google.protobuf.ServiceOptions', null, proto);
+goog.exportSymbol('google.protobuf.SourceCodeInfo', null, proto);
+goog.exportSymbol('google.protobuf.SourceCodeInfo.Location', null, proto);
+goog.exportSymbol('google.protobuf.UninterpretedOption', null, proto);
+goog.exportSymbol('google.protobuf.UninterpretedOption.NamePart', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.FileDescriptorSet = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.FileDescriptorSet.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.FileDescriptorSet, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.FileDescriptorSet.displayName = 'proto.google.protobuf.FileDescriptorSet';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.FileDescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.FileDescriptorProto.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.FileDescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.FileDescriptorProto.displayName = 'proto.google.protobuf.FileDescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.DescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.DescriptorProto.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.DescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.DescriptorProto.displayName = 'proto.google.protobuf.DescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.DescriptorProto.ExtensionRange, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.DescriptorProto.ExtensionRange.displayName = 'proto.google.protobuf.DescriptorProto.ExtensionRange';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.DescriptorProto.ReservedRange, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.DescriptorProto.ReservedRange.displayName = 'proto.google.protobuf.DescriptorProto.ReservedRange';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.ExtensionRangeOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.ExtensionRangeOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.ExtensionRangeOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.ExtensionRangeOptions.displayName = 'proto.google.protobuf.ExtensionRangeOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.ExtensionRangeOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.ExtensionRangeOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.FieldDescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.FieldDescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.FieldDescriptorProto.displayName = 'proto.google.protobuf.FieldDescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.OneofDescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.OneofDescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.OneofDescriptorProto.displayName = 'proto.google.protobuf.OneofDescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.EnumDescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.EnumDescriptorProto.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.EnumDescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.EnumDescriptorProto.displayName = 'proto.google.protobuf.EnumDescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.EnumDescriptorProto.EnumReservedRange, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.displayName = 'proto.google.protobuf.EnumDescriptorProto.EnumReservedRange';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.EnumValueDescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.EnumValueDescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.EnumValueDescriptorProto.displayName = 'proto.google.protobuf.EnumValueDescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.ServiceDescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.ServiceDescriptorProto.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.ServiceDescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.ServiceDescriptorProto.displayName = 'proto.google.protobuf.ServiceDescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.MethodDescriptorProto = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.MethodDescriptorProto, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.MethodDescriptorProto.displayName = 'proto.google.protobuf.MethodDescriptorProto';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.FileOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.FileOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.FileOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.FileOptions.displayName = 'proto.google.protobuf.FileOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.FileOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.FileOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.MessageOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.MessageOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.MessageOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.MessageOptions.displayName = 'proto.google.protobuf.MessageOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.MessageOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.MessageOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.FieldOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.FieldOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.FieldOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.FieldOptions.displayName = 'proto.google.protobuf.FieldOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.FieldOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.FieldOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.OneofOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.OneofOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.OneofOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.OneofOptions.displayName = 'proto.google.protobuf.OneofOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.OneofOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.OneofOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.EnumOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.EnumOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.EnumOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.EnumOptions.displayName = 'proto.google.protobuf.EnumOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.EnumOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.EnumOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.EnumValueOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.EnumValueOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.EnumValueOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.EnumValueOptions.displayName = 'proto.google.protobuf.EnumValueOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.EnumValueOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.EnumValueOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.ServiceOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.ServiceOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.ServiceOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.ServiceOptions.displayName = 'proto.google.protobuf.ServiceOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.ServiceOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.ServiceOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.MethodOptions = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, 500, proto.google.protobuf.MethodOptions.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.MethodOptions, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.MethodOptions.displayName = 'proto.google.protobuf.MethodOptions';
+}
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
+ */
+proto.google.protobuf.MethodOptions.extensions = {};
+
+
+/**
+ * The extensions registered with this message class. This is a map of
+ * extension field number to fieldInfo object.
+ *
+ * For example:
+ *     { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, ctor: proto.example.MyMessage} }
+ *
+ * fieldName contains the JsCompiler renamed field name property so that it
+ * works in OPTIMIZED mode.
+ *
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
+proto.google.protobuf.MethodOptions.extensionsBinary = {};
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.UninterpretedOption = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.UninterpretedOption.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.UninterpretedOption, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.UninterpretedOption.displayName = 'proto.google.protobuf.UninterpretedOption';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.UninterpretedOption.NamePart = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.UninterpretedOption.NamePart, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.UninterpretedOption.NamePart.displayName = 'proto.google.protobuf.UninterpretedOption.NamePart';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.SourceCodeInfo = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.SourceCodeInfo.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.SourceCodeInfo, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.SourceCodeInfo.displayName = 'proto.google.protobuf.SourceCodeInfo';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.SourceCodeInfo.Location = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.SourceCodeInfo.Location.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.SourceCodeInfo.Location, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.SourceCodeInfo.Location.displayName = 'proto.google.protobuf.SourceCodeInfo.Location';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.GeneratedCodeInfo = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.GeneratedCodeInfo.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.GeneratedCodeInfo, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.GeneratedCodeInfo.displayName = 'proto.google.protobuf.GeneratedCodeInfo';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.GeneratedCodeInfo.Annotation.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.GeneratedCodeInfo.Annotation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.GeneratedCodeInfo.Annotation.displayName = 'proto.google.protobuf.GeneratedCodeInfo.Annotation';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.FileDescriptorSet.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.FileDescriptorSet.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.FileDescriptorSet.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.FileDescriptorSet} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FileDescriptorSet.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    fileList: jspb.Message.toObjectList(msg.getFileList(),
+    proto.google.protobuf.FileDescriptorProto.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.FileDescriptorSet}
+ */
+proto.google.protobuf.FileDescriptorSet.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.FileDescriptorSet;
+  return proto.google.protobuf.FileDescriptorSet.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.FileDescriptorSet} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.FileDescriptorSet}
+ */
+proto.google.protobuf.FileDescriptorSet.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.google.protobuf.FileDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.FileDescriptorProto.deserializeBinaryFromReader);
+      msg.addFile(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.FileDescriptorSet.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.FileDescriptorSet.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.FileDescriptorSet} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FileDescriptorSet.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFileList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.google.protobuf.FileDescriptorProto.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated FileDescriptorProto file = 1;
+ * @return {!Array<!proto.google.protobuf.FileDescriptorProto>}
+ */
+proto.google.protobuf.FileDescriptorSet.prototype.getFileList = function() {
+  return /** @type{!Array<!proto.google.protobuf.FileDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FileDescriptorProto, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.FileDescriptorProto>} value
+ * @return {!proto.google.protobuf.FileDescriptorSet} returns this
+*/
+proto.google.protobuf.FileDescriptorSet.prototype.setFileList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FileDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FileDescriptorProto}
+ */
+proto.google.protobuf.FileDescriptorSet.prototype.addFile = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.FileDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorSet} returns this
+ */
+proto.google.protobuf.FileDescriptorSet.prototype.clearFileList = function() {
+  return this.setFileList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.FileDescriptorProto.repeatedFields_ = [3,10,11,4,5,6,7];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.FileDescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.FileDescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FileDescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    pb_package: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    dependencyList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    publicDependencyList: (f = jspb.Message.getRepeatedField(msg, 10)) == null ? undefined : f,
+    weakDependencyList: (f = jspb.Message.getRepeatedField(msg, 11)) == null ? undefined : f,
+    messageTypeList: jspb.Message.toObjectList(msg.getMessageTypeList(),
+    proto.google.protobuf.DescriptorProto.toObject, includeInstance),
+    enumTypeList: jspb.Message.toObjectList(msg.getEnumTypeList(),
+    proto.google.protobuf.EnumDescriptorProto.toObject, includeInstance),
+    serviceList: jspb.Message.toObjectList(msg.getServiceList(),
+    proto.google.protobuf.ServiceDescriptorProto.toObject, includeInstance),
+    extensionList: jspb.Message.toObjectList(msg.getExtensionList(),
+    proto.google.protobuf.FieldDescriptorProto.toObject, includeInstance),
+    options: (f = msg.getOptions()) && proto.google.protobuf.FileOptions.toObject(includeInstance, f),
+    sourceCodeInfo: (f = msg.getSourceCodeInfo()) && proto.google.protobuf.SourceCodeInfo.toObject(includeInstance, f),
+    syntax: (f = jspb.Message.getField(msg, 12)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.FileDescriptorProto}
+ */
+proto.google.protobuf.FileDescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.FileDescriptorProto;
+  return proto.google.protobuf.FileDescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.FileDescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.FileDescriptorProto}
+ */
+proto.google.protobuf.FileDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPackage(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addDependency(value);
+      break;
+    case 10:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPublicDependency(values[i]);
+      }
+      break;
+    case 11:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addWeakDependency(values[i]);
+      }
+      break;
+    case 4:
+      var value = new proto.google.protobuf.DescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader);
+      msg.addMessageType(value);
+      break;
+    case 5:
+      var value = new proto.google.protobuf.EnumDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader);
+      msg.addEnumType(value);
+      break;
+    case 6:
+      var value = new proto.google.protobuf.ServiceDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.ServiceDescriptorProto.deserializeBinaryFromReader);
+      msg.addService(value);
+      break;
+    case 7:
+      var value = new proto.google.protobuf.FieldDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader);
+      msg.addExtension$(value);
+      break;
+    case 8:
+      var value = new proto.google.protobuf.FileOptions;
+      reader.readMessage(value,proto.google.protobuf.FileOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    case 9:
+      var value = new proto.google.protobuf.SourceCodeInfo;
+      reader.readMessage(value,proto.google.protobuf.SourceCodeInfo.deserializeBinaryFromReader);
+      msg.setSourceCodeInfo(value);
+      break;
+    case 12:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSyntax(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.FileDescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.FileDescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FileDescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getDependencyList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getPublicDependencyList();
+  if (f.length > 0) {
+    writer.writeRepeatedInt32(
+      10,
+      f
+    );
+  }
+  f = message.getWeakDependencyList();
+  if (f.length > 0) {
+    writer.writeRepeatedInt32(
+      11,
+      f
+    );
+  }
+  f = message.getMessageTypeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      4,
+      f,
+      proto.google.protobuf.DescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getEnumTypeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      5,
+      f,
+      proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getServiceList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.google.protobuf.ServiceDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getExtensionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      7,
+      f,
+      proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      8,
+      f,
+      proto.google.protobuf.FileOptions.serializeBinaryToWriter
+    );
+  }
+  f = message.getSourceCodeInfo();
+  if (f != null) {
+    writer.writeMessage(
+      9,
+      f,
+      proto.google.protobuf.SourceCodeInfo.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 12));
+  if (f != null) {
+    writer.writeString(
+      12,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string package = 2;
+ * @return {string}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getPackage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.setPackage = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearPackage = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.hasPackage = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * repeated string dependency = 3;
+ * @return {!Array<string>}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getDependencyList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.setDependencyList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.addDependency = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearDependencyList = function() {
+  return this.setDependencyList([]);
+};
+
+
+/**
+ * repeated int32 public_dependency = 10;
+ * @return {!Array<number>}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getPublicDependencyList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 10));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.setPublicDependencyList = function(value) {
+  return jspb.Message.setField(this, 10, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.addPublicDependency = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 10, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearPublicDependencyList = function() {
+  return this.setPublicDependencyList([]);
+};
+
+
+/**
+ * repeated int32 weak_dependency = 11;
+ * @return {!Array<number>}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getWeakDependencyList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 11));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.setWeakDependencyList = function(value) {
+  return jspb.Message.setField(this, 11, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.addWeakDependency = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 11, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearWeakDependencyList = function() {
+  return this.setWeakDependencyList([]);
+};
+
+
+/**
+ * repeated DescriptorProto message_type = 4;
+ * @return {!Array<!proto.google.protobuf.DescriptorProto>}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getMessageTypeList = function() {
+  return /** @type{!Array<!proto.google.protobuf.DescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto, 4));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.DescriptorProto>} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+*/
+proto.google.protobuf.FileDescriptorProto.prototype.setMessageTypeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 4, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.DescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.DescriptorProto}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.addMessageType = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.DescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearMessageTypeList = function() {
+  return this.setMessageTypeList([]);
+};
+
+
+/**
+ * repeated EnumDescriptorProto enum_type = 5;
+ * @return {!Array<!proto.google.protobuf.EnumDescriptorProto>}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getEnumTypeList = function() {
+  return /** @type{!Array<!proto.google.protobuf.EnumDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumDescriptorProto, 5));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.EnumDescriptorProto>} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+*/
+proto.google.protobuf.FileDescriptorProto.prototype.setEnumTypeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 5, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.EnumDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.EnumDescriptorProto}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.addEnumType = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.google.protobuf.EnumDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearEnumTypeList = function() {
+  return this.setEnumTypeList([]);
+};
+
+
+/**
+ * repeated ServiceDescriptorProto service = 6;
+ * @return {!Array<!proto.google.protobuf.ServiceDescriptorProto>}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getServiceList = function() {
+  return /** @type{!Array<!proto.google.protobuf.ServiceDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.ServiceDescriptorProto, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.ServiceDescriptorProto>} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+*/
+proto.google.protobuf.FileDescriptorProto.prototype.setServiceList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.ServiceDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.ServiceDescriptorProto}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.addService = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.ServiceDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearServiceList = function() {
+  return this.setServiceList([]);
+};
+
+
+/**
+ * repeated FieldDescriptorProto extension = 7;
+ * @return {!Array<!proto.google.protobuf.FieldDescriptorProto>}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getExtensionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.FieldDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FieldDescriptorProto, 7));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.FieldDescriptorProto>} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+*/
+proto.google.protobuf.FileDescriptorProto.prototype.setExtensionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 7, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FieldDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FieldDescriptorProto}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.addExtension$ = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 7, opt_value, proto.google.protobuf.FieldDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearExtensionList = function() {
+  return this.setExtensionList([]);
+};
+
+
+/**
+ * optional FileOptions options = 8;
+ * @return {?proto.google.protobuf.FileOptions}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.FileOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.FileOptions, 8));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.FileOptions|undefined} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+*/
+proto.google.protobuf.FileDescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 8, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 8) != null;
+};
+
+
+/**
+ * optional SourceCodeInfo source_code_info = 9;
+ * @return {?proto.google.protobuf.SourceCodeInfo}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getSourceCodeInfo = function() {
+  return /** @type{?proto.google.protobuf.SourceCodeInfo} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.SourceCodeInfo, 9));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.SourceCodeInfo|undefined} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+*/
+proto.google.protobuf.FileDescriptorProto.prototype.setSourceCodeInfo = function(value) {
+  return jspb.Message.setWrapperField(this, 9, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearSourceCodeInfo = function() {
+  return this.setSourceCodeInfo(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.hasSourceCodeInfo = function() {
+  return jspb.Message.getField(this, 9) != null;
+};
+
+
+/**
+ * optional string syntax = 12;
+ * @return {string}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.getSyntax = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 12, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.setSyntax = function(value) {
+  return jspb.Message.setField(this, 12, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileDescriptorProto} returns this
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.clearSyntax = function() {
+  return jspb.Message.setField(this, 12, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileDescriptorProto.prototype.hasSyntax = function() {
+  return jspb.Message.getField(this, 12) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.DescriptorProto.repeatedFields_ = [2,6,3,4,5,8,9,10];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.DescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.DescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.DescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    fieldList: jspb.Message.toObjectList(msg.getFieldList(),
+    proto.google.protobuf.FieldDescriptorProto.toObject, includeInstance),
+    extensionList: jspb.Message.toObjectList(msg.getExtensionList(),
+    proto.google.protobuf.FieldDescriptorProto.toObject, includeInstance),
+    nestedTypeList: jspb.Message.toObjectList(msg.getNestedTypeList(),
+    proto.google.protobuf.DescriptorProto.toObject, includeInstance),
+    enumTypeList: jspb.Message.toObjectList(msg.getEnumTypeList(),
+    proto.google.protobuf.EnumDescriptorProto.toObject, includeInstance),
+    extensionRangeList: jspb.Message.toObjectList(msg.getExtensionRangeList(),
+    proto.google.protobuf.DescriptorProto.ExtensionRange.toObject, includeInstance),
+    oneofDeclList: jspb.Message.toObjectList(msg.getOneofDeclList(),
+    proto.google.protobuf.OneofDescriptorProto.toObject, includeInstance),
+    options: (f = msg.getOptions()) && proto.google.protobuf.MessageOptions.toObject(includeInstance, f),
+    reservedRangeList: jspb.Message.toObjectList(msg.getReservedRangeList(),
+    proto.google.protobuf.DescriptorProto.ReservedRange.toObject, includeInstance),
+    reservedNameList: (f = jspb.Message.getRepeatedField(msg, 10)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.DescriptorProto}
+ */
+proto.google.protobuf.DescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.DescriptorProto;
+  return proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.DescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.DescriptorProto}
+ */
+proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new proto.google.protobuf.FieldDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader);
+      msg.addField(value);
+      break;
+    case 6:
+      var value = new proto.google.protobuf.FieldDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader);
+      msg.addExtension$(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.DescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.DescriptorProto.deserializeBinaryFromReader);
+      msg.addNestedType(value);
+      break;
+    case 4:
+      var value = new proto.google.protobuf.EnumDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader);
+      msg.addEnumType(value);
+      break;
+    case 5:
+      var value = new proto.google.protobuf.DescriptorProto.ExtensionRange;
+      reader.readMessage(value,proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinaryFromReader);
+      msg.addExtensionRange(value);
+      break;
+    case 8:
+      var value = new proto.google.protobuf.OneofDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.OneofDescriptorProto.deserializeBinaryFromReader);
+      msg.addOneofDecl(value);
+      break;
+    case 7:
+      var value = new proto.google.protobuf.MessageOptions;
+      reader.readMessage(value,proto.google.protobuf.MessageOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    case 9:
+      var value = new proto.google.protobuf.DescriptorProto.ReservedRange;
+      reader.readMessage(value,proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinaryFromReader);
+      msg.addReservedRange(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addReservedName(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.DescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.DescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.DescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFieldList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getExtensionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getNestedTypeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      3,
+      f,
+      proto.google.protobuf.DescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getEnumTypeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      4,
+      f,
+      proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getExtensionRangeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      5,
+      f,
+      proto.google.protobuf.DescriptorProto.ExtensionRange.serializeBinaryToWriter
+    );
+  }
+  f = message.getOneofDeclList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      8,
+      f,
+      proto.google.protobuf.OneofDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      7,
+      f,
+      proto.google.protobuf.MessageOptions.serializeBinaryToWriter
+    );
+  }
+  f = message.getReservedRangeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      9,
+      f,
+      proto.google.protobuf.DescriptorProto.ReservedRange.serializeBinaryToWriter
+    );
+  }
+  f = message.getReservedNameList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      10,
+      f
+    );
+  }
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.DescriptorProto.ExtensionRange.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    start: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    end: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    options: (f = msg.getOptions()) && proto.google.protobuf.ExtensionRangeOptions.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.DescriptorProto.ExtensionRange;
+  return proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setStart(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setEnd(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.ExtensionRangeOptions;
+      reader.readMessage(value,proto.google.protobuf.ExtensionRangeOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.DescriptorProto.ExtensionRange.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {number} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.google.protobuf.ExtensionRangeOptions.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional int32 start = 1;
+ * @return {number}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.getStart = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.setStart = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.clearStart = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.hasStart = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int32 end = 2;
+ * @return {number}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.getEnd = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.setEnd = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.clearEnd = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.hasEnd = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional ExtensionRangeOptions options = 3;
+ * @return {?proto.google.protobuf.ExtensionRangeOptions}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.ExtensionRangeOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.ExtensionRangeOptions, 3));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.ExtensionRangeOptions|undefined} value
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
+*/
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.DescriptorProto.ExtensionRange.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.DescriptorProto.ReservedRange.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.DescriptorProto.ReservedRange} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    start: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    end: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.DescriptorProto.ReservedRange}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.DescriptorProto.ReservedRange;
+  return proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.DescriptorProto.ReservedRange} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.DescriptorProto.ReservedRange}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setStart(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setEnd(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.DescriptorProto.ReservedRange.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.DescriptorProto.ReservedRange} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {number} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 start = 1;
+ * @return {number}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.getStart = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.setStart = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.clearStart = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.hasStart = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int32 end = 2;
+ * @return {number}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.getEnd = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.setEnd = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.DescriptorProto.ReservedRange} returns this
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.clearEnd = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.DescriptorProto.ReservedRange.prototype.hasEnd = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.DescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * repeated FieldDescriptorProto field = 2;
+ * @return {!Array<!proto.google.protobuf.FieldDescriptorProto>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getFieldList = function() {
+  return /** @type{!Array<!proto.google.protobuf.FieldDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FieldDescriptorProto, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.FieldDescriptorProto>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setFieldList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FieldDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FieldDescriptorProto}
+ */
+proto.google.protobuf.DescriptorProto.prototype.addField = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.FieldDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearFieldList = function() {
+  return this.setFieldList([]);
+};
+
+
+/**
+ * repeated FieldDescriptorProto extension = 6;
+ * @return {!Array<!proto.google.protobuf.FieldDescriptorProto>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getExtensionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.FieldDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.FieldDescriptorProto, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.FieldDescriptorProto>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setExtensionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FieldDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FieldDescriptorProto}
+ */
+proto.google.protobuf.DescriptorProto.prototype.addExtension$ = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.google.protobuf.FieldDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearExtensionList = function() {
+  return this.setExtensionList([]);
+};
+
+
+/**
+ * repeated DescriptorProto nested_type = 3;
+ * @return {!Array<!proto.google.protobuf.DescriptorProto>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getNestedTypeList = function() {
+  return /** @type{!Array<!proto.google.protobuf.DescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto, 3));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.DescriptorProto>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setNestedTypeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 3, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.DescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.DescriptorProto}
+ */
+proto.google.protobuf.DescriptorProto.prototype.addNestedType = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.DescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearNestedTypeList = function() {
+  return this.setNestedTypeList([]);
+};
+
+
+/**
+ * repeated EnumDescriptorProto enum_type = 4;
+ * @return {!Array<!proto.google.protobuf.EnumDescriptorProto>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getEnumTypeList = function() {
+  return /** @type{!Array<!proto.google.protobuf.EnumDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumDescriptorProto, 4));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.EnumDescriptorProto>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setEnumTypeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 4, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.EnumDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.EnumDescriptorProto}
+ */
+proto.google.protobuf.DescriptorProto.prototype.addEnumType = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.EnumDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearEnumTypeList = function() {
+  return this.setEnumTypeList([]);
+};
+
+
+/**
+ * repeated ExtensionRange extension_range = 5;
+ * @return {!Array<!proto.google.protobuf.DescriptorProto.ExtensionRange>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getExtensionRangeList = function() {
+  return /** @type{!Array<!proto.google.protobuf.DescriptorProto.ExtensionRange>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto.ExtensionRange, 5));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.DescriptorProto.ExtensionRange>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setExtensionRangeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 5, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.DescriptorProto.ExtensionRange=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.DescriptorProto.ExtensionRange}
+ */
+proto.google.protobuf.DescriptorProto.prototype.addExtensionRange = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.google.protobuf.DescriptorProto.ExtensionRange, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearExtensionRangeList = function() {
+  return this.setExtensionRangeList([]);
+};
+
+
+/**
+ * repeated OneofDescriptorProto oneof_decl = 8;
+ * @return {!Array<!proto.google.protobuf.OneofDescriptorProto>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getOneofDeclList = function() {
+  return /** @type{!Array<!proto.google.protobuf.OneofDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.OneofDescriptorProto, 8));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.OneofDescriptorProto>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setOneofDeclList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 8, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.OneofDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.OneofDescriptorProto}
+ */
+proto.google.protobuf.DescriptorProto.prototype.addOneofDecl = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 8, opt_value, proto.google.protobuf.OneofDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearOneofDeclList = function() {
+  return this.setOneofDeclList([]);
+};
+
+
+/**
+ * optional MessageOptions options = 7;
+ * @return {?proto.google.protobuf.MessageOptions}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.MessageOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.MessageOptions, 7));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.MessageOptions|undefined} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 7, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.DescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+/**
+ * repeated ReservedRange reserved_range = 9;
+ * @return {!Array<!proto.google.protobuf.DescriptorProto.ReservedRange>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getReservedRangeList = function() {
+  return /** @type{!Array<!proto.google.protobuf.DescriptorProto.ReservedRange>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.DescriptorProto.ReservedRange, 9));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.DescriptorProto.ReservedRange>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+*/
+proto.google.protobuf.DescriptorProto.prototype.setReservedRangeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 9, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.DescriptorProto.ReservedRange=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.DescriptorProto.ReservedRange}
+ */
+proto.google.protobuf.DescriptorProto.prototype.addReservedRange = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.google.protobuf.DescriptorProto.ReservedRange, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearReservedRangeList = function() {
+  return this.setReservedRangeList([]);
+};
+
+
+/**
+ * repeated string reserved_name = 10;
+ * @return {!Array<string>}
+ */
+proto.google.protobuf.DescriptorProto.prototype.getReservedNameList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 10));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.setReservedNameList = function(value) {
+  return jspb.Message.setField(this, 10, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.addReservedName = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 10, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.DescriptorProto} returns this
+ */
+proto.google.protobuf.DescriptorProto.prototype.clearReservedNameList = function() {
+  return this.setReservedNameList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.ExtensionRangeOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.ExtensionRangeOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.ExtensionRangeOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.ExtensionRangeOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ExtensionRangeOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.ExtensionRangeOptions.extensions, proto.google.protobuf.ExtensionRangeOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.ExtensionRangeOptions}
+ */
+proto.google.protobuf.ExtensionRangeOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.ExtensionRangeOptions;
+  return proto.google.protobuf.ExtensionRangeOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.ExtensionRangeOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.ExtensionRangeOptions}
+ */
+proto.google.protobuf.ExtensionRangeOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.ExtensionRangeOptions.extensionsBinary,
+        proto.google.protobuf.ExtensionRangeOptions.prototype.getExtension,
+        proto.google.protobuf.ExtensionRangeOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.ExtensionRangeOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.ExtensionRangeOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.ExtensionRangeOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ExtensionRangeOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.ExtensionRangeOptions.extensionsBinary, proto.google.protobuf.ExtensionRangeOptions.prototype.getExtension);
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.ExtensionRangeOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.ExtensionRangeOptions} returns this
+*/
+proto.google.protobuf.ExtensionRangeOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.ExtensionRangeOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.ExtensionRangeOptions} returns this
+ */
+proto.google.protobuf.ExtensionRangeOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.FieldDescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.FieldDescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FieldDescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    number: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    label: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    type: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
+    typeName: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f,
+    extendee: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    defaultValue: (f = jspb.Message.getField(msg, 7)) == null ? undefined : f,
+    oneofIndex: (f = jspb.Message.getField(msg, 9)) == null ? undefined : f,
+    jsonName: (f = jspb.Message.getField(msg, 10)) == null ? undefined : f,
+    options: (f = msg.getOptions()) && proto.google.protobuf.FieldOptions.toObject(includeInstance, f),
+    proto3Optional: (f = jspb.Message.getBooleanField(msg, 17)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.FieldDescriptorProto}
+ */
+proto.google.protobuf.FieldDescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.FieldDescriptorProto;
+  return proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.FieldDescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.FieldDescriptorProto}
+ */
+proto.google.protobuf.FieldDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setNumber(value);
+      break;
+    case 4:
+      var value = /** @type {!proto.google.protobuf.FieldDescriptorProto.Label} */ (reader.readEnum());
+      msg.setLabel(value);
+      break;
+    case 5:
+      var value = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTypeName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setExtendee(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDefaultValue(value);
+      break;
+    case 9:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setOneofIndex(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setJsonName(value);
+      break;
+    case 8:
+      var value = new proto.google.protobuf.FieldOptions;
+      reader.readMessage(value,proto.google.protobuf.FieldOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    case 17:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setProto3Optional(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.FieldDescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FieldDescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeInt32(
+      3,
+      f
+    );
+  }
+  f = /** @type {!proto.google.protobuf.FieldDescriptorProto.Label} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeEnum(
+      4,
+      f
+    );
+  }
+  f = /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeEnum(
+      5,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 6));
+  if (f != null) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 7));
+  if (f != null) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 9));
+  if (f != null) {
+    writer.writeInt32(
+      9,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 10));
+  if (f != null) {
+    writer.writeString(
+      10,
+      f
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      8,
+      f,
+      proto.google.protobuf.FieldOptions.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 17));
+  if (f != null) {
+    writer.writeBool(
+      17,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.FieldDescriptorProto.Type = {
+  TYPE_DOUBLE: 1,
+  TYPE_FLOAT: 2,
+  TYPE_INT64: 3,
+  TYPE_UINT64: 4,
+  TYPE_INT32: 5,
+  TYPE_FIXED64: 6,
+  TYPE_FIXED32: 7,
+  TYPE_BOOL: 8,
+  TYPE_STRING: 9,
+  TYPE_GROUP: 10,
+  TYPE_MESSAGE: 11,
+  TYPE_BYTES: 12,
+  TYPE_UINT32: 13,
+  TYPE_ENUM: 14,
+  TYPE_SFIXED32: 15,
+  TYPE_SFIXED64: 16,
+  TYPE_SINT32: 17,
+  TYPE_SINT64: 18
+};
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.FieldDescriptorProto.Label = {
+  LABEL_OPTIONAL: 1,
+  LABEL_REQUIRED: 2,
+  LABEL_REPEATED: 3
+};
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int32 number = 3;
+ * @return {number}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getNumber = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setNumber = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearNumber = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasNumber = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional Label label = 4;
+ * @return {!proto.google.protobuf.FieldDescriptorProto.Label}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getLabel = function() {
+  return /** @type {!proto.google.protobuf.FieldDescriptorProto.Label} */ (jspb.Message.getFieldWithDefault(this, 4, 1));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FieldDescriptorProto.Label} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setLabel = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearLabel = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasLabel = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional Type type = 5;
+ * @return {!proto.google.protobuf.FieldDescriptorProto.Type}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getType = function() {
+  return /** @type {!proto.google.protobuf.FieldDescriptorProto.Type} */ (jspb.Message.getFieldWithDefault(this, 5, 1));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FieldDescriptorProto.Type} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setType = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearType = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasType = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional string type_name = 6;
+ * @return {string}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getTypeName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setTypeName = function(value) {
+  return jspb.Message.setField(this, 6, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearTypeName = function() {
+  return jspb.Message.setField(this, 6, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasTypeName = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional string extendee = 2;
+ * @return {string}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getExtendee = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setExtendee = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearExtendee = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasExtendee = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string default_value = 7;
+ * @return {string}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getDefaultValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setDefaultValue = function(value) {
+  return jspb.Message.setField(this, 7, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearDefaultValue = function() {
+  return jspb.Message.setField(this, 7, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasDefaultValue = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+/**
+ * optional int32 oneof_index = 9;
+ * @return {number}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getOneofIndex = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setOneofIndex = function(value) {
+  return jspb.Message.setField(this, 9, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearOneofIndex = function() {
+  return jspb.Message.setField(this, 9, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasOneofIndex = function() {
+  return jspb.Message.getField(this, 9) != null;
+};
+
+
+/**
+ * optional string json_name = 10;
+ * @return {string}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getJsonName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setJsonName = function(value) {
+  return jspb.Message.setField(this, 10, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearJsonName = function() {
+  return jspb.Message.setField(this, 10, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasJsonName = function() {
+  return jspb.Message.getField(this, 10) != null;
+};
+
+
+/**
+ * optional FieldOptions options = 8;
+ * @return {?proto.google.protobuf.FieldOptions}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.FieldOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.FieldOptions, 8));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.FieldOptions|undefined} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+*/
+proto.google.protobuf.FieldDescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 8, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 8) != null;
+};
+
+
+/**
+ * optional bool proto3_optional = 17;
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.getProto3Optional = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 17, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.setProto3Optional = function(value) {
+  return jspb.Message.setField(this, 17, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldDescriptorProto} returns this
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.clearProto3Optional = function() {
+  return jspb.Message.setField(this, 17, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldDescriptorProto.prototype.hasProto3Optional = function() {
+  return jspb.Message.getField(this, 17) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.OneofDescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.OneofDescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.OneofDescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    options: (f = msg.getOptions()) && proto.google.protobuf.OneofOptions.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.OneofDescriptorProto}
+ */
+proto.google.protobuf.OneofDescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.OneofDescriptorProto;
+  return proto.google.protobuf.OneofDescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.OneofDescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.OneofDescriptorProto}
+ */
+proto.google.protobuf.OneofDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new proto.google.protobuf.OneofOptions;
+      reader.readMessage(value,proto.google.protobuf.OneofOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.OneofDescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.OneofDescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.OneofDescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.google.protobuf.OneofOptions.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional OneofOptions options = 2;
+ * @return {?proto.google.protobuf.OneofOptions}
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.OneofOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.OneofOptions, 2));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.OneofOptions|undefined} value
+ * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
+*/
+proto.google.protobuf.OneofDescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.OneofDescriptorProto} returns this
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.OneofDescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.EnumDescriptorProto.repeatedFields_ = [2,4,5];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.EnumDescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.EnumDescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumDescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    valueList: jspb.Message.toObjectList(msg.getValueList(),
+    proto.google.protobuf.EnumValueDescriptorProto.toObject, includeInstance),
+    options: (f = msg.getOptions()) && proto.google.protobuf.EnumOptions.toObject(includeInstance, f),
+    reservedRangeList: jspb.Message.toObjectList(msg.getReservedRangeList(),
+    proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.toObject, includeInstance),
+    reservedNameList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.EnumDescriptorProto}
+ */
+proto.google.protobuf.EnumDescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.EnumDescriptorProto;
+  return proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.EnumDescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.EnumDescriptorProto}
+ */
+proto.google.protobuf.EnumDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new proto.google.protobuf.EnumValueDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.EnumValueDescriptorProto.deserializeBinaryFromReader);
+      msg.addValue(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.EnumOptions;
+      reader.readMessage(value,proto.google.protobuf.EnumOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    case 4:
+      var value = new proto.google.protobuf.EnumDescriptorProto.EnumReservedRange;
+      reader.readMessage(value,proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinaryFromReader);
+      msg.addReservedRange(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addReservedName(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.EnumDescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumDescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getValueList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.google.protobuf.EnumValueDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.google.protobuf.EnumOptions.serializeBinaryToWriter
+    );
+  }
+  f = message.getReservedRangeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      4,
+      f,
+      proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.serializeBinaryToWriter
+    );
+  }
+  f = message.getReservedNameList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      5,
+      f
+    );
+  }
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    start: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    end: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.EnumDescriptorProto.EnumReservedRange;
+  return proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setStart(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setEnd(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {number} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 start = 1;
+ * @return {number}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.getStart = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.setStart = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.clearStart = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.hasStart = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int32 end = 2;
+ * @return {number}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.getEnd = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.setEnd = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.clearEnd = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumDescriptorProto.EnumReservedRange.prototype.hasEnd = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * repeated EnumValueDescriptorProto value = 2;
+ * @return {!Array<!proto.google.protobuf.EnumValueDescriptorProto>}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.getValueList = function() {
+  return /** @type{!Array<!proto.google.protobuf.EnumValueDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumValueDescriptorProto, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.EnumValueDescriptorProto>} value
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+*/
+proto.google.protobuf.EnumDescriptorProto.prototype.setValueList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.EnumValueDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.addValue = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.EnumValueDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.clearValueList = function() {
+  return this.setValueList([]);
+};
+
+
+/**
+ * optional EnumOptions options = 3;
+ * @return {?proto.google.protobuf.EnumOptions}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.EnumOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.EnumOptions, 3));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.EnumOptions|undefined} value
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+*/
+proto.google.protobuf.EnumDescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * repeated EnumReservedRange reserved_range = 4;
+ * @return {!Array<!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange>}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.getReservedRangeList = function() {
+  return /** @type{!Array<!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumDescriptorProto.EnumReservedRange, 4));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange>} value
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+*/
+proto.google.protobuf.EnumDescriptorProto.prototype.setReservedRangeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 4, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.EnumDescriptorProto.EnumReservedRange}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.addReservedRange = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.EnumDescriptorProto.EnumReservedRange, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.clearReservedRangeList = function() {
+  return this.setReservedRangeList([]);
+};
+
+
+/**
+ * repeated string reserved_name = 5;
+ * @return {!Array<string>}
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.getReservedNameList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.setReservedNameList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.addReservedName = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.EnumDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumDescriptorProto.prototype.clearReservedNameList = function() {
+  return this.setReservedNameList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.EnumValueDescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.EnumValueDescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumValueDescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    number: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    options: (f = msg.getOptions()) && proto.google.protobuf.EnumValueOptions.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.EnumValueDescriptorProto;
+  return proto.google.protobuf.EnumValueDescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.EnumValueDescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setNumber(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.EnumValueOptions;
+      reader.readMessage(value,proto.google.protobuf.EnumValueOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.EnumValueDescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.EnumValueDescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumValueDescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.google.protobuf.EnumValueOptions.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional int32 number = 2;
+ * @return {number}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.getNumber = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.setNumber = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.clearNumber = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.hasNumber = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional EnumValueOptions options = 3;
+ * @return {?proto.google.protobuf.EnumValueOptions}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.EnumValueOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.EnumValueOptions, 3));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.EnumValueOptions|undefined} value
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
+*/
+proto.google.protobuf.EnumValueDescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.EnumValueDescriptorProto} returns this
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumValueDescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.ServiceDescriptorProto.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.ServiceDescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.ServiceDescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ServiceDescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    methodList: jspb.Message.toObjectList(msg.getMethodList(),
+    proto.google.protobuf.MethodDescriptorProto.toObject, includeInstance),
+    options: (f = msg.getOptions()) && proto.google.protobuf.ServiceOptions.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.ServiceDescriptorProto}
+ */
+proto.google.protobuf.ServiceDescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.ServiceDescriptorProto;
+  return proto.google.protobuf.ServiceDescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.ServiceDescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.ServiceDescriptorProto}
+ */
+proto.google.protobuf.ServiceDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new proto.google.protobuf.MethodDescriptorProto;
+      reader.readMessage(value,proto.google.protobuf.MethodDescriptorProto.deserializeBinaryFromReader);
+      msg.addMethod(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.ServiceOptions;
+      reader.readMessage(value,proto.google.protobuf.ServiceOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.ServiceDescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.ServiceDescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ServiceDescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getMethodList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.google.protobuf.MethodDescriptorProto.serializeBinaryToWriter
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.google.protobuf.ServiceOptions.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * repeated MethodDescriptorProto method = 2;
+ * @return {!Array<!proto.google.protobuf.MethodDescriptorProto>}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.getMethodList = function() {
+  return /** @type{!Array<!proto.google.protobuf.MethodDescriptorProto>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.MethodDescriptorProto, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.MethodDescriptorProto>} value
+ * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
+*/
+proto.google.protobuf.ServiceDescriptorProto.prototype.setMethodList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.MethodDescriptorProto=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.MethodDescriptorProto}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.addMethod = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.MethodDescriptorProto, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.clearMethodList = function() {
+  return this.setMethodList([]);
+};
+
+
+/**
+ * optional ServiceOptions options = 3;
+ * @return {?proto.google.protobuf.ServiceOptions}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.ServiceOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.ServiceOptions, 3));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.ServiceOptions|undefined} value
+ * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
+*/
+proto.google.protobuf.ServiceDescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.ServiceDescriptorProto} returns this
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.ServiceDescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.MethodDescriptorProto.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.MethodDescriptorProto} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.MethodDescriptorProto.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    inputType: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    outputType: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    options: (f = msg.getOptions()) && proto.google.protobuf.MethodOptions.toObject(includeInstance, f),
+    clientStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
+    serverStreaming: jspb.Message.getBooleanFieldWithDefault(msg, 6, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.MethodDescriptorProto}
+ */
+proto.google.protobuf.MethodDescriptorProto.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.MethodDescriptorProto;
+  return proto.google.protobuf.MethodDescriptorProto.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.MethodDescriptorProto} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.MethodDescriptorProto}
+ */
+proto.google.protobuf.MethodDescriptorProto.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInputType(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setOutputType(value);
+      break;
+    case 4:
+      var value = new proto.google.protobuf.MethodOptions;
+      reader.readMessage(value,proto.google.protobuf.MethodOptions.deserializeBinaryFromReader);
+      msg.setOptions(value);
+      break;
+    case 5:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setClientStreaming(value);
+      break;
+    case 6:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setServerStreaming(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.MethodDescriptorProto.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.MethodDescriptorProto} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.MethodDescriptorProto.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getOptions();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      proto.google.protobuf.MethodOptions.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeBool(
+      5,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 6));
+  if (f != null) {
+    writer.writeBool(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string input_type = 2;
+ * @return {string}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.getInputType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.setInputType = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.clearInputType = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.hasInputType = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string output_type = 3;
+ * @return {string}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.getOutputType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.setOutputType = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.clearOutputType = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.hasOutputType = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional MethodOptions options = 4;
+ * @return {?proto.google.protobuf.MethodOptions}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.getOptions = function() {
+  return /** @type{?proto.google.protobuf.MethodOptions} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.MethodOptions, 4));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.MethodOptions|undefined} value
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+*/
+proto.google.protobuf.MethodDescriptorProto.prototype.setOptions = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.clearOptions = function() {
+  return this.setOptions(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.hasOptions = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional bool client_streaming = 5;
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.getClientStreaming = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.setClientStreaming = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.clearClientStreaming = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.hasClientStreaming = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional bool server_streaming = 6;
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.getServerStreaming = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.setServerStreaming = function(value) {
+  return jspb.Message.setField(this, 6, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MethodDescriptorProto} returns this
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.clearServerStreaming = function() {
+  return jspb.Message.setField(this, 6, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodDescriptorProto.prototype.hasServerStreaming = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.FileOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.FileOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.FileOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.FileOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FileOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    javaPackage: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    javaOuterClassname: (f = jspb.Message.getField(msg, 8)) == null ? undefined : f,
+    javaMultipleFiles: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),
+    javaGenerateEqualsAndHash: (f = jspb.Message.getBooleanField(msg, 20)) == null ? undefined : f,
+    javaStringCheckUtf8: jspb.Message.getBooleanFieldWithDefault(msg, 27, false),
+    optimizeFor: jspb.Message.getFieldWithDefault(msg, 9, 1),
+    goPackage: (f = jspb.Message.getField(msg, 11)) == null ? undefined : f,
+    ccGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 16, false),
+    javaGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 17, false),
+    pyGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 18, false),
+    phpGenericServices: jspb.Message.getBooleanFieldWithDefault(msg, 42, false),
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 23, false),
+    ccEnableArenas: jspb.Message.getBooleanFieldWithDefault(msg, 31, true),
+    objcClassPrefix: (f = jspb.Message.getField(msg, 36)) == null ? undefined : f,
+    csharpNamespace: (f = jspb.Message.getField(msg, 37)) == null ? undefined : f,
+    swiftPrefix: (f = jspb.Message.getField(msg, 39)) == null ? undefined : f,
+    phpClassPrefix: (f = jspb.Message.getField(msg, 40)) == null ? undefined : f,
+    phpNamespace: (f = jspb.Message.getField(msg, 41)) == null ? undefined : f,
+    phpMetadataNamespace: (f = jspb.Message.getField(msg, 44)) == null ? undefined : f,
+    rubyPackage: (f = jspb.Message.getField(msg, 45)) == null ? undefined : f,
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.FileOptions.extensions, proto.google.protobuf.FileOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.FileOptions}
+ */
+proto.google.protobuf.FileOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.FileOptions;
+  return proto.google.protobuf.FileOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.FileOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.FileOptions}
+ */
+proto.google.protobuf.FileOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setJavaPackage(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setJavaOuterClassname(value);
+      break;
+    case 10:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setJavaMultipleFiles(value);
+      break;
+    case 20:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setJavaGenerateEqualsAndHash(value);
+      break;
+    case 27:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setJavaStringCheckUtf8(value);
+      break;
+    case 9:
+      var value = /** @type {!proto.google.protobuf.FileOptions.OptimizeMode} */ (reader.readEnum());
+      msg.setOptimizeFor(value);
+      break;
+    case 11:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGoPackage(value);
+      break;
+    case 16:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setCcGenericServices(value);
+      break;
+    case 17:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setJavaGenericServices(value);
+      break;
+    case 18:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setPyGenericServices(value);
+      break;
+    case 42:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setPhpGenericServices(value);
+      break;
+    case 23:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 31:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setCcEnableArenas(value);
+      break;
+    case 36:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setObjcClassPrefix(value);
+      break;
+    case 37:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCsharpNamespace(value);
+      break;
+    case 39:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSwiftPrefix(value);
+      break;
+    case 40:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPhpClassPrefix(value);
+      break;
+    case 41:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPhpNamespace(value);
+      break;
+    case 44:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPhpMetadataNamespace(value);
+      break;
+    case 45:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setRubyPackage(value);
+      break;
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.FileOptions.extensionsBinary,
+        proto.google.protobuf.FileOptions.prototype.getExtension,
+        proto.google.protobuf.FileOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.FileOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.FileOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.FileOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FileOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 8));
+  if (f != null) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 10));
+  if (f != null) {
+    writer.writeBool(
+      10,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 20));
+  if (f != null) {
+    writer.writeBool(
+      20,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 27));
+  if (f != null) {
+    writer.writeBool(
+      27,
+      f
+    );
+  }
+  f = /** @type {!proto.google.protobuf.FileOptions.OptimizeMode} */ (jspb.Message.getField(message, 9));
+  if (f != null) {
+    writer.writeEnum(
+      9,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 11));
+  if (f != null) {
+    writer.writeString(
+      11,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 16));
+  if (f != null) {
+    writer.writeBool(
+      16,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 17));
+  if (f != null) {
+    writer.writeBool(
+      17,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 18));
+  if (f != null) {
+    writer.writeBool(
+      18,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 42));
+  if (f != null) {
+    writer.writeBool(
+      42,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 23));
+  if (f != null) {
+    writer.writeBool(
+      23,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 31));
+  if (f != null) {
+    writer.writeBool(
+      31,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 36));
+  if (f != null) {
+    writer.writeString(
+      36,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 37));
+  if (f != null) {
+    writer.writeString(
+      37,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 39));
+  if (f != null) {
+    writer.writeString(
+      39,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 40));
+  if (f != null) {
+    writer.writeString(
+      40,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 41));
+  if (f != null) {
+    writer.writeString(
+      41,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 44));
+  if (f != null) {
+    writer.writeString(
+      44,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 45));
+  if (f != null) {
+    writer.writeString(
+      45,
+      f
+    );
+  }
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.FileOptions.extensionsBinary, proto.google.protobuf.FileOptions.prototype.getExtension);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.FileOptions.OptimizeMode = {
+  SPEED: 1,
+  CODE_SIZE: 2,
+  LITE_RUNTIME: 3
+};
+
+/**
+ * optional string java_package = 1;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getJavaPackage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setJavaPackage = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearJavaPackage = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasJavaPackage = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string java_outer_classname = 8;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getJavaOuterClassname = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setJavaOuterClassname = function(value) {
+  return jspb.Message.setField(this, 8, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearJavaOuterClassname = function() {
+  return jspb.Message.setField(this, 8, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasJavaOuterClassname = function() {
+  return jspb.Message.getField(this, 8) != null;
+};
+
+
+/**
+ * optional bool java_multiple_files = 10;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getJavaMultipleFiles = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setJavaMultipleFiles = function(value) {
+  return jspb.Message.setField(this, 10, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearJavaMultipleFiles = function() {
+  return jspb.Message.setField(this, 10, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasJavaMultipleFiles = function() {
+  return jspb.Message.getField(this, 10) != null;
+};
+
+
+/**
+ * optional bool java_generate_equals_and_hash = 20;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getJavaGenerateEqualsAndHash = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 20, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setJavaGenerateEqualsAndHash = function(value) {
+  return jspb.Message.setField(this, 20, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearJavaGenerateEqualsAndHash = function() {
+  return jspb.Message.setField(this, 20, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasJavaGenerateEqualsAndHash = function() {
+  return jspb.Message.getField(this, 20) != null;
+};
+
+
+/**
+ * optional bool java_string_check_utf8 = 27;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getJavaStringCheckUtf8 = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 27, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setJavaStringCheckUtf8 = function(value) {
+  return jspb.Message.setField(this, 27, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearJavaStringCheckUtf8 = function() {
+  return jspb.Message.setField(this, 27, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasJavaStringCheckUtf8 = function() {
+  return jspb.Message.getField(this, 27) != null;
+};
+
+
+/**
+ * optional OptimizeMode optimize_for = 9;
+ * @return {!proto.google.protobuf.FileOptions.OptimizeMode}
+ */
+proto.google.protobuf.FileOptions.prototype.getOptimizeFor = function() {
+  return /** @type {!proto.google.protobuf.FileOptions.OptimizeMode} */ (jspb.Message.getFieldWithDefault(this, 9, 1));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FileOptions.OptimizeMode} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setOptimizeFor = function(value) {
+  return jspb.Message.setField(this, 9, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearOptimizeFor = function() {
+  return jspb.Message.setField(this, 9, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasOptimizeFor = function() {
+  return jspb.Message.getField(this, 9) != null;
+};
+
+
+/**
+ * optional string go_package = 11;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getGoPackage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setGoPackage = function(value) {
+  return jspb.Message.setField(this, 11, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearGoPackage = function() {
+  return jspb.Message.setField(this, 11, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasGoPackage = function() {
+  return jspb.Message.getField(this, 11) != null;
+};
+
+
+/**
+ * optional bool cc_generic_services = 16;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getCcGenericServices = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 16, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setCcGenericServices = function(value) {
+  return jspb.Message.setField(this, 16, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearCcGenericServices = function() {
+  return jspb.Message.setField(this, 16, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasCcGenericServices = function() {
+  return jspb.Message.getField(this, 16) != null;
+};
+
+
+/**
+ * optional bool java_generic_services = 17;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getJavaGenericServices = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 17, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setJavaGenericServices = function(value) {
+  return jspb.Message.setField(this, 17, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearJavaGenericServices = function() {
+  return jspb.Message.setField(this, 17, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasJavaGenericServices = function() {
+  return jspb.Message.getField(this, 17) != null;
+};
+
+
+/**
+ * optional bool py_generic_services = 18;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getPyGenericServices = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 18, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setPyGenericServices = function(value) {
+  return jspb.Message.setField(this, 18, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearPyGenericServices = function() {
+  return jspb.Message.setField(this, 18, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasPyGenericServices = function() {
+  return jspb.Message.getField(this, 18) != null;
+};
+
+
+/**
+ * optional bool php_generic_services = 42;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getPhpGenericServices = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 42, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setPhpGenericServices = function(value) {
+  return jspb.Message.setField(this, 42, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearPhpGenericServices = function() {
+  return jspb.Message.setField(this, 42, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasPhpGenericServices = function() {
+  return jspb.Message.getField(this, 42) != null;
+};
+
+
+/**
+ * optional bool deprecated = 23;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 23, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setDeprecated = function(value) {
+  return jspb.Message.setField(this, 23, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearDeprecated = function() {
+  return jspb.Message.setField(this, 23, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasDeprecated = function() {
+  return jspb.Message.getField(this, 23) != null;
+};
+
+
+/**
+ * optional bool cc_enable_arenas = 31;
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.getCcEnableArenas = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 31, true));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setCcEnableArenas = function(value) {
+  return jspb.Message.setField(this, 31, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearCcEnableArenas = function() {
+  return jspb.Message.setField(this, 31, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasCcEnableArenas = function() {
+  return jspb.Message.getField(this, 31) != null;
+};
+
+
+/**
+ * optional string objc_class_prefix = 36;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getObjcClassPrefix = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 36, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setObjcClassPrefix = function(value) {
+  return jspb.Message.setField(this, 36, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearObjcClassPrefix = function() {
+  return jspb.Message.setField(this, 36, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasObjcClassPrefix = function() {
+  return jspb.Message.getField(this, 36) != null;
+};
+
+
+/**
+ * optional string csharp_namespace = 37;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getCsharpNamespace = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 37, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setCsharpNamespace = function(value) {
+  return jspb.Message.setField(this, 37, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearCsharpNamespace = function() {
+  return jspb.Message.setField(this, 37, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasCsharpNamespace = function() {
+  return jspb.Message.getField(this, 37) != null;
+};
+
+
+/**
+ * optional string swift_prefix = 39;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getSwiftPrefix = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 39, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setSwiftPrefix = function(value) {
+  return jspb.Message.setField(this, 39, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearSwiftPrefix = function() {
+  return jspb.Message.setField(this, 39, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasSwiftPrefix = function() {
+  return jspb.Message.getField(this, 39) != null;
+};
+
+
+/**
+ * optional string php_class_prefix = 40;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getPhpClassPrefix = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 40, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setPhpClassPrefix = function(value) {
+  return jspb.Message.setField(this, 40, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearPhpClassPrefix = function() {
+  return jspb.Message.setField(this, 40, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasPhpClassPrefix = function() {
+  return jspb.Message.getField(this, 40) != null;
+};
+
+
+/**
+ * optional string php_namespace = 41;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getPhpNamespace = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 41, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setPhpNamespace = function(value) {
+  return jspb.Message.setField(this, 41, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearPhpNamespace = function() {
+  return jspb.Message.setField(this, 41, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasPhpNamespace = function() {
+  return jspb.Message.getField(this, 41) != null;
+};
+
+
+/**
+ * optional string php_metadata_namespace = 44;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getPhpMetadataNamespace = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 44, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setPhpMetadataNamespace = function(value) {
+  return jspb.Message.setField(this, 44, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearPhpMetadataNamespace = function() {
+  return jspb.Message.setField(this, 44, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasPhpMetadataNamespace = function() {
+  return jspb.Message.getField(this, 44) != null;
+};
+
+
+/**
+ * optional string ruby_package = 45;
+ * @return {string}
+ */
+proto.google.protobuf.FileOptions.prototype.getRubyPackage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 45, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.setRubyPackage = function(value) {
+  return jspb.Message.setField(this, 45, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearRubyPackage = function() {
+  return jspb.Message.setField(this, 45, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FileOptions.prototype.hasRubyPackage = function() {
+  return jspb.Message.getField(this, 45) != null;
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.FileOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.FileOptions} returns this
+*/
+proto.google.protobuf.FileOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.FileOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FileOptions} returns this
+ */
+proto.google.protobuf.FileOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.MessageOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.MessageOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.MessageOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.MessageOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.MessageOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    messageSetWireFormat: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
+    noStandardDescriptorAccessor: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
+    mapEntry: (f = jspb.Message.getBooleanField(msg, 7)) == null ? undefined : f,
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.MessageOptions.extensions, proto.google.protobuf.MessageOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.MessageOptions}
+ */
+proto.google.protobuf.MessageOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.MessageOptions;
+  return proto.google.protobuf.MessageOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.MessageOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.MessageOptions}
+ */
+proto.google.protobuf.MessageOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setMessageSetWireFormat(value);
+      break;
+    case 2:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setNoStandardDescriptorAccessor(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 7:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setMapEntry(value);
+      break;
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.MessageOptions.extensionsBinary,
+        proto.google.protobuf.MessageOptions.prototype.getExtension,
+        proto.google.protobuf.MessageOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.MessageOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.MessageOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.MessageOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.MessageOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeBool(
+      2,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 7));
+  if (f != null) {
+    writer.writeBool(
+      7,
+      f
+    );
+  }
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.MessageOptions.extensionsBinary, proto.google.protobuf.MessageOptions.prototype.getExtension);
+};
+
+
+/**
+ * optional bool message_set_wire_format = 1;
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.getMessageSetWireFormat = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.setMessageSetWireFormat = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.clearMessageSetWireFormat = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.hasMessageSetWireFormat = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional bool no_standard_descriptor_accessor = 2;
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.getNoStandardDescriptorAccessor = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.setNoStandardDescriptorAccessor = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.clearNoStandardDescriptorAccessor = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.hasNoStandardDescriptorAccessor = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional bool deprecated = 3;
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.setDeprecated = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.clearDeprecated = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.hasDeprecated = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional bool map_entry = 7;
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.getMapEntry = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 7, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.setMapEntry = function(value) {
+  return jspb.Message.setField(this, 7, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.clearMapEntry = function() {
+  return jspb.Message.setField(this, 7, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MessageOptions.prototype.hasMapEntry = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.MessageOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+*/
+proto.google.protobuf.MessageOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.MessageOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.MessageOptions} returns this
+ */
+proto.google.protobuf.MessageOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.FieldOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.FieldOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.FieldOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.FieldOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FieldOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    ctype: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    packed: (f = jspb.Message.getBooleanField(msg, 2)) == null ? undefined : f,
+    jstype: jspb.Message.getFieldWithDefault(msg, 6, 0),
+    lazy: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
+    weak: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.FieldOptions.extensions, proto.google.protobuf.FieldOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.FieldOptions}
+ */
+proto.google.protobuf.FieldOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.FieldOptions;
+  return proto.google.protobuf.FieldOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.FieldOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.FieldOptions}
+ */
+proto.google.protobuf.FieldOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.google.protobuf.FieldOptions.CType} */ (reader.readEnum());
+      msg.setCtype(value);
+      break;
+    case 2:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setPacked(value);
+      break;
+    case 6:
+      var value = /** @type {!proto.google.protobuf.FieldOptions.JSType} */ (reader.readEnum());
+      msg.setJstype(value);
+      break;
+    case 5:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setLazy(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 10:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setWeak(value);
+      break;
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.FieldOptions.extensionsBinary,
+        proto.google.protobuf.FieldOptions.prototype.getExtension,
+        proto.google.protobuf.FieldOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.FieldOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.FieldOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.FieldOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FieldOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {!proto.google.protobuf.FieldOptions.CType} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeBool(
+      2,
+      f
+    );
+  }
+  f = /** @type {!proto.google.protobuf.FieldOptions.JSType} */ (jspb.Message.getField(message, 6));
+  if (f != null) {
+    writer.writeEnum(
+      6,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeBool(
+      5,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 10));
+  if (f != null) {
+    writer.writeBool(
+      10,
+      f
+    );
+  }
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.FieldOptions.extensionsBinary, proto.google.protobuf.FieldOptions.prototype.getExtension);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.FieldOptions.CType = {
+  STRING: 0,
+  CORD: 1,
+  STRING_PIECE: 2
+};
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.FieldOptions.JSType = {
+  JS_NORMAL: 0,
+  JS_STRING: 1,
+  JS_NUMBER: 2
+};
+
+/**
+ * optional CType ctype = 1;
+ * @return {!proto.google.protobuf.FieldOptions.CType}
+ */
+proto.google.protobuf.FieldOptions.prototype.getCtype = function() {
+  return /** @type {!proto.google.protobuf.FieldOptions.CType} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FieldOptions.CType} value
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.setCtype = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.clearCtype = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.hasCtype = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional bool packed = 2;
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.getPacked = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.setPacked = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.clearPacked = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.hasPacked = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional JSType jstype = 6;
+ * @return {!proto.google.protobuf.FieldOptions.JSType}
+ */
+proto.google.protobuf.FieldOptions.prototype.getJstype = function() {
+  return /** @type {!proto.google.protobuf.FieldOptions.JSType} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.FieldOptions.JSType} value
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.setJstype = function(value) {
+  return jspb.Message.setField(this, 6, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.clearJstype = function() {
+  return jspb.Message.setField(this, 6, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.hasJstype = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional bool lazy = 5;
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.getLazy = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.setLazy = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.clearLazy = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.hasLazy = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional bool deprecated = 3;
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.setDeprecated = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.clearDeprecated = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.hasDeprecated = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional bool weak = 10;
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.getWeak = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.setWeak = function(value) {
+  return jspb.Message.setField(this, 10, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.clearWeak = function() {
+  return jspb.Message.setField(this, 10, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.FieldOptions.prototype.hasWeak = function() {
+  return jspb.Message.getField(this, 10) != null;
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.FieldOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+*/
+proto.google.protobuf.FieldOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.FieldOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FieldOptions} returns this
+ */
+proto.google.protobuf.FieldOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.OneofOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.OneofOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.OneofOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.OneofOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.OneofOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.OneofOptions.extensions, proto.google.protobuf.OneofOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.OneofOptions}
+ */
+proto.google.protobuf.OneofOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.OneofOptions;
+  return proto.google.protobuf.OneofOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.OneofOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.OneofOptions}
+ */
+proto.google.protobuf.OneofOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.OneofOptions.extensionsBinary,
+        proto.google.protobuf.OneofOptions.prototype.getExtension,
+        proto.google.protobuf.OneofOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.OneofOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.OneofOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.OneofOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.OneofOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.OneofOptions.extensionsBinary, proto.google.protobuf.OneofOptions.prototype.getExtension);
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.OneofOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.OneofOptions} returns this
+*/
+proto.google.protobuf.OneofOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.OneofOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.OneofOptions} returns this
+ */
+proto.google.protobuf.OneofOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.EnumOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.EnumOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.EnumOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.EnumOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    allowAlias: (f = jspb.Message.getBooleanField(msg, 2)) == null ? undefined : f,
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.EnumOptions.extensions, proto.google.protobuf.EnumOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.EnumOptions}
+ */
+proto.google.protobuf.EnumOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.EnumOptions;
+  return proto.google.protobuf.EnumOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.EnumOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.EnumOptions}
+ */
+proto.google.protobuf.EnumOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setAllowAlias(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.EnumOptions.extensionsBinary,
+        proto.google.protobuf.EnumOptions.prototype.getExtension,
+        proto.google.protobuf.EnumOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.EnumOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.EnumOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.EnumOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeBool(
+      2,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.EnumOptions.extensionsBinary, proto.google.protobuf.EnumOptions.prototype.getExtension);
+};
+
+
+/**
+ * optional bool allow_alias = 2;
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumOptions.prototype.getAllowAlias = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.EnumOptions} returns this
+ */
+proto.google.protobuf.EnumOptions.prototype.setAllowAlias = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumOptions} returns this
+ */
+proto.google.protobuf.EnumOptions.prototype.clearAllowAlias = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumOptions.prototype.hasAllowAlias = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional bool deprecated = 3;
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumOptions.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.EnumOptions} returns this
+ */
+proto.google.protobuf.EnumOptions.prototype.setDeprecated = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumOptions} returns this
+ */
+proto.google.protobuf.EnumOptions.prototype.clearDeprecated = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumOptions.prototype.hasDeprecated = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.EnumOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.EnumOptions} returns this
+*/
+proto.google.protobuf.EnumOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.EnumOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.EnumOptions} returns this
+ */
+proto.google.protobuf.EnumOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.EnumValueOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.EnumValueOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.EnumValueOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.EnumValueOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumValueOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.EnumValueOptions.extensions, proto.google.protobuf.EnumValueOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.EnumValueOptions}
+ */
+proto.google.protobuf.EnumValueOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.EnumValueOptions;
+  return proto.google.protobuf.EnumValueOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.EnumValueOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.EnumValueOptions}
+ */
+proto.google.protobuf.EnumValueOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.EnumValueOptions.extensionsBinary,
+        proto.google.protobuf.EnumValueOptions.prototype.getExtension,
+        proto.google.protobuf.EnumValueOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.EnumValueOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.EnumValueOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.EnumValueOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumValueOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.EnumValueOptions.extensionsBinary, proto.google.protobuf.EnumValueOptions.prototype.getExtension);
+};
+
+
+/**
+ * optional bool deprecated = 1;
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumValueOptions.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.EnumValueOptions} returns this
+ */
+proto.google.protobuf.EnumValueOptions.prototype.setDeprecated = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.EnumValueOptions} returns this
+ */
+proto.google.protobuf.EnumValueOptions.prototype.clearDeprecated = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.EnumValueOptions.prototype.hasDeprecated = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.EnumValueOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.EnumValueOptions} returns this
+*/
+proto.google.protobuf.EnumValueOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.EnumValueOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.EnumValueOptions} returns this
+ */
+proto.google.protobuf.EnumValueOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.ServiceOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.ServiceOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.ServiceOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.ServiceOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ServiceOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 33, false),
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.ServiceOptions.extensions, proto.google.protobuf.ServiceOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.ServiceOptions}
+ */
+proto.google.protobuf.ServiceOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.ServiceOptions;
+  return proto.google.protobuf.ServiceOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.ServiceOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.ServiceOptions}
+ */
+proto.google.protobuf.ServiceOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 33:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.ServiceOptions.extensionsBinary,
+        proto.google.protobuf.ServiceOptions.prototype.getExtension,
+        proto.google.protobuf.ServiceOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.ServiceOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.ServiceOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.ServiceOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ServiceOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 33));
+  if (f != null) {
+    writer.writeBool(
+      33,
+      f
+    );
+  }
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.ServiceOptions.extensionsBinary, proto.google.protobuf.ServiceOptions.prototype.getExtension);
+};
+
+
+/**
+ * optional bool deprecated = 33;
+ * @return {boolean}
+ */
+proto.google.protobuf.ServiceOptions.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 33, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.ServiceOptions} returns this
+ */
+proto.google.protobuf.ServiceOptions.prototype.setDeprecated = function(value) {
+  return jspb.Message.setField(this, 33, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.ServiceOptions} returns this
+ */
+proto.google.protobuf.ServiceOptions.prototype.clearDeprecated = function() {
+  return jspb.Message.setField(this, 33, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.ServiceOptions.prototype.hasDeprecated = function() {
+  return jspb.Message.getField(this, 33) != null;
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.ServiceOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.ServiceOptions} returns this
+*/
+proto.google.protobuf.ServiceOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.ServiceOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.ServiceOptions} returns this
+ */
+proto.google.protobuf.ServiceOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.MethodOptions.repeatedFields_ = [999];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.MethodOptions.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.MethodOptions.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.MethodOptions} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.MethodOptions.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 33, false),
+    idempotencyLevel: jspb.Message.getFieldWithDefault(msg, 34, 0),
+    uninterpretedOptionList: jspb.Message.toObjectList(msg.getUninterpretedOptionList(),
+    proto.google.protobuf.UninterpretedOption.toObject, includeInstance)
+  };
+
+  jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), obj,
+      proto.google.protobuf.MethodOptions.extensions, proto.google.protobuf.MethodOptions.prototype.getExtension,
+      includeInstance);
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.MethodOptions}
+ */
+proto.google.protobuf.MethodOptions.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.MethodOptions;
+  return proto.google.protobuf.MethodOptions.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.MethodOptions} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.MethodOptions}
+ */
+proto.google.protobuf.MethodOptions.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 33:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 34:
+      var value = /** @type {!proto.google.protobuf.MethodOptions.IdempotencyLevel} */ (reader.readEnum());
+      msg.setIdempotencyLevel(value);
+      break;
+    case 999:
+      var value = new proto.google.protobuf.UninterpretedOption;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader);
+      msg.addUninterpretedOption(value);
+      break;
+    default:
+      jspb.Message.readBinaryExtension(msg, reader,
+        proto.google.protobuf.MethodOptions.extensionsBinary,
+        proto.google.protobuf.MethodOptions.prototype.getExtension,
+        proto.google.protobuf.MethodOptions.prototype.setExtension);
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.MethodOptions.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.MethodOptions.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.MethodOptions} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.MethodOptions.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 33));
+  if (f != null) {
+    writer.writeBool(
+      33,
+      f
+    );
+  }
+  f = /** @type {!proto.google.protobuf.MethodOptions.IdempotencyLevel} */ (jspb.Message.getField(message, 34));
+  if (f != null) {
+    writer.writeEnum(
+      34,
+      f
+    );
+  }
+  f = message.getUninterpretedOptionList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      999,
+      f,
+      proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter
+    );
+  }
+  jspb.Message.serializeBinaryExtensions(message, writer,
+    proto.google.protobuf.MethodOptions.extensionsBinary, proto.google.protobuf.MethodOptions.prototype.getExtension);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.MethodOptions.IdempotencyLevel = {
+  IDEMPOTENCY_UNKNOWN: 0,
+  NO_SIDE_EFFECTS: 1,
+  IDEMPOTENT: 2
+};
+
+/**
+ * optional bool deprecated = 33;
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodOptions.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 33, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.MethodOptions} returns this
+ */
+proto.google.protobuf.MethodOptions.prototype.setDeprecated = function(value) {
+  return jspb.Message.setField(this, 33, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MethodOptions} returns this
+ */
+proto.google.protobuf.MethodOptions.prototype.clearDeprecated = function() {
+  return jspb.Message.setField(this, 33, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodOptions.prototype.hasDeprecated = function() {
+  return jspb.Message.getField(this, 33) != null;
+};
+
+
+/**
+ * optional IdempotencyLevel idempotency_level = 34;
+ * @return {!proto.google.protobuf.MethodOptions.IdempotencyLevel}
+ */
+proto.google.protobuf.MethodOptions.prototype.getIdempotencyLevel = function() {
+  return /** @type {!proto.google.protobuf.MethodOptions.IdempotencyLevel} */ (jspb.Message.getFieldWithDefault(this, 34, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.MethodOptions.IdempotencyLevel} value
+ * @return {!proto.google.protobuf.MethodOptions} returns this
+ */
+proto.google.protobuf.MethodOptions.prototype.setIdempotencyLevel = function(value) {
+  return jspb.Message.setField(this, 34, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.MethodOptions} returns this
+ */
+proto.google.protobuf.MethodOptions.prototype.clearIdempotencyLevel = function() {
+  return jspb.Message.setField(this, 34, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.MethodOptions.prototype.hasIdempotencyLevel = function() {
+  return jspb.Message.getField(this, 34) != null;
+};
+
+
+/**
+ * repeated UninterpretedOption uninterpreted_option = 999;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption>}
+ */
+proto.google.protobuf.MethodOptions.prototype.getUninterpretedOptionList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption, 999));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption>} value
+ * @return {!proto.google.protobuf.MethodOptions} returns this
+*/
+proto.google.protobuf.MethodOptions.prototype.setUninterpretedOptionList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 999, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.MethodOptions.prototype.addUninterpretedOption = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 999, opt_value, proto.google.protobuf.UninterpretedOption, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.MethodOptions} returns this
+ */
+proto.google.protobuf.MethodOptions.prototype.clearUninterpretedOptionList = function() {
+  return this.setUninterpretedOptionList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.UninterpretedOption.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.UninterpretedOption.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.UninterpretedOption} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UninterpretedOption.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    nameList: jspb.Message.toObjectList(msg.getNameList(),
+    proto.google.protobuf.UninterpretedOption.NamePart.toObject, includeInstance),
+    identifierValue: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    positiveIntValue: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    negativeIntValue: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
+    doubleValue: (f = jspb.Message.getOptionalFloatingPointField(msg, 6)) == null ? undefined : f,
+    stringValue: msg.getStringValue_asB64(),
+    aggregateValue: (f = jspb.Message.getField(msg, 8)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.UninterpretedOption.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.UninterpretedOption;
+  return proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.UninterpretedOption} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.UninterpretedOption}
+ */
+proto.google.protobuf.UninterpretedOption.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 2:
+      var value = new proto.google.protobuf.UninterpretedOption.NamePart;
+      reader.readMessage(value,proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinaryFromReader);
+      msg.addName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIdentifierValue(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setPositiveIntValue(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setNegativeIntValue(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setDoubleValue(value);
+      break;
+    case 7:
+      var value = /** @type {!Uint8Array} */ (reader.readBytes());
+      msg.setStringValue(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAggregateValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.UninterpretedOption} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UninterpretedOption.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getNameList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.google.protobuf.UninterpretedOption.NamePart.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeUint64(
+      4,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeInt64(
+      5,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 6));
+  if (f != null) {
+    writer.writeDouble(
+      6,
+      f
+    );
+  }
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 7));
+  if (f != null) {
+    writer.writeBytes(
+      7,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 8));
+  if (f != null) {
+    writer.writeString(
+      8,
+      f
+    );
+  }
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.UninterpretedOption.NamePart.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.UninterpretedOption.NamePart} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    namePart: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    isExtension: (f = jspb.Message.getBooleanField(msg, 2)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.UninterpretedOption.NamePart}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.UninterpretedOption.NamePart;
+  return proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.UninterpretedOption.NamePart} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.UninterpretedOption.NamePart}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setNamePart(value);
+      break;
+    case 2:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsExtension(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.UninterpretedOption.NamePart.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.UninterpretedOption.NamePart} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeBool(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * required string name_part = 1;
+ * @return {string}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.getNamePart = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.setNamePart = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.clearNamePart = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.hasNamePart = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * required bool is_extension = 2;
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.getIsExtension = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.setIsExtension = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption.NamePart} returns this
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.clearIsExtension = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.NamePart.prototype.hasIsExtension = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * repeated NamePart name = 2;
+ * @return {!Array<!proto.google.protobuf.UninterpretedOption.NamePart>}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getNameList = function() {
+  return /** @type{!Array<!proto.google.protobuf.UninterpretedOption.NamePart>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.UninterpretedOption.NamePart, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.UninterpretedOption.NamePart>} value
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+*/
+proto.google.protobuf.UninterpretedOption.prototype.setNameList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.UninterpretedOption.NamePart=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.UninterpretedOption.NamePart}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.addName = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.UninterpretedOption.NamePart, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.clearNameList = function() {
+  return this.setNameList([]);
+};
+
+
+/**
+ * optional string identifier_value = 3;
+ * @return {string}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getIdentifierValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.setIdentifierValue = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.clearIdentifierValue = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.hasIdentifierValue = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional uint64 positive_int_value = 4;
+ * @return {number}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getPositiveIntValue = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.setPositiveIntValue = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.clearPositiveIntValue = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.hasPositiveIntValue = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional int64 negative_int_value = 5;
+ * @return {number}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getNegativeIntValue = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.setNegativeIntValue = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.clearNegativeIntValue = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.hasNegativeIntValue = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional double double_value = 6;
+ * @return {number}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getDoubleValue = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 6, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.setDoubleValue = function(value) {
+  return jspb.Message.setField(this, 6, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.clearDoubleValue = function() {
+  return jspb.Message.setField(this, 6, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.hasDoubleValue = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional bytes string_value = 7;
+ * @return {!(string|Uint8Array)}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getStringValue = function() {
+  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * optional bytes string_value = 7;
+ * This is a type-conversion wrapper around `getStringValue()`
+ * @return {string}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getStringValue_asB64 = function() {
+  return /** @type {string} */ (jspb.Message.bytesAsB64(
+      this.getStringValue()));
+};
+
+
+/**
+ * optional bytes string_value = 7;
+ * Note that Uint8Array is not supported on all browsers.
+ * @see http://caniuse.com/Uint8Array
+ * This is a type-conversion wrapper around `getStringValue()`
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getStringValue_asU8 = function() {
+  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
+      this.getStringValue()));
+};
+
+
+/**
+ * @param {!(string|Uint8Array)} value
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.setStringValue = function(value) {
+  return jspb.Message.setField(this, 7, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.clearStringValue = function() {
+  return jspb.Message.setField(this, 7, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.hasStringValue = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+/**
+ * optional string aggregate_value = 8;
+ * @return {string}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.getAggregateValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.setAggregateValue = function(value) {
+  return jspb.Message.setField(this, 8, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.UninterpretedOption} returns this
+ */
+proto.google.protobuf.UninterpretedOption.prototype.clearAggregateValue = function() {
+  return jspb.Message.setField(this, 8, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.UninterpretedOption.prototype.hasAggregateValue = function() {
+  return jspb.Message.getField(this, 8) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.SourceCodeInfo.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.SourceCodeInfo.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.SourceCodeInfo.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.SourceCodeInfo} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.SourceCodeInfo.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    locationList: jspb.Message.toObjectList(msg.getLocationList(),
+    proto.google.protobuf.SourceCodeInfo.Location.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.SourceCodeInfo}
+ */
+proto.google.protobuf.SourceCodeInfo.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.SourceCodeInfo;
+  return proto.google.protobuf.SourceCodeInfo.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.SourceCodeInfo} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.SourceCodeInfo}
+ */
+proto.google.protobuf.SourceCodeInfo.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.google.protobuf.SourceCodeInfo.Location;
+      reader.readMessage(value,proto.google.protobuf.SourceCodeInfo.Location.deserializeBinaryFromReader);
+      msg.addLocation(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.SourceCodeInfo.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.SourceCodeInfo.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.SourceCodeInfo} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.SourceCodeInfo.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getLocationList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.google.protobuf.SourceCodeInfo.Location.serializeBinaryToWriter
+    );
+  }
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.SourceCodeInfo.Location.repeatedFields_ = [1,2,6];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.SourceCodeInfo.Location.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.SourceCodeInfo.Location} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.SourceCodeInfo.Location.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    pathList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f,
+    spanList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
+    leadingComments: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    trailingComments: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    leadingDetachedCommentsList: (f = jspb.Message.getRepeatedField(msg, 6)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.SourceCodeInfo.Location;
+  return proto.google.protobuf.SourceCodeInfo.Location.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.SourceCodeInfo.Location} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPath(values[i]);
+      }
+      break;
+    case 2:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addSpan(values[i]);
+      }
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLeadingComments(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTrailingComments(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addLeadingDetachedComments(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.SourceCodeInfo.Location.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.SourceCodeInfo.Location} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.SourceCodeInfo.Location.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPathList();
+  if (f.length > 0) {
+    writer.writePackedInt32(
+      1,
+      f
+    );
+  }
+  f = message.getSpanList();
+  if (f.length > 0) {
+    writer.writePackedInt32(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getLeadingDetachedCommentsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated int32 path = 1;
+ * @return {!Array<number>}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.getPathList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 1));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.setPathList = function(value) {
+  return jspb.Message.setField(this, 1, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.addPath = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.clearPathList = function() {
+  return this.setPathList([]);
+};
+
+
+/**
+ * repeated int32 span = 2;
+ * @return {!Array<number>}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.getSpanList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.setSpanList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.addSpan = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.clearSpanList = function() {
+  return this.setSpanList([]);
+};
+
+
+/**
+ * optional string leading_comments = 3;
+ * @return {string}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.getLeadingComments = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.setLeadingComments = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.clearLeadingComments = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.hasLeadingComments = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional string trailing_comments = 4;
+ * @return {string}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.getTrailingComments = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.setTrailingComments = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.clearTrailingComments = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.hasTrailingComments = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * repeated string leading_detached_comments = 6;
+ * @return {!Array<string>}
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.getLeadingDetachedCommentsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 6));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.setLeadingDetachedCommentsList = function(value) {
+  return jspb.Message.setField(this, 6, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.addLeadingDetachedComments = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 6, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.Location.prototype.clearLeadingDetachedCommentsList = function() {
+  return this.setLeadingDetachedCommentsList([]);
+};
+
+
+/**
+ * repeated Location location = 1;
+ * @return {!Array<!proto.google.protobuf.SourceCodeInfo.Location>}
+ */
+proto.google.protobuf.SourceCodeInfo.prototype.getLocationList = function() {
+  return /** @type{!Array<!proto.google.protobuf.SourceCodeInfo.Location>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.SourceCodeInfo.Location, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.SourceCodeInfo.Location>} value
+ * @return {!proto.google.protobuf.SourceCodeInfo} returns this
+*/
+proto.google.protobuf.SourceCodeInfo.prototype.setLocationList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.SourceCodeInfo.Location=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.SourceCodeInfo.Location}
+ */
+proto.google.protobuf.SourceCodeInfo.prototype.addLocation = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.SourceCodeInfo.Location, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.SourceCodeInfo} returns this
+ */
+proto.google.protobuf.SourceCodeInfo.prototype.clearLocationList = function() {
+  return this.setLocationList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.GeneratedCodeInfo.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.GeneratedCodeInfo.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.GeneratedCodeInfo.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.GeneratedCodeInfo} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.GeneratedCodeInfo.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    annotationList: jspb.Message.toObjectList(msg.getAnnotationList(),
+    proto.google.protobuf.GeneratedCodeInfo.Annotation.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo}
+ */
+proto.google.protobuf.GeneratedCodeInfo.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.GeneratedCodeInfo;
+  return proto.google.protobuf.GeneratedCodeInfo.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.GeneratedCodeInfo} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo}
+ */
+proto.google.protobuf.GeneratedCodeInfo.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.google.protobuf.GeneratedCodeInfo.Annotation;
+      reader.readMessage(value,proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinaryFromReader);
+      msg.addAnnotation(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.GeneratedCodeInfo.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.GeneratedCodeInfo.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.GeneratedCodeInfo} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.GeneratedCodeInfo.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getAnnotationList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.google.protobuf.GeneratedCodeInfo.Annotation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.GeneratedCodeInfo.Annotation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    pathList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f,
+    sourceFile: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    begin: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    end: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.GeneratedCodeInfo.Annotation;
+  return proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedInt32() : [reader.readInt32()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPath(values[i]);
+      }
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSourceFile(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setBegin(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setEnd(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.GeneratedCodeInfo.Annotation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPathList();
+  if (f.length > 0) {
+    writer.writePackedInt32(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeInt32(
+      3,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeInt32(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated int32 path = 1;
+ * @return {!Array<number>}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getPathList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 1));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setPathList = function(value) {
+  return jspb.Message.setField(this, 1, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.addPath = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearPathList = function() {
+  return this.setPathList([]);
+};
+
+
+/**
+ * optional string source_file = 2;
+ * @return {string}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getSourceFile = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setSourceFile = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearSourceFile = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.hasSourceFile = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional int32 begin = 3;
+ * @return {number}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getBegin = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setBegin = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearBegin = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.hasBegin = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional int32 end = 4;
+ * @return {number}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.getEnd = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.setEnd = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.clearEnd = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.GeneratedCodeInfo.Annotation.prototype.hasEnd = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * repeated Annotation annotation = 1;
+ * @return {!Array<!proto.google.protobuf.GeneratedCodeInfo.Annotation>}
+ */
+proto.google.protobuf.GeneratedCodeInfo.prototype.getAnnotationList = function() {
+  return /** @type{!Array<!proto.google.protobuf.GeneratedCodeInfo.Annotation>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.GeneratedCodeInfo.Annotation, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.GeneratedCodeInfo.Annotation>} value
+ * @return {!proto.google.protobuf.GeneratedCodeInfo} returns this
+*/
+proto.google.protobuf.GeneratedCodeInfo.prototype.setAnnotationList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.GeneratedCodeInfo.Annotation=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.GeneratedCodeInfo.Annotation}
+ */
+proto.google.protobuf.GeneratedCodeInfo.prototype.addAnnotation = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.GeneratedCodeInfo.Annotation, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.GeneratedCodeInfo} returns this
+ */
+proto.google.protobuf.GeneratedCodeInfo.prototype.clearAnnotationList = function() {
+  return this.setAnnotationList([]);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/duration_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/duration_pb.js
new file mode 100644
index 0000000..4ceb55a
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/duration_pb.js
@@ -0,0 +1,200 @@
+// source: google/protobuf/duration.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.Duration', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Duration = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Duration, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Duration.displayName = 'proto.google.protobuf.Duration';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Duration.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Duration.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Duration} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Duration.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    seconds: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    nanos: jspb.Message.getFieldWithDefault(msg, 2, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Duration}
+ */
+proto.google.protobuf.Duration.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Duration;
+  return proto.google.protobuf.Duration.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Duration} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Duration}
+ */
+proto.google.protobuf.Duration.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setSeconds(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setNanos(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Duration.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Duration.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Duration} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Duration.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSeconds();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getNanos();
+  if (f !== 0) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 seconds = 1;
+ * @return {number}
+ */
+proto.google.protobuf.Duration.prototype.getSeconds = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Duration} returns this
+ */
+proto.google.protobuf.Duration.prototype.setSeconds = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional int32 nanos = 2;
+ * @return {number}
+ */
+proto.google.protobuf.Duration.prototype.getNanos = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Duration} returns this
+ */
+proto.google.protobuf.Duration.prototype.setNanos = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/empty_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/empty_pb.js
new file mode 100644
index 0000000..31392b4
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/empty_pb.js
@@ -0,0 +1,141 @@
+// source: google/protobuf/empty.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.Empty', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Empty = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Empty, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Empty.displayName = 'proto.google.protobuf.Empty';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Empty.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Empty.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Empty} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Empty.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Empty}
+ */
+proto.google.protobuf.Empty.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Empty;
+  return proto.google.protobuf.Empty.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Empty} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Empty}
+ */
+proto.google.protobuf.Empty.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Empty.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Empty.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Empty} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Empty.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/field_mask_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/field_mask_pb.js
new file mode 100644
index 0000000..ee7bda0
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/field_mask_pb.js
@@ -0,0 +1,196 @@
+// source: google/protobuf/field_mask.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.FieldMask', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.FieldMask = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.FieldMask.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.FieldMask, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.FieldMask.displayName = 'proto.google.protobuf.FieldMask';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.FieldMask.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.FieldMask.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.FieldMask.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.FieldMask} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FieldMask.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    pathsList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.FieldMask}
+ */
+proto.google.protobuf.FieldMask.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.FieldMask;
+  return proto.google.protobuf.FieldMask.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.FieldMask} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.FieldMask}
+ */
+proto.google.protobuf.FieldMask.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addPaths(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.FieldMask.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.FieldMask.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.FieldMask} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FieldMask.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPathsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated string paths = 1;
+ * @return {!Array<string>}
+ */
+proto.google.protobuf.FieldMask.prototype.getPathsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.google.protobuf.FieldMask} returns this
+ */
+proto.google.protobuf.FieldMask.prototype.setPathsList = function(value) {
+  return jspb.Message.setField(this, 1, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.FieldMask} returns this
+ */
+proto.google.protobuf.FieldMask.prototype.addPaths = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.FieldMask} returns this
+ */
+proto.google.protobuf.FieldMask.prototype.clearPathsList = function() {
+  return this.setPathsList([]);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/source_context_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/source_context_pb.js
new file mode 100644
index 0000000..1cc063c
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/source_context_pb.js
@@ -0,0 +1,170 @@
+// source: google/protobuf/source_context.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.SourceContext', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.SourceContext = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.SourceContext, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.SourceContext.displayName = 'proto.google.protobuf.SourceContext';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.SourceContext.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.SourceContext.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.SourceContext} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.SourceContext.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    fileName: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.SourceContext}
+ */
+proto.google.protobuf.SourceContext.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.SourceContext;
+  return proto.google.protobuf.SourceContext.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.SourceContext} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.SourceContext}
+ */
+proto.google.protobuf.SourceContext.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFileName(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.SourceContext.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.SourceContext.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.SourceContext} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.SourceContext.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFileName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string file_name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.SourceContext.prototype.getFileName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.SourceContext} returns this
+ */
+proto.google.protobuf.SourceContext.prototype.setFileName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/struct_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/struct_pb.js
new file mode 100644
index 0000000..b1f2a9a
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/struct_pb.js
@@ -0,0 +1,948 @@
+// source: google/protobuf/struct.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.ListValue', null, proto);
+goog.exportSymbol('google.protobuf.NullValue', null, proto);
+goog.exportSymbol('google.protobuf.Struct', null, proto);
+goog.exportSymbol('google.protobuf.Value', null, proto);
+goog.exportSymbol('google.protobuf.Value.KindCase', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Struct = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Struct, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Struct.displayName = 'proto.google.protobuf.Struct';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Value = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.google.protobuf.Value.oneofGroups_);
+};
+goog.inherits(proto.google.protobuf.Value, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Value.displayName = 'proto.google.protobuf.Value';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.ListValue = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.ListValue.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.ListValue, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.ListValue.displayName = 'proto.google.protobuf.ListValue';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Struct.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Struct.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Struct} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Struct.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    fieldsMap: (f = msg.getFieldsMap()) ? f.toObject(includeInstance, proto.google.protobuf.Value.toObject) : []
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Struct}
+ */
+proto.google.protobuf.Struct.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Struct;
+  return proto.google.protobuf.Struct.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Struct} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Struct}
+ */
+proto.google.protobuf.Struct.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = msg.getFieldsMap();
+      reader.readMessage(value, function(message, reader) {
+        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readMessage, proto.google.protobuf.Value.deserializeBinaryFromReader, "", new proto.google.protobuf.Value());
+         });
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Struct.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Struct.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Struct} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Struct.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFieldsMap(true);
+  if (f && f.getLength() > 0) {
+    f.serializeBinary(1, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeMessage, proto.google.protobuf.Value.serializeBinaryToWriter);
+  }
+};
+
+
+/**
+ * map<string, Value> fields = 1;
+ * @param {boolean=} opt_noLazyCreate Do not create the map if
+ * empty, instead returning `undefined`
+ * @return {!jspb.Map<string,!proto.google.protobuf.Value>}
+ */
+proto.google.protobuf.Struct.prototype.getFieldsMap = function(opt_noLazyCreate) {
+  return /** @type {!jspb.Map<string,!proto.google.protobuf.Value>} */ (
+      jspb.Message.getMapField(this, 1, opt_noLazyCreate,
+      proto.google.protobuf.Value));
+};
+
+
+/**
+ * Clears values from the map. The map will be non-null.
+ * @return {!proto.google.protobuf.Struct} returns this
+ */
+proto.google.protobuf.Struct.prototype.clearFieldsMap = function() {
+  this.getFieldsMap().clear();
+  return this;};
+
+
+
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
+ * @const
+ */
+proto.google.protobuf.Value.oneofGroups_ = [[1,2,3,4,5,6]];
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.Value.KindCase = {
+  KIND_NOT_SET: 0,
+  NULL_VALUE: 1,
+  NUMBER_VALUE: 2,
+  STRING_VALUE: 3,
+  BOOL_VALUE: 4,
+  STRUCT_VALUE: 5,
+  LIST_VALUE: 6
+};
+
+/**
+ * @return {proto.google.protobuf.Value.KindCase}
+ */
+proto.google.protobuf.Value.prototype.getKindCase = function() {
+  return /** @type {proto.google.protobuf.Value.KindCase} */(jspb.Message.computeOneofCase(this, proto.google.protobuf.Value.oneofGroups_[0]));
+};
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Value.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Value.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Value} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Value.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    nullValue: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    numberValue: jspb.Message.getFloatingPointFieldWithDefault(msg, 2, 0.0),
+    stringValue: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    boolValue: jspb.Message.getBooleanFieldWithDefault(msg, 4, false),
+    structValue: (f = msg.getStructValue()) && proto.google.protobuf.Struct.toObject(includeInstance, f),
+    listValue: (f = msg.getListValue()) && proto.google.protobuf.ListValue.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Value}
+ */
+proto.google.protobuf.Value.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Value;
+  return proto.google.protobuf.Value.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Value} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Value}
+ */
+proto.google.protobuf.Value.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.google.protobuf.NullValue} */ (reader.readEnum());
+      msg.setNullValue(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setNumberValue(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setStringValue(value);
+      break;
+    case 4:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setBoolValue(value);
+      break;
+    case 5:
+      var value = new proto.google.protobuf.Struct;
+      reader.readMessage(value,proto.google.protobuf.Struct.deserializeBinaryFromReader);
+      msg.setStructValue(value);
+      break;
+    case 6:
+      var value = new proto.google.protobuf.ListValue;
+      reader.readMessage(value,proto.google.protobuf.ListValue.deserializeBinaryFromReader);
+      msg.setListValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Value.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Value.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Value} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Value.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {!proto.google.protobuf.NullValue} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeDouble(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeBool(
+      4,
+      f
+    );
+  }
+  f = message.getStructValue();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      proto.google.protobuf.Struct.serializeBinaryToWriter
+    );
+  }
+  f = message.getListValue();
+  if (f != null) {
+    writer.writeMessage(
+      6,
+      f,
+      proto.google.protobuf.ListValue.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional NullValue null_value = 1;
+ * @return {!proto.google.protobuf.NullValue}
+ */
+proto.google.protobuf.Value.prototype.getNullValue = function() {
+  return /** @type {!proto.google.protobuf.NullValue} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.NullValue} value
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.setNullValue = function(value) {
+  return jspb.Message.setOneofField(this, 1, proto.google.protobuf.Value.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.clearNullValue = function() {
+  return jspb.Message.setOneofField(this, 1, proto.google.protobuf.Value.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Value.prototype.hasNullValue = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional double number_value = 2;
+ * @return {number}
+ */
+proto.google.protobuf.Value.prototype.getNumberValue = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 2, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.setNumberValue = function(value) {
+  return jspb.Message.setOneofField(this, 2, proto.google.protobuf.Value.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.clearNumberValue = function() {
+  return jspb.Message.setOneofField(this, 2, proto.google.protobuf.Value.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Value.prototype.hasNumberValue = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string string_value = 3;
+ * @return {string}
+ */
+proto.google.protobuf.Value.prototype.getStringValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.setStringValue = function(value) {
+  return jspb.Message.setOneofField(this, 3, proto.google.protobuf.Value.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.clearStringValue = function() {
+  return jspb.Message.setOneofField(this, 3, proto.google.protobuf.Value.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Value.prototype.hasStringValue = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional bool bool_value = 4;
+ * @return {boolean}
+ */
+proto.google.protobuf.Value.prototype.getBoolValue = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.setBoolValue = function(value) {
+  return jspb.Message.setOneofField(this, 4, proto.google.protobuf.Value.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.clearBoolValue = function() {
+  return jspb.Message.setOneofField(this, 4, proto.google.protobuf.Value.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Value.prototype.hasBoolValue = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional Struct struct_value = 5;
+ * @return {?proto.google.protobuf.Struct}
+ */
+proto.google.protobuf.Value.prototype.getStructValue = function() {
+  return /** @type{?proto.google.protobuf.Struct} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.Struct, 5));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.Struct|undefined} value
+ * @return {!proto.google.protobuf.Value} returns this
+*/
+proto.google.protobuf.Value.prototype.setStructValue = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 5, proto.google.protobuf.Value.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.clearStructValue = function() {
+  return this.setStructValue(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Value.prototype.hasStructValue = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional ListValue list_value = 6;
+ * @return {?proto.google.protobuf.ListValue}
+ */
+proto.google.protobuf.Value.prototype.getListValue = function() {
+  return /** @type{?proto.google.protobuf.ListValue} */ (
+    jspb.Message.getWrapperField(this, proto.google.protobuf.ListValue, 6));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.ListValue|undefined} value
+ * @return {!proto.google.protobuf.Value} returns this
+*/
+proto.google.protobuf.Value.prototype.setListValue = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 6, proto.google.protobuf.Value.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.Value} returns this
+ */
+proto.google.protobuf.Value.prototype.clearListValue = function() {
+  return this.setListValue(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Value.prototype.hasListValue = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.ListValue.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.ListValue.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.ListValue.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.ListValue} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ListValue.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    valuesList: jspb.Message.toObjectList(msg.getValuesList(),
+    proto.google.protobuf.Value.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.ListValue}
+ */
+proto.google.protobuf.ListValue.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.ListValue;
+  return proto.google.protobuf.ListValue.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.ListValue} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.ListValue}
+ */
+proto.google.protobuf.ListValue.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.google.protobuf.Value;
+      reader.readMessage(value,proto.google.protobuf.Value.deserializeBinaryFromReader);
+      msg.addValues(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.ListValue.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.ListValue.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.ListValue} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.ListValue.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValuesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.google.protobuf.Value.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Value values = 1;
+ * @return {!Array<!proto.google.protobuf.Value>}
+ */
+proto.google.protobuf.ListValue.prototype.getValuesList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Value>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Value, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Value>} value
+ * @return {!proto.google.protobuf.ListValue} returns this
+*/
+proto.google.protobuf.ListValue.prototype.setValuesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Value=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Value}
+ */
+proto.google.protobuf.ListValue.prototype.addValues = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.google.protobuf.Value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.ListValue} returns this
+ */
+proto.google.protobuf.ListValue.prototype.clearValuesList = function() {
+  return this.setValuesList([]);
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.NullValue = {
+  NULL_VALUE: 0
+};
+
+goog.object.extend(exports, proto);
+/* This code will be inserted into generated code for
+ * google/protobuf/struct.proto. */
+
+/**
+ * Typedef representing plain JavaScript values that can go into a
+ *     Struct.
+ * @typedef {null|number|string|boolean|Array|Object}
+ */
+proto.google.protobuf.JavaScriptValue;
+
+
+/**
+ * Converts this Value object to a plain JavaScript value.
+ * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript
+ *     value representing this Struct.
+ */
+proto.google.protobuf.Value.prototype.toJavaScript = function() {
+  var kindCase = proto.google.protobuf.Value.KindCase;
+  switch (this.getKindCase()) {
+    case kindCase.NULL_VALUE:
+      return null;
+    case kindCase.NUMBER_VALUE:
+      return this.getNumberValue();
+    case kindCase.STRING_VALUE:
+      return this.getStringValue();
+    case kindCase.BOOL_VALUE:
+      return this.getBoolValue();
+    case kindCase.STRUCT_VALUE:
+      return this.getStructValue().toJavaScript();
+    case kindCase.LIST_VALUE:
+      return this.getListValue().toJavaScript();
+    default:
+      throw new Error('Unexpected struct type');
+  }
+};
+
+
+/**
+ * Converts this JavaScript value to a new Value proto.
+ * @param {!proto.google.protobuf.JavaScriptValue} value The value to
+ *     convert.
+ * @return {!proto.google.protobuf.Value} The newly constructed value.
+ */
+proto.google.protobuf.Value.fromJavaScript = function(value) {
+  var ret = new proto.google.protobuf.Value();
+  switch (goog.typeOf(value)) {
+    case 'string':
+      ret.setStringValue(/** @type {string} */ (value));
+      break;
+    case 'number':
+      ret.setNumberValue(/** @type {number} */ (value));
+      break;
+    case 'boolean':
+      ret.setBoolValue(/** @type {boolean} */ (value));
+      break;
+    case 'null':
+      ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);
+      break;
+    case 'array':
+      ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(
+          /** @type{!Array} */ (value)));
+      break;
+    case 'object':
+      ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(
+          /** @type{!Object} */ (value)));
+      break;
+    default:
+      throw new Error('Unexpected struct type.');
+  }
+
+  return ret;
+};
+
+
+/**
+ * Converts this ListValue object to a plain JavaScript array.
+ * @return {!Array} a plain JavaScript array representing this List.
+ */
+proto.google.protobuf.ListValue.prototype.toJavaScript = function() {
+  var ret = [];
+  var values = this.getValuesList();
+
+  for (var i = 0; i < values.length; i++) {
+    ret[i] = values[i].toJavaScript();
+  }
+
+  return ret;
+};
+
+
+/**
+ * Constructs a ListValue protobuf from this plain JavaScript array.
+ * @param {!Array} array a plain JavaScript array
+ * @return {proto.google.protobuf.ListValue} a new ListValue object
+ */
+proto.google.protobuf.ListValue.fromJavaScript = function(array) {
+  var ret = new proto.google.protobuf.ListValue();
+
+  for (var i = 0; i < array.length; i++) {
+    ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));
+  }
+
+  return ret;
+};
+
+
+/**
+ * Converts this Struct object to a plain JavaScript object.
+ * @return {!Object<string, !proto.google.protobuf.JavaScriptValue>} a plain
+ *     JavaScript object representing this Struct.
+ */
+proto.google.protobuf.Struct.prototype.toJavaScript = function() {
+  var ret = {};
+
+  this.getFieldsMap().forEach(function(value, key) {
+    ret[key] = value.toJavaScript();
+  });
+
+  return ret;
+};
+
+
+/**
+ * Constructs a Struct protobuf from this plain JavaScript object.
+ * @param {!Object} obj a plain JavaScript object
+ * @return {proto.google.protobuf.Struct} a new Struct object
+ */
+proto.google.protobuf.Struct.fromJavaScript = function(obj) {
+  var ret = new proto.google.protobuf.Struct();
+  var map = ret.getFieldsMap();
+
+  for (var property in obj) {
+    var val = obj[property];
+    map.set(property, proto.google.protobuf.Value.fromJavaScript(val));
+  }
+
+  return ret;
+};
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js
new file mode 100644
index 0000000..42ece50
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/timestamp_pb.js
@@ -0,0 +1,236 @@
+// source: google/protobuf/timestamp.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.Timestamp', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Timestamp = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Timestamp, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Timestamp.displayName = 'proto.google.protobuf.Timestamp';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Timestamp.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Timestamp.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Timestamp} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Timestamp.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    seconds: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    nanos: jspb.Message.getFieldWithDefault(msg, 2, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Timestamp}
+ */
+proto.google.protobuf.Timestamp.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Timestamp;
+  return proto.google.protobuf.Timestamp.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Timestamp} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Timestamp}
+ */
+proto.google.protobuf.Timestamp.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setSeconds(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setNanos(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Timestamp.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Timestamp.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Timestamp} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Timestamp.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSeconds();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+  f = message.getNanos();
+  if (f !== 0) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 seconds = 1;
+ * @return {number}
+ */
+proto.google.protobuf.Timestamp.prototype.getSeconds = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Timestamp} returns this
+ */
+proto.google.protobuf.Timestamp.prototype.setSeconds = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional int32 nanos = 2;
+ * @return {number}
+ */
+proto.google.protobuf.Timestamp.prototype.getNanos = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Timestamp} returns this
+ */
+proto.google.protobuf.Timestamp.prototype.setNanos = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+goog.object.extend(exports, proto);
+/* This code will be inserted into generated code for
+ * google/protobuf/timestamp.proto. */
+
+/**
+ * Returns a JavaScript 'Date' object corresponding to this Timestamp.
+ * @return {!Date}
+ */
+proto.google.protobuf.Timestamp.prototype.toDate = function() {
+  var seconds = this.getSeconds();
+  var nanos = this.getNanos();
+
+  return new Date((seconds * 1000) + (nanos / 1000000));
+};
+
+
+/**
+ * Sets the value of this Timestamp object to be the given Date.
+ * @param {!Date} value The value to set.
+ */
+proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {
+  this.setSeconds(Math.floor(value.getTime() / 1000));
+  this.setNanos(value.getMilliseconds() * 1000000);
+};
+
+
+/**
+ * Factory method that returns a Timestamp object with value equal to
+ * the given Date.
+ * @param {!Date} value The value to set.
+ * @return {!proto.google.protobuf.Timestamp}
+ */
+proto.google.protobuf.Timestamp.fromDate = function(value) {
+  var timestamp = new proto.google.protobuf.Timestamp();
+  timestamp.fromDate(value);
+  return timestamp;
+};
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/type_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/type_pb.js
new file mode 100644
index 0000000..e8bcb30
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/type_pb.js
@@ -0,0 +1,1706 @@
+// source: google/protobuf/type.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+var google_protobuf_any_pb = require('google-protobuf/google/protobuf/any_pb.js');
+goog.object.extend(proto, google_protobuf_any_pb);
+var google_protobuf_source_context_pb = require('google-protobuf/google/protobuf/source_context_pb.js');
+goog.object.extend(proto, google_protobuf_source_context_pb);
+goog.exportSymbol('google.protobuf.Enum', null, proto);
+goog.exportSymbol('google.protobuf.EnumValue', null, proto);
+goog.exportSymbol('google.protobuf.Field', null, proto);
+goog.exportSymbol('google.protobuf.Field.Cardinality', null, proto);
+goog.exportSymbol('google.protobuf.Field.Kind', null, proto);
+goog.exportSymbol('google.protobuf.Option', null, proto);
+goog.exportSymbol('google.protobuf.Syntax', null, proto);
+goog.exportSymbol('google.protobuf.Type', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Type = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Type.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.Type, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Type.displayName = 'proto.google.protobuf.Type';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Field = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Field.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.Field, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Field.displayName = 'proto.google.protobuf.Field';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Enum = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.Enum.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.Enum, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Enum.displayName = 'proto.google.protobuf.Enum';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.EnumValue = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.google.protobuf.EnumValue.repeatedFields_, null);
+};
+goog.inherits(proto.google.protobuf.EnumValue, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.EnumValue.displayName = 'proto.google.protobuf.EnumValue';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Option = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Option, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Option.displayName = 'proto.google.protobuf.Option';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.Type.repeatedFields_ = [2,3,4];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Type.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Type.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Type} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Type.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    fieldsList: jspb.Message.toObjectList(msg.getFieldsList(),
+    proto.google.protobuf.Field.toObject, includeInstance),
+    oneofsList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
+    proto.google.protobuf.Option.toObject, includeInstance),
+    sourceContext: (f = msg.getSourceContext()) && google_protobuf_source_context_pb.SourceContext.toObject(includeInstance, f),
+    syntax: jspb.Message.getFieldWithDefault(msg, 6, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Type}
+ */
+proto.google.protobuf.Type.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Type;
+  return proto.google.protobuf.Type.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Type} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Type}
+ */
+proto.google.protobuf.Type.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new proto.google.protobuf.Field;
+      reader.readMessage(value,proto.google.protobuf.Field.deserializeBinaryFromReader);
+      msg.addFields(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addOneofs(value);
+      break;
+    case 4:
+      var value = new proto.google.protobuf.Option;
+      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
+      msg.addOptions(value);
+      break;
+    case 5:
+      var value = new google_protobuf_source_context_pb.SourceContext;
+      reader.readMessage(value,google_protobuf_source_context_pb.SourceContext.deserializeBinaryFromReader);
+      msg.setSourceContext(value);
+      break;
+    case 6:
+      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
+      msg.setSyntax(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Type.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Type.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Type} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Type.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFieldsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.google.protobuf.Field.serializeBinaryToWriter
+    );
+  }
+  f = message.getOneofsList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getOptionsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      4,
+      f,
+      proto.google.protobuf.Option.serializeBinaryToWriter
+    );
+  }
+  f = message.getSourceContext();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      google_protobuf_source_context_pb.SourceContext.serializeBinaryToWriter
+    );
+  }
+  f = message.getSyntax();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.Type.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated Field fields = 2;
+ * @return {!Array<!proto.google.protobuf.Field>}
+ */
+proto.google.protobuf.Type.prototype.getFieldsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Field>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Field, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Field>} value
+ * @return {!proto.google.protobuf.Type} returns this
+*/
+proto.google.protobuf.Type.prototype.setFieldsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Field=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Field}
+ */
+proto.google.protobuf.Type.prototype.addFields = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.Field, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.clearFieldsList = function() {
+  return this.setFieldsList([]);
+};
+
+
+/**
+ * repeated string oneofs = 3;
+ * @return {!Array<string>}
+ */
+proto.google.protobuf.Type.prototype.getOneofsList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.setOneofsList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.addOneofs = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.clearOneofsList = function() {
+  return this.setOneofsList([]);
+};
+
+
+/**
+ * repeated Option options = 4;
+ * @return {!Array<!proto.google.protobuf.Option>}
+ */
+proto.google.protobuf.Type.prototype.getOptionsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 4));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Option>} value
+ * @return {!proto.google.protobuf.Type} returns this
+*/
+proto.google.protobuf.Type.prototype.setOptionsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 4, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Option=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.Type.prototype.addOptions = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.google.protobuf.Option, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.clearOptionsList = function() {
+  return this.setOptionsList([]);
+};
+
+
+/**
+ * optional SourceContext source_context = 5;
+ * @return {?proto.google.protobuf.SourceContext}
+ */
+proto.google.protobuf.Type.prototype.getSourceContext = function() {
+  return /** @type{?proto.google.protobuf.SourceContext} */ (
+    jspb.Message.getWrapperField(this, google_protobuf_source_context_pb.SourceContext, 5));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.SourceContext|undefined} value
+ * @return {!proto.google.protobuf.Type} returns this
+*/
+proto.google.protobuf.Type.prototype.setSourceContext = function(value) {
+  return jspb.Message.setWrapperField(this, 5, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.clearSourceContext = function() {
+  return this.setSourceContext(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Type.prototype.hasSourceContext = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional Syntax syntax = 6;
+ * @return {!proto.google.protobuf.Syntax}
+ */
+proto.google.protobuf.Type.prototype.getSyntax = function() {
+  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Syntax} value
+ * @return {!proto.google.protobuf.Type} returns this
+ */
+proto.google.protobuf.Type.prototype.setSyntax = function(value) {
+  return jspb.Message.setProto3EnumField(this, 6, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.Field.repeatedFields_ = [9];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Field.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Field.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Field} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Field.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    kind: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    cardinality: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    number: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    name: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    typeUrl: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    oneofIndex: jspb.Message.getFieldWithDefault(msg, 7, 0),
+    packed: jspb.Message.getBooleanFieldWithDefault(msg, 8, false),
+    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
+    proto.google.protobuf.Option.toObject, includeInstance),
+    jsonName: jspb.Message.getFieldWithDefault(msg, 10, ""),
+    defaultValue: jspb.Message.getFieldWithDefault(msg, 11, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Field}
+ */
+proto.google.protobuf.Field.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Field;
+  return proto.google.protobuf.Field.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Field} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Field}
+ */
+proto.google.protobuf.Field.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.google.protobuf.Field.Kind} */ (reader.readEnum());
+      msg.setKind(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.google.protobuf.Field.Cardinality} */ (reader.readEnum());
+      msg.setCardinality(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setNumber(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTypeUrl(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setOneofIndex(value);
+      break;
+    case 8:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setPacked(value);
+      break;
+    case 9:
+      var value = new proto.google.protobuf.Option;
+      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
+      msg.addOptions(value);
+      break;
+    case 10:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setJsonName(value);
+      break;
+    case 11:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDefaultValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Field.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Field.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Field} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Field.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKind();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getCardinality();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+  f = message.getNumber();
+  if (f !== 0) {
+    writer.writeInt32(
+      3,
+      f
+    );
+  }
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getTypeUrl();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
+  f = message.getOneofIndex();
+  if (f !== 0) {
+    writer.writeInt32(
+      7,
+      f
+    );
+  }
+  f = message.getPacked();
+  if (f) {
+    writer.writeBool(
+      8,
+      f
+    );
+  }
+  f = message.getOptionsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      9,
+      f,
+      proto.google.protobuf.Option.serializeBinaryToWriter
+    );
+  }
+  f = message.getJsonName();
+  if (f.length > 0) {
+    writer.writeString(
+      10,
+      f
+    );
+  }
+  f = message.getDefaultValue();
+  if (f.length > 0) {
+    writer.writeString(
+      11,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.Field.Kind = {
+  TYPE_UNKNOWN: 0,
+  TYPE_DOUBLE: 1,
+  TYPE_FLOAT: 2,
+  TYPE_INT64: 3,
+  TYPE_UINT64: 4,
+  TYPE_INT32: 5,
+  TYPE_FIXED64: 6,
+  TYPE_FIXED32: 7,
+  TYPE_BOOL: 8,
+  TYPE_STRING: 9,
+  TYPE_GROUP: 10,
+  TYPE_MESSAGE: 11,
+  TYPE_BYTES: 12,
+  TYPE_UINT32: 13,
+  TYPE_ENUM: 14,
+  TYPE_SFIXED32: 15,
+  TYPE_SFIXED64: 16,
+  TYPE_SINT32: 17,
+  TYPE_SINT64: 18
+};
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.Field.Cardinality = {
+  CARDINALITY_UNKNOWN: 0,
+  CARDINALITY_OPTIONAL: 1,
+  CARDINALITY_REQUIRED: 2,
+  CARDINALITY_REPEATED: 3
+};
+
+/**
+ * optional Kind kind = 1;
+ * @return {!proto.google.protobuf.Field.Kind}
+ */
+proto.google.protobuf.Field.prototype.getKind = function() {
+  return /** @type {!proto.google.protobuf.Field.Kind} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Field.Kind} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setKind = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional Cardinality cardinality = 2;
+ * @return {!proto.google.protobuf.Field.Cardinality}
+ */
+proto.google.protobuf.Field.prototype.getCardinality = function() {
+  return /** @type {!proto.google.protobuf.Field.Cardinality} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Field.Cardinality} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setCardinality = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+/**
+ * optional int32 number = 3;
+ * @return {number}
+ */
+proto.google.protobuf.Field.prototype.getNumber = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setNumber = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional string name = 4;
+ * @return {string}
+ */
+proto.google.protobuf.Field.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * optional string type_url = 6;
+ * @return {string}
+ */
+proto.google.protobuf.Field.prototype.getTypeUrl = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setTypeUrl = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional int32 oneof_index = 7;
+ * @return {number}
+ */
+proto.google.protobuf.Field.prototype.getOneofIndex = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setOneofIndex = function(value) {
+  return jspb.Message.setProto3IntField(this, 7, value);
+};
+
+
+/**
+ * optional bool packed = 8;
+ * @return {boolean}
+ */
+proto.google.protobuf.Field.prototype.getPacked = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setPacked = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 8, value);
+};
+
+
+/**
+ * repeated Option options = 9;
+ * @return {!Array<!proto.google.protobuf.Option>}
+ */
+proto.google.protobuf.Field.prototype.getOptionsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 9));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Option>} value
+ * @return {!proto.google.protobuf.Field} returns this
+*/
+proto.google.protobuf.Field.prototype.setOptionsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 9, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Option=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.Field.prototype.addOptions = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.google.protobuf.Option, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.clearOptionsList = function() {
+  return this.setOptionsList([]);
+};
+
+
+/**
+ * optional string json_name = 10;
+ * @return {string}
+ */
+proto.google.protobuf.Field.prototype.getJsonName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 10, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setJsonName = function(value) {
+  return jspb.Message.setProto3StringField(this, 10, value);
+};
+
+
+/**
+ * optional string default_value = 11;
+ * @return {string}
+ */
+proto.google.protobuf.Field.prototype.getDefaultValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 11, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Field} returns this
+ */
+proto.google.protobuf.Field.prototype.setDefaultValue = function(value) {
+  return jspb.Message.setProto3StringField(this, 11, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.Enum.repeatedFields_ = [2,3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Enum.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Enum.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Enum} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Enum.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    enumvalueList: jspb.Message.toObjectList(msg.getEnumvalueList(),
+    proto.google.protobuf.EnumValue.toObject, includeInstance),
+    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
+    proto.google.protobuf.Option.toObject, includeInstance),
+    sourceContext: (f = msg.getSourceContext()) && google_protobuf_source_context_pb.SourceContext.toObject(includeInstance, f),
+    syntax: jspb.Message.getFieldWithDefault(msg, 5, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Enum}
+ */
+proto.google.protobuf.Enum.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Enum;
+  return proto.google.protobuf.Enum.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Enum} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Enum}
+ */
+proto.google.protobuf.Enum.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new proto.google.protobuf.EnumValue;
+      reader.readMessage(value,proto.google.protobuf.EnumValue.deserializeBinaryFromReader);
+      msg.addEnumvalue(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.Option;
+      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
+      msg.addOptions(value);
+      break;
+    case 4:
+      var value = new google_protobuf_source_context_pb.SourceContext;
+      reader.readMessage(value,google_protobuf_source_context_pb.SourceContext.deserializeBinaryFromReader);
+      msg.setSourceContext(value);
+      break;
+    case 5:
+      var value = /** @type {!proto.google.protobuf.Syntax} */ (reader.readEnum());
+      msg.setSyntax(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Enum.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Enum.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Enum} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Enum.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getEnumvalueList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      proto.google.protobuf.EnumValue.serializeBinaryToWriter
+    );
+  }
+  f = message.getOptionsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      3,
+      f,
+      proto.google.protobuf.Option.serializeBinaryToWriter
+    );
+  }
+  f = message.getSourceContext();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      google_protobuf_source_context_pb.SourceContext.serializeBinaryToWriter
+    );
+  }
+  f = message.getSyntax();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.Enum.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Enum} returns this
+ */
+proto.google.protobuf.Enum.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated EnumValue enumvalue = 2;
+ * @return {!Array<!proto.google.protobuf.EnumValue>}
+ */
+proto.google.protobuf.Enum.prototype.getEnumvalueList = function() {
+  return /** @type{!Array<!proto.google.protobuf.EnumValue>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.EnumValue, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.EnumValue>} value
+ * @return {!proto.google.protobuf.Enum} returns this
+*/
+proto.google.protobuf.Enum.prototype.setEnumvalueList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.EnumValue=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.EnumValue}
+ */
+proto.google.protobuf.Enum.prototype.addEnumvalue = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.google.protobuf.EnumValue, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Enum} returns this
+ */
+proto.google.protobuf.Enum.prototype.clearEnumvalueList = function() {
+  return this.setEnumvalueList([]);
+};
+
+
+/**
+ * repeated Option options = 3;
+ * @return {!Array<!proto.google.protobuf.Option>}
+ */
+proto.google.protobuf.Enum.prototype.getOptionsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 3));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Option>} value
+ * @return {!proto.google.protobuf.Enum} returns this
+*/
+proto.google.protobuf.Enum.prototype.setOptionsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 3, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Option=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.Enum.prototype.addOptions = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.Option, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.Enum} returns this
+ */
+proto.google.protobuf.Enum.prototype.clearOptionsList = function() {
+  return this.setOptionsList([]);
+};
+
+
+/**
+ * optional SourceContext source_context = 4;
+ * @return {?proto.google.protobuf.SourceContext}
+ */
+proto.google.protobuf.Enum.prototype.getSourceContext = function() {
+  return /** @type{?proto.google.protobuf.SourceContext} */ (
+    jspb.Message.getWrapperField(this, google_protobuf_source_context_pb.SourceContext, 4));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.SourceContext|undefined} value
+ * @return {!proto.google.protobuf.Enum} returns this
+*/
+proto.google.protobuf.Enum.prototype.setSourceContext = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.Enum} returns this
+ */
+proto.google.protobuf.Enum.prototype.clearSourceContext = function() {
+  return this.setSourceContext(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Enum.prototype.hasSourceContext = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional Syntax syntax = 5;
+ * @return {!proto.google.protobuf.Syntax}
+ */
+proto.google.protobuf.Enum.prototype.getSyntax = function() {
+  return /** @type {!proto.google.protobuf.Syntax} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Syntax} value
+ * @return {!proto.google.protobuf.Enum} returns this
+ */
+proto.google.protobuf.Enum.prototype.setSyntax = function(value) {
+  return jspb.Message.setProto3EnumField(this, 5, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.google.protobuf.EnumValue.repeatedFields_ = [3];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.EnumValue.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.EnumValue.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.EnumValue} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumValue.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    number: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    optionsList: jspb.Message.toObjectList(msg.getOptionsList(),
+    proto.google.protobuf.Option.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.EnumValue}
+ */
+proto.google.protobuf.EnumValue.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.EnumValue;
+  return proto.google.protobuf.EnumValue.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.EnumValue} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.EnumValue}
+ */
+proto.google.protobuf.EnumValue.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setNumber(value);
+      break;
+    case 3:
+      var value = new proto.google.protobuf.Option;
+      reader.readMessage(value,proto.google.protobuf.Option.deserializeBinaryFromReader);
+      msg.addOptions(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.EnumValue.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.EnumValue.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.EnumValue} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.EnumValue.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getNumber();
+  if (f !== 0) {
+    writer.writeInt32(
+      2,
+      f
+    );
+  }
+  f = message.getOptionsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      3,
+      f,
+      proto.google.protobuf.Option.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.EnumValue.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.EnumValue} returns this
+ */
+proto.google.protobuf.EnumValue.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int32 number = 2;
+ * @return {number}
+ */
+proto.google.protobuf.EnumValue.prototype.getNumber = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.EnumValue} returns this
+ */
+proto.google.protobuf.EnumValue.prototype.setNumber = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * repeated Option options = 3;
+ * @return {!Array<!proto.google.protobuf.Option>}
+ */
+proto.google.protobuf.EnumValue.prototype.getOptionsList = function() {
+  return /** @type{!Array<!proto.google.protobuf.Option>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.google.protobuf.Option, 3));
+};
+
+
+/**
+ * @param {!Array<!proto.google.protobuf.Option>} value
+ * @return {!proto.google.protobuf.EnumValue} returns this
+*/
+proto.google.protobuf.EnumValue.prototype.setOptionsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 3, value);
+};
+
+
+/**
+ * @param {!proto.google.protobuf.Option=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.EnumValue.prototype.addOptions = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.google.protobuf.Option, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.google.protobuf.EnumValue} returns this
+ */
+proto.google.protobuf.EnumValue.prototype.clearOptionsList = function() {
+  return this.setOptionsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Option.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Option.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Option} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Option.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    value: (f = msg.getValue()) && google_protobuf_any_pb.Any.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.Option.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Option;
+  return proto.google.protobuf.Option.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Option} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Option}
+ */
+proto.google.protobuf.Option.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = new google_protobuf_any_pb.Any;
+      reader.readMessage(value,google_protobuf_any_pb.Any.deserializeBinaryFromReader);
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Option.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Option.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Option} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Option.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getValue();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      google_protobuf_any_pb.Any.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.google.protobuf.Option.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.Option} returns this
+ */
+proto.google.protobuf.Option.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional Any value = 2;
+ * @return {?proto.google.protobuf.Any}
+ */
+proto.google.protobuf.Option.prototype.getValue = function() {
+  return /** @type{?proto.google.protobuf.Any} */ (
+    jspb.Message.getWrapperField(this, google_protobuf_any_pb.Any, 2));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.Any|undefined} value
+ * @return {!proto.google.protobuf.Option} returns this
+*/
+proto.google.protobuf.Option.prototype.setValue = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.google.protobuf.Option} returns this
+ */
+proto.google.protobuf.Option.prototype.clearValue = function() {
+  return this.setValue(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.google.protobuf.Option.prototype.hasValue = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.google.protobuf.Syntax = {
+  SYNTAX_PROTO2: 0,
+  SYNTAX_PROTO3: 1
+};
+
+goog.object.extend(exports, proto);
diff --git a/src/third_party/google-protobuf-commonjs_strict/google/protobuf/wrappers_pb.js b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/wrappers_pb.js
new file mode 100644
index 0000000..75b7a26
--- /dev/null
+++ b/src/third_party/google-protobuf-commonjs_strict/google/protobuf/wrappers_pb.js
@@ -0,0 +1,1410 @@
+// source: google/protobuf/wrappers.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var proto = {};
+
+goog.exportSymbol('google.protobuf.BoolValue', null, proto);
+goog.exportSymbol('google.protobuf.BytesValue', null, proto);
+goog.exportSymbol('google.protobuf.DoubleValue', null, proto);
+goog.exportSymbol('google.protobuf.FloatValue', null, proto);
+goog.exportSymbol('google.protobuf.Int32Value', null, proto);
+goog.exportSymbol('google.protobuf.Int64Value', null, proto);
+goog.exportSymbol('google.protobuf.StringValue', null, proto);
+goog.exportSymbol('google.protobuf.UInt32Value', null, proto);
+goog.exportSymbol('google.protobuf.UInt64Value', null, proto);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.DoubleValue = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.DoubleValue, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.DoubleValue.displayName = 'proto.google.protobuf.DoubleValue';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.FloatValue = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.FloatValue, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.FloatValue.displayName = 'proto.google.protobuf.FloatValue';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Int64Value = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Int64Value, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Int64Value.displayName = 'proto.google.protobuf.Int64Value';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.UInt64Value = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.UInt64Value, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.UInt64Value.displayName = 'proto.google.protobuf.UInt64Value';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.Int32Value = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.Int32Value, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.Int32Value.displayName = 'proto.google.protobuf.Int32Value';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.UInt32Value = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.UInt32Value, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.UInt32Value.displayName = 'proto.google.protobuf.UInt32Value';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.BoolValue = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.BoolValue, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.BoolValue.displayName = 'proto.google.protobuf.BoolValue';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.StringValue = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.StringValue, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.StringValue.displayName = 'proto.google.protobuf.StringValue';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.google.protobuf.BytesValue = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.google.protobuf.BytesValue, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.google.protobuf.BytesValue.displayName = 'proto.google.protobuf.BytesValue';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.DoubleValue.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.DoubleValue.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.DoubleValue} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DoubleValue.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getFloatingPointFieldWithDefault(msg, 1, 0.0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.DoubleValue}
+ */
+proto.google.protobuf.DoubleValue.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.DoubleValue;
+  return proto.google.protobuf.DoubleValue.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.DoubleValue} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.DoubleValue}
+ */
+proto.google.protobuf.DoubleValue.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readDouble());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.DoubleValue.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.DoubleValue.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.DoubleValue} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.DoubleValue.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f !== 0.0) {
+    writer.writeDouble(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional double value = 1;
+ * @return {number}
+ */
+proto.google.protobuf.DoubleValue.prototype.getValue = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 1, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.DoubleValue} returns this
+ */
+proto.google.protobuf.DoubleValue.prototype.setValue = function(value) {
+  return jspb.Message.setProto3FloatField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.FloatValue.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.FloatValue.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.FloatValue} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FloatValue.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getFloatingPointFieldWithDefault(msg, 1, 0.0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.FloatValue}
+ */
+proto.google.protobuf.FloatValue.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.FloatValue;
+  return proto.google.protobuf.FloatValue.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.FloatValue} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.FloatValue}
+ */
+proto.google.protobuf.FloatValue.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readFloat());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.FloatValue.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.FloatValue.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.FloatValue} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.FloatValue.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f !== 0.0) {
+    writer.writeFloat(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional float value = 1;
+ * @return {number}
+ */
+proto.google.protobuf.FloatValue.prototype.getValue = function() {
+  return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 1, 0.0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.FloatValue} returns this
+ */
+proto.google.protobuf.FloatValue.prototype.setValue = function(value) {
+  return jspb.Message.setProto3FloatField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Int64Value.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Int64Value.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Int64Value} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Int64Value.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Int64Value}
+ */
+proto.google.protobuf.Int64Value.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Int64Value;
+  return proto.google.protobuf.Int64Value.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Int64Value} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Int64Value}
+ */
+proto.google.protobuf.Int64Value.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Int64Value.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Int64Value.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Int64Value} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Int64Value.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f !== 0) {
+    writer.writeInt64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int64 value = 1;
+ * @return {number}
+ */
+proto.google.protobuf.Int64Value.prototype.getValue = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Int64Value} returns this
+ */
+proto.google.protobuf.Int64Value.prototype.setValue = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.UInt64Value.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.UInt64Value.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.UInt64Value} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UInt64Value.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.UInt64Value}
+ */
+proto.google.protobuf.UInt64Value.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.UInt64Value;
+  return proto.google.protobuf.UInt64Value.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.UInt64Value} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.UInt64Value}
+ */
+proto.google.protobuf.UInt64Value.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.UInt64Value.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.UInt64Value.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.UInt64Value} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UInt64Value.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f !== 0) {
+    writer.writeUint64(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional uint64 value = 1;
+ * @return {number}
+ */
+proto.google.protobuf.UInt64Value.prototype.getValue = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.UInt64Value} returns this
+ */
+proto.google.protobuf.UInt64Value.prototype.setValue = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.Int32Value.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.Int32Value.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.Int32Value} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Int32Value.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.Int32Value}
+ */
+proto.google.protobuf.Int32Value.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.Int32Value;
+  return proto.google.protobuf.Int32Value.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.Int32Value} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.Int32Value}
+ */
+proto.google.protobuf.Int32Value.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.Int32Value.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.Int32Value.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.Int32Value} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.Int32Value.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 value = 1;
+ * @return {number}
+ */
+proto.google.protobuf.Int32Value.prototype.getValue = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.Int32Value} returns this
+ */
+proto.google.protobuf.Int32Value.prototype.setValue = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.UInt32Value.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.UInt32Value.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.UInt32Value} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UInt32Value.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.UInt32Value}
+ */
+proto.google.protobuf.UInt32Value.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.UInt32Value;
+  return proto.google.protobuf.UInt32Value.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.UInt32Value} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.UInt32Value}
+ */
+proto.google.protobuf.UInt32Value.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.UInt32Value.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.UInt32Value.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.UInt32Value} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.UInt32Value.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f !== 0) {
+    writer.writeUint32(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional uint32 value = 1;
+ * @return {number}
+ */
+proto.google.protobuf.UInt32Value.prototype.getValue = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.google.protobuf.UInt32Value} returns this
+ */
+proto.google.protobuf.UInt32Value.prototype.setValue = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.BoolValue.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.BoolValue.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.BoolValue} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.BoolValue.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.BoolValue}
+ */
+proto.google.protobuf.BoolValue.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.BoolValue;
+  return proto.google.protobuf.BoolValue.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.BoolValue} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.BoolValue}
+ */
+proto.google.protobuf.BoolValue.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.BoolValue.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.BoolValue.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.BoolValue} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.BoolValue.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool value = 1;
+ * @return {boolean}
+ */
+proto.google.protobuf.BoolValue.prototype.getValue = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.google.protobuf.BoolValue} returns this
+ */
+proto.google.protobuf.BoolValue.prototype.setValue = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.StringValue.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.StringValue.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.StringValue} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.StringValue.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.StringValue}
+ */
+proto.google.protobuf.StringValue.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.StringValue;
+  return proto.google.protobuf.StringValue.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.StringValue} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.StringValue}
+ */
+proto.google.protobuf.StringValue.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.StringValue.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.StringValue.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.StringValue} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.StringValue.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string value = 1;
+ * @return {string}
+ */
+proto.google.protobuf.StringValue.prototype.getValue = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.google.protobuf.StringValue} returns this
+ */
+proto.google.protobuf.StringValue.prototype.setValue = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.google.protobuf.BytesValue.prototype.toObject = function(opt_includeInstance) {
+  return proto.google.protobuf.BytesValue.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.google.protobuf.BytesValue} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.BytesValue.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    value: msg.getValue_asB64()
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.google.protobuf.BytesValue}
+ */
+proto.google.protobuf.BytesValue.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.google.protobuf.BytesValue;
+  return proto.google.protobuf.BytesValue.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.google.protobuf.BytesValue} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.google.protobuf.BytesValue}
+ */
+proto.google.protobuf.BytesValue.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!Uint8Array} */ (reader.readBytes());
+      msg.setValue(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.BytesValue.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.google.protobuf.BytesValue.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.google.protobuf.BytesValue} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.google.protobuf.BytesValue.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getValue_asU8();
+  if (f.length > 0) {
+    writer.writeBytes(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bytes value = 1;
+ * @return {!(string|Uint8Array)}
+ */
+proto.google.protobuf.BytesValue.prototype.getValue = function() {
+  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * optional bytes value = 1;
+ * This is a type-conversion wrapper around `getValue()`
+ * @return {string}
+ */
+proto.google.protobuf.BytesValue.prototype.getValue_asB64 = function() {
+  return /** @type {string} */ (jspb.Message.bytesAsB64(
+      this.getValue()));
+};
+
+
+/**
+ * optional bytes value = 1;
+ * Note that Uint8Array is not supported on all browsers.
+ * @see http://caniuse.com/Uint8Array
+ * This is a type-conversion wrapper around `getValue()`
+ * @return {!Uint8Array}
+ */
+proto.google.protobuf.BytesValue.prototype.getValue_asU8 = function() {
+  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
+      this.getValue()));
+};
+
+
+/**
+ * @param {!(string|Uint8Array)} value
+ * @return {!proto.google.protobuf.BytesValue} returns this
+ */
+proto.google.protobuf.BytesValue.prototype.setValue = function(value) {
+  return jspb.Message.setProto3BytesField(this, 1, value);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/templates/manifest.gjson b/templates/manifest.gjson
index 8a9fe9d..957193f 100644
--- a/templates/manifest.gjson
+++ b/templates/manifest.gjson
@@ -52,7 +52,8 @@
 #if defined(CHROMIUM || GECKO)
     "https://support.google.com/*",
 #endif
-    "storage"
+    "storage",
+    "alarms"
   ],
 #if defined(CHROMIUM_MV3)
   "host_permissions": [
diff --git a/webpack.config.js b/webpack.config.js
index 615ae14..7d71978 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,3 +1,4 @@
+const webpack = require('webpack');
 const path = require('path');
 const json5 = require('json5');
 const CopyWebpackPlugin = require('copy-webpack-plugin');
@@ -85,6 +86,9 @@
           },
         ]
       }),
+      new webpack.DefinePlugin({
+        'PRODUCTION': args.mode == 'production',
+      }),
       ...getCopyPluginsForOverridenLocales(outputPath),
     ],
     // NOTE: Change to
