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