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);
