// source: api_proto/kill_switch_objects.proto
/**
 * @fileoverview
 * @enhanceable
 * @suppress {missingRequire} reports error on implicit type usages.
 * @suppress {messageConventions} JS Compiler reports an error if a variable or
 *     field starts with 'MSG_' and isn't a translatable message.
 * @public
 */
// GENERATED CODE -- DO NOT EDIT!
/* eslint-disable */
// @ts-nocheck

var jspb = require('google-protobuf');
var goog = jspb;
var proto = {};

var api_proto_common_pb = require('../api_proto/common_pb.js');
goog.object.extend(proto, api_proto_common_pb);
var google_protobuf_timestamp_pb = require('google-protobuf/google/protobuf/timestamp_pb.js');
goog.object.extend(proto, google_protobuf_timestamp_pb);
goog.exportSymbol('AuthorizedUserTransformation', null, proto);
goog.exportSymbol('Feature', null, proto);
goog.exportSymbol('Feature.Type', null, proto);
goog.exportSymbol('KillSwitch', null, proto);
goog.exportSymbol('KillSwitchAuditLogEntry', null, proto);
goog.exportSymbol('KillSwitchAuditLogEntry.AuthorizedUserAdded', null, proto);
goog.exportSymbol('KillSwitchAuditLogEntry.AuthorizedUserDeleted', null, proto);
goog.exportSymbol('KillSwitchAuditLogEntry.AuthorizedUserUpdated', null, proto);
goog.exportSymbol('KillSwitchAuditLogEntry.DescriptionCase', null, proto);
goog.exportSymbol('KillSwitchAuditLogEntry.KillSwitchDisabled', null, proto);
goog.exportSymbol('KillSwitchAuditLogEntry.KillSwitchEnabled', null, proto);
goog.exportSymbol('KillSwitchAuthorizedUser', null, proto);
goog.exportSymbol('KillSwitchAuthorizedUser.AccessLevel', null, proto);
goog.exportSymbol('KillSwitchTransformation', null, proto);
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.Feature = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.Feature, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.Feature.displayName = 'proto.Feature';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitch = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, proto.KillSwitch.repeatedFields_, null);
};
goog.inherits(proto.KillSwitch, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitch.displayName = 'proto.KillSwitch';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchAuthorizedUser = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.KillSwitchAuthorizedUser, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchAuthorizedUser.displayName = 'proto.KillSwitchAuthorizedUser';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchTransformation = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.KillSwitchTransformation, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchTransformation.displayName = 'proto.KillSwitchTransformation';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.AuthorizedUserTransformation = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.AuthorizedUserTransformation, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.AuthorizedUserTransformation.displayName = 'proto.AuthorizedUserTransformation';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchAuditLogEntry = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.KillSwitchAuditLogEntry.oneofGroups_);
};
goog.inherits(proto.KillSwitchAuditLogEntry, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchAuditLogEntry.displayName = 'proto.KillSwitchAuditLogEntry';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.KillSwitchAuditLogEntry.KillSwitchEnabled, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchAuditLogEntry.KillSwitchEnabled.displayName = 'proto.KillSwitchAuditLogEntry.KillSwitchEnabled';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.KillSwitchAuditLogEntry.KillSwitchDisabled, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchAuditLogEntry.KillSwitchDisabled.displayName = 'proto.KillSwitchAuditLogEntry.KillSwitchDisabled';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserAdded, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserAdded';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted';
}



if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.Feature.prototype.toObject = function(opt_includeInstance) {
  return proto.Feature.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.Feature} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.Feature.toObject = function(includeInstance, msg) {
  var f, obj = {
    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
    codename: jspb.Message.getFieldWithDefault(msg, 2, ""),
    type: jspb.Message.getFieldWithDefault(msg, 3, 0)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.Feature}
 */
proto.Feature.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.Feature;
  return proto.Feature.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.Feature} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.Feature}
 */
proto.Feature.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {number} */ (reader.readInt32());
      msg.setId(value);
      break;
    case 2:
      var value = /** @type {string} */ (reader.readString());
      msg.setCodename(value);
      break;
    case 3:
      var value = /** @type {!proto.Feature.Type} */ (reader.readEnum());
      msg.setType(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.Feature.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.Feature.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.Feature} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.Feature.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getId();
  if (f !== 0) {
    writer.writeInt32(
      1,
      f
    );
  }
  f = message.getCodename();
  if (f.length > 0) {
    writer.writeString(
      2,
      f
    );
  }
  f = message.getType();
  if (f !== 0.0) {
    writer.writeEnum(
      3,
      f
    );
  }
};


/**
 * @enum {number}
 */
proto.Feature.Type = {
  TYPE_UNKNOWN: 0,
  TYPE_EXPERIMENT: 1,
  TYPE_OPTION: 2,
  TYPE_INTERNAL_KILL_SWITCH: 3,
  TYPE_DEPRECATED: 10
};

/**
 * optional int32 id = 1;
 * @return {number}
 */
proto.Feature.prototype.getId = function() {
  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


/**
 * @param {number} value
 * @return {!proto.Feature} returns this
 */
proto.Feature.prototype.setId = function(value) {
  return jspb.Message.setProto3IntField(this, 1, value);
};


/**
 * optional string codename = 2;
 * @return {string}
 */
proto.Feature.prototype.getCodename = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
};


/**
 * @param {string} value
 * @return {!proto.Feature} returns this
 */
proto.Feature.prototype.setCodename = function(value) {
  return jspb.Message.setProto3StringField(this, 2, value);
};


/**
 * optional Type type = 3;
 * @return {!proto.Feature.Type}
 */
proto.Feature.prototype.getType = function() {
  return /** @type {!proto.Feature.Type} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
};


/**
 * @param {!proto.Feature.Type} value
 * @return {!proto.Feature} returns this
 */
proto.Feature.prototype.setType = function(value) {
  return jspb.Message.setProto3EnumField(this, 3, value);
};



/**
 * List of repeated fields within this message type.
 * @private {!Array<number>}
 * @const
 */
proto.KillSwitch.repeatedFields_ = [5];



if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitch.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitch.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitch} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitch.toObject = function(includeInstance, msg) {
  var f, obj = {
    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
    feature: (f = msg.getFeature()) && proto.Feature.toObject(includeInstance, f),
    minVersion: jspb.Message.getFieldWithDefault(msg, 3, ""),
    maxVersion: jspb.Message.getFieldWithDefault(msg, 4, ""),
    browsersList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
    active: jspb.Message.getBooleanFieldWithDefault(msg, 6, false)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitch}
 */
proto.KillSwitch.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitch;
  return proto.KillSwitch.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitch} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitch}
 */
proto.KillSwitch.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {number} */ (reader.readInt32());
      msg.setId(value);
      break;
    case 2:
      var value = new proto.Feature;
      reader.readMessage(value,proto.Feature.deserializeBinaryFromReader);
      msg.setFeature(value);
      break;
    case 3:
      var value = /** @type {string} */ (reader.readString());
      msg.setMinVersion(value);
      break;
    case 4:
      var value = /** @type {string} */ (reader.readString());
      msg.setMaxVersion(value);
      break;
    case 5:
      var values = /** @type {!Array<!proto.Environment.Browser>} */ (reader.isDelimited() ? reader.readPackedEnum() : [reader.readEnum()]);
      for (var i = 0; i < values.length; i++) {
        msg.addBrowsers(values[i]);
      }
      break;
    case 6:
      var value = /** @type {boolean} */ (reader.readBool());
      msg.setActive(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitch.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitch.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitch} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitch.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getId();
  if (f !== 0) {
    writer.writeInt32(
      1,
      f
    );
  }
  f = message.getFeature();
  if (f != null) {
    writer.writeMessage(
      2,
      f,
      proto.Feature.serializeBinaryToWriter
    );
  }
  f = message.getMinVersion();
  if (f.length > 0) {
    writer.writeString(
      3,
      f
    );
  }
  f = message.getMaxVersion();
  if (f.length > 0) {
    writer.writeString(
      4,
      f
    );
  }
  f = message.getBrowsersList();
  if (f.length > 0) {
    writer.writePackedEnum(
      5,
      f
    );
  }
  f = message.getActive();
  if (f) {
    writer.writeBool(
      6,
      f
    );
  }
};


/**
 * optional int32 id = 1;
 * @return {number}
 */
proto.KillSwitch.prototype.getId = function() {
  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


/**
 * @param {number} value
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.setId = function(value) {
  return jspb.Message.setProto3IntField(this, 1, value);
};


/**
 * optional Feature feature = 2;
 * @return {?proto.Feature}
 */
proto.KillSwitch.prototype.getFeature = function() {
  return /** @type{?proto.Feature} */ (
    jspb.Message.getWrapperField(this, proto.Feature, 2));
};


/**
 * @param {?proto.Feature|undefined} value
 * @return {!proto.KillSwitch} returns this
*/
proto.KillSwitch.prototype.setFeature = function(value) {
  return jspb.Message.setWrapperField(this, 2, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.clearFeature = function() {
  return this.setFeature(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitch.prototype.hasFeature = function() {
  return jspb.Message.getField(this, 2) != null;
};


/**
 * optional string min_version = 3;
 * @return {string}
 */
proto.KillSwitch.prototype.getMinVersion = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
};


/**
 * @param {string} value
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.setMinVersion = function(value) {
  return jspb.Message.setProto3StringField(this, 3, value);
};


/**
 * optional string max_version = 4;
 * @return {string}
 */
proto.KillSwitch.prototype.getMaxVersion = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
};


/**
 * @param {string} value
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.setMaxVersion = function(value) {
  return jspb.Message.setProto3StringField(this, 4, value);
};


/**
 * repeated Environment.Browser browsers = 5;
 * @return {!Array<!proto.Environment.Browser>}
 */
proto.KillSwitch.prototype.getBrowsersList = function() {
  return /** @type {!Array<!proto.Environment.Browser>} */ (jspb.Message.getRepeatedField(this, 5));
};


/**
 * @param {!Array<!proto.Environment.Browser>} value
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.setBrowsersList = function(value) {
  return jspb.Message.setField(this, 5, value || []);
};


/**
 * @param {!proto.Environment.Browser} value
 * @param {number=} opt_index
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.addBrowsers = function(value, opt_index) {
  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
};


/**
 * Clears the list making it empty but non-null.
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.clearBrowsersList = function() {
  return this.setBrowsersList([]);
};


/**
 * optional bool active = 6;
 * @return {boolean}
 */
proto.KillSwitch.prototype.getActive = function() {
  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
};


/**
 * @param {boolean} value
 * @return {!proto.KillSwitch} returns this
 */
proto.KillSwitch.prototype.setActive = function(value) {
  return jspb.Message.setProto3BooleanField(this, 6, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchAuthorizedUser.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchAuthorizedUser.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchAuthorizedUser} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuthorizedUser.toObject = function(includeInstance, msg) {
  var f, obj = {
    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
    googleUid: jspb.Message.getFieldWithDefault(msg, 2, ""),
    email: jspb.Message.getFieldWithDefault(msg, 3, ""),
    accessLevel: jspb.Message.getFieldWithDefault(msg, 4, 0)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchAuthorizedUser}
 */
proto.KillSwitchAuthorizedUser.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchAuthorizedUser;
  return proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchAuthorizedUser} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchAuthorizedUser}
 */
proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {number} */ (reader.readInt32());
      msg.setId(value);
      break;
    case 2:
      var value = /** @type {string} */ (reader.readString());
      msg.setGoogleUid(value);
      break;
    case 3:
      var value = /** @type {string} */ (reader.readString());
      msg.setEmail(value);
      break;
    case 4:
      var value = /** @type {!proto.KillSwitchAuthorizedUser.AccessLevel} */ (reader.readEnum());
      msg.setAccessLevel(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchAuthorizedUser.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchAuthorizedUser.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchAuthorizedUser} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuthorizedUser.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getId();
  if (f !== 0) {
    writer.writeInt32(
      1,
      f
    );
  }
  f = message.getGoogleUid();
  if (f.length > 0) {
    writer.writeString(
      2,
      f
    );
  }
  f = message.getEmail();
  if (f.length > 0) {
    writer.writeString(
      3,
      f
    );
  }
  f = message.getAccessLevel();
  if (f !== 0.0) {
    writer.writeEnum(
      4,
      f
    );
  }
};


/**
 * @enum {number}
 */
proto.KillSwitchAuthorizedUser.AccessLevel = {
  ACCESS_LEVEL_NONE: 0,
  ACCESS_LEVEL_ACTIVATOR: 5,
  ACCESS_LEVEL_ADMIN: 10
};

/**
 * optional int32 id = 1;
 * @return {number}
 */
proto.KillSwitchAuthorizedUser.prototype.getId = function() {
  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


/**
 * @param {number} value
 * @return {!proto.KillSwitchAuthorizedUser} returns this
 */
proto.KillSwitchAuthorizedUser.prototype.setId = function(value) {
  return jspb.Message.setProto3IntField(this, 1, value);
};


/**
 * optional string google_uid = 2;
 * @return {string}
 */
proto.KillSwitchAuthorizedUser.prototype.getGoogleUid = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
};


/**
 * @param {string} value
 * @return {!proto.KillSwitchAuthorizedUser} returns this
 */
proto.KillSwitchAuthorizedUser.prototype.setGoogleUid = function(value) {
  return jspb.Message.setProto3StringField(this, 2, value);
};


/**
 * optional string email = 3;
 * @return {string}
 */
proto.KillSwitchAuthorizedUser.prototype.getEmail = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
};


/**
 * @param {string} value
 * @return {!proto.KillSwitchAuthorizedUser} returns this
 */
proto.KillSwitchAuthorizedUser.prototype.setEmail = function(value) {
  return jspb.Message.setProto3StringField(this, 3, value);
};


/**
 * optional AccessLevel access_level = 4;
 * @return {!proto.KillSwitchAuthorizedUser.AccessLevel}
 */
proto.KillSwitchAuthorizedUser.prototype.getAccessLevel = function() {
  return /** @type {!proto.KillSwitchAuthorizedUser.AccessLevel} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
};


/**
 * @param {!proto.KillSwitchAuthorizedUser.AccessLevel} value
 * @return {!proto.KillSwitchAuthorizedUser} returns this
 */
proto.KillSwitchAuthorizedUser.prototype.setAccessLevel = function(value) {
  return jspb.Message.setProto3EnumField(this, 4, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchTransformation.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchTransformation.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchTransformation} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchTransformation.toObject = function(includeInstance, msg) {
  var f, obj = {
    old: (f = msg.getOld()) && proto.KillSwitch.toObject(includeInstance, f),
    pb_new: (f = msg.getNew()) && proto.KillSwitch.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchTransformation}
 */
proto.KillSwitchTransformation.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchTransformation;
  return proto.KillSwitchTransformation.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchTransformation} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchTransformation}
 */
proto.KillSwitchTransformation.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.KillSwitch;
      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
      msg.setOld(value);
      break;
    case 2:
      var value = new proto.KillSwitch;
      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
      msg.setNew(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchTransformation.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchTransformation.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchTransformation} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchTransformation.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getOld();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.KillSwitch.serializeBinaryToWriter
    );
  }
  f = message.getNew();
  if (f != null) {
    writer.writeMessage(
      2,
      f,
      proto.KillSwitch.serializeBinaryToWriter
    );
  }
};


/**
 * optional KillSwitch old = 1;
 * @return {?proto.KillSwitch}
 */
proto.KillSwitchTransformation.prototype.getOld = function() {
  return /** @type{?proto.KillSwitch} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitch, 1));
};


/**
 * @param {?proto.KillSwitch|undefined} value
 * @return {!proto.KillSwitchTransformation} returns this
*/
proto.KillSwitchTransformation.prototype.setOld = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchTransformation} returns this
 */
proto.KillSwitchTransformation.prototype.clearOld = function() {
  return this.setOld(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchTransformation.prototype.hasOld = function() {
  return jspb.Message.getField(this, 1) != null;
};


/**
 * optional KillSwitch new = 2;
 * @return {?proto.KillSwitch}
 */
proto.KillSwitchTransformation.prototype.getNew = function() {
  return /** @type{?proto.KillSwitch} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitch, 2));
};


/**
 * @param {?proto.KillSwitch|undefined} value
 * @return {!proto.KillSwitchTransformation} returns this
*/
proto.KillSwitchTransformation.prototype.setNew = function(value) {
  return jspb.Message.setWrapperField(this, 2, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchTransformation} returns this
 */
proto.KillSwitchTransformation.prototype.clearNew = function() {
  return this.setNew(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchTransformation.prototype.hasNew = function() {
  return jspb.Message.getField(this, 2) != null;
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.AuthorizedUserTransformation.prototype.toObject = function(opt_includeInstance) {
  return proto.AuthorizedUserTransformation.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.AuthorizedUserTransformation} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.AuthorizedUserTransformation.toObject = function(includeInstance, msg) {
  var f, obj = {
    old: (f = msg.getOld()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f),
    pb_new: (f = msg.getNew()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.AuthorizedUserTransformation}
 */
proto.AuthorizedUserTransformation.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.AuthorizedUserTransformation;
  return proto.AuthorizedUserTransformation.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.AuthorizedUserTransformation} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.AuthorizedUserTransformation}
 */
proto.AuthorizedUserTransformation.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.KillSwitchAuthorizedUser;
      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
      msg.setOld(value);
      break;
    case 2:
      var value = new proto.KillSwitchAuthorizedUser;
      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
      msg.setNew(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.AuthorizedUserTransformation.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.AuthorizedUserTransformation.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.AuthorizedUserTransformation} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.AuthorizedUserTransformation.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getOld();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
    );
  }
  f = message.getNew();
  if (f != null) {
    writer.writeMessage(
      2,
      f,
      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
    );
  }
};


/**
 * optional KillSwitchAuthorizedUser old = 1;
 * @return {?proto.KillSwitchAuthorizedUser}
 */
proto.AuthorizedUserTransformation.prototype.getOld = function() {
  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
};


/**
 * @param {?proto.KillSwitchAuthorizedUser|undefined} value
 * @return {!proto.AuthorizedUserTransformation} returns this
*/
proto.AuthorizedUserTransformation.prototype.setOld = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.AuthorizedUserTransformation} returns this
 */
proto.AuthorizedUserTransformation.prototype.clearOld = function() {
  return this.setOld(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.AuthorizedUserTransformation.prototype.hasOld = function() {
  return jspb.Message.getField(this, 1) != null;
};


/**
 * optional KillSwitchAuthorizedUser new = 2;
 * @return {?proto.KillSwitchAuthorizedUser}
 */
proto.AuthorizedUserTransformation.prototype.getNew = function() {
  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 2));
};


/**
 * @param {?proto.KillSwitchAuthorizedUser|undefined} value
 * @return {!proto.AuthorizedUserTransformation} returns this
*/
proto.AuthorizedUserTransformation.prototype.setNew = function(value) {
  return jspb.Message.setWrapperField(this, 2, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.AuthorizedUserTransformation} returns this
 */
proto.AuthorizedUserTransformation.prototype.clearNew = function() {
  return this.setNew(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.AuthorizedUserTransformation.prototype.hasNew = function() {
  return jspb.Message.getField(this, 2) != null;
};



/**
 * Oneof group definitions for this message. Each group defines the field
 * numbers belonging to that group. When of these fields' value is set, all
 * other fields in the group are cleared. During deserialization, if multiple
 * fields are encountered for a group, only the last value seen will be kept.
 * @private {!Array<!Array<number>>}
 * @const
 */
proto.KillSwitchAuditLogEntry.oneofGroups_ = [[3,4,5,6,7]];

/**
 * @enum {number}
 */
proto.KillSwitchAuditLogEntry.DescriptionCase = {
  DESCRIPTION_NOT_SET: 0,
  KILL_SWITCH_ENABLED: 3,
  KILL_SWITCH_DISABLED: 4,
  AUTHORIZED_USER_ADDED: 5,
  AUTHORIZED_USER_UPDATED: 6,
  AUTHORIZED_USER_DELETED: 7
};

/**
 * @return {proto.KillSwitchAuditLogEntry.DescriptionCase}
 */
proto.KillSwitchAuditLogEntry.prototype.getDescriptionCase = function() {
  return /** @type {proto.KillSwitchAuditLogEntry.DescriptionCase} */(jspb.Message.computeOneofCase(this, proto.KillSwitchAuditLogEntry.oneofGroups_[0]));
};



if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchAuditLogEntry.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchAuditLogEntry.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchAuditLogEntry} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.toObject = function(includeInstance, msg) {
  var f, obj = {
    timestamp: (f = msg.getTimestamp()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f),
    user: (f = msg.getUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f),
    killSwitchEnabled: (f = msg.getKillSwitchEnabled()) && proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject(includeInstance, f),
    killSwitchDisabled: (f = msg.getKillSwitchDisabled()) && proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject(includeInstance, f),
    authorizedUserAdded: (f = msg.getAuthorizedUserAdded()) && proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject(includeInstance, f),
    authorizedUserUpdated: (f = msg.getAuthorizedUserUpdated()) && proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject(includeInstance, f),
    authorizedUserDeleted: (f = msg.getAuthorizedUserDeleted()) && proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchAuditLogEntry}
 */
proto.KillSwitchAuditLogEntry.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchAuditLogEntry;
  return proto.KillSwitchAuditLogEntry.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchAuditLogEntry} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchAuditLogEntry}
 */
proto.KillSwitchAuditLogEntry.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new google_protobuf_timestamp_pb.Timestamp;
      reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader);
      msg.setTimestamp(value);
      break;
    case 2:
      var value = new proto.KillSwitchAuthorizedUser;
      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
      msg.setUser(value);
      break;
    case 3:
      var value = new proto.KillSwitchAuditLogEntry.KillSwitchEnabled;
      reader.readMessage(value,proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader);
      msg.setKillSwitchEnabled(value);
      break;
    case 4:
      var value = new proto.KillSwitchAuditLogEntry.KillSwitchDisabled;
      reader.readMessage(value,proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader);
      msg.setKillSwitchDisabled(value);
      break;
    case 5:
      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserAdded;
      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader);
      msg.setAuthorizedUserAdded(value);
      break;
    case 6:
      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated;
      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader);
      msg.setAuthorizedUserUpdated(value);
      break;
    case 7:
      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted;
      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader);
      msg.setAuthorizedUserDeleted(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchAuditLogEntry.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchAuditLogEntry.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchAuditLogEntry} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getTimestamp();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter
    );
  }
  f = message.getUser();
  if (f != null) {
    writer.writeMessage(
      2,
      f,
      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
    );
  }
  f = message.getKillSwitchEnabled();
  if (f != null) {
    writer.writeMessage(
      3,
      f,
      proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter
    );
  }
  f = message.getKillSwitchDisabled();
  if (f != null) {
    writer.writeMessage(
      4,
      f,
      proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter
    );
  }
  f = message.getAuthorizedUserAdded();
  if (f != null) {
    writer.writeMessage(
      5,
      f,
      proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter
    );
  }
  f = message.getAuthorizedUserUpdated();
  if (f != null) {
    writer.writeMessage(
      6,
      f,
      proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter
    );
  }
  f = message.getAuthorizedUserDeleted();
  if (f != null) {
    writer.writeMessage(
      7,
      f,
      proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter
    );
  }
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject = function(includeInstance, msg) {
  var f, obj = {
    killSwitch: (f = msg.getKillSwitch()) && proto.KillSwitch.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchAuditLogEntry.KillSwitchEnabled;
  return proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.KillSwitch;
      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
      msg.setKillSwitch(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getKillSwitch();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.KillSwitch.serializeBinaryToWriter
    );
  }
};


/**
 * optional KillSwitch kill_switch = 1;
 * @return {?proto.KillSwitch}
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.getKillSwitch = function() {
  return /** @type{?proto.KillSwitch} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitch, 1));
};


/**
 * @param {?proto.KillSwitch|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} returns this
*/
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.setKillSwitch = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} returns this
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.clearKillSwitch = function() {
  return this.setKillSwitch(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.hasKillSwitch = function() {
  return jspb.Message.getField(this, 1) != null;
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject = function(includeInstance, msg) {
  var f, obj = {
    transformation: (f = msg.getTransformation()) && proto.KillSwitchTransformation.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchAuditLogEntry.KillSwitchDisabled;
  return proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.KillSwitchTransformation;
      reader.readMessage(value,proto.KillSwitchTransformation.deserializeBinaryFromReader);
      msg.setTransformation(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getTransformation();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.KillSwitchTransformation.serializeBinaryToWriter
    );
  }
};


/**
 * optional KillSwitchTransformation transformation = 1;
 * @return {?proto.KillSwitchTransformation}
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.getTransformation = function() {
  return /** @type{?proto.KillSwitchTransformation} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchTransformation, 1));
};


/**
 * @param {?proto.KillSwitchTransformation|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} returns this
*/
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.setTransformation = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} returns this
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.clearTransformation = function() {
  return this.setTransformation(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.hasTransformation = function() {
  return jspb.Message.getField(this, 1) != null;
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject = function(includeInstance, msg) {
  var f, obj = {
    user: (f = msg.getUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserAdded;
  return proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.KillSwitchAuthorizedUser;
      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
      msg.setUser(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getUser();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
    );
  }
};


/**
 * optional KillSwitchAuthorizedUser user = 1;
 * @return {?proto.KillSwitchAuthorizedUser}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.getUser = function() {
  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
};


/**
 * @param {?proto.KillSwitchAuthorizedUser|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} returns this
*/
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.setUser = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} returns this
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.clearUser = function() {
  return this.setUser(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.hasUser = function() {
  return jspb.Message.getField(this, 1) != null;
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject = function(includeInstance, msg) {
  var f, obj = {
    transformation: (f = msg.getTransformation()) && proto.AuthorizedUserTransformation.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated;
  return proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.AuthorizedUserTransformation;
      reader.readMessage(value,proto.AuthorizedUserTransformation.deserializeBinaryFromReader);
      msg.setTransformation(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getTransformation();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.AuthorizedUserTransformation.serializeBinaryToWriter
    );
  }
};


/**
 * optional AuthorizedUserTransformation transformation = 1;
 * @return {?proto.AuthorizedUserTransformation}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.getTransformation = function() {
  return /** @type{?proto.AuthorizedUserTransformation} */ (
    jspb.Message.getWrapperField(this, proto.AuthorizedUserTransformation, 1));
};


/**
 * @param {?proto.AuthorizedUserTransformation|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} returns this
*/
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.setTransformation = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} returns this
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.clearTransformation = function() {
  return this.setTransformation(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.hasTransformation = function() {
  return jspb.Message.getField(this, 1) != null;
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.toObject = function(opt_includeInstance) {
  return proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject = function(includeInstance, msg) {
  var f, obj = {
    oldUser: (f = msg.getOldUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted;
  return proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.KillSwitchAuthorizedUser;
      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
      msg.setOldUser(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getOldUser();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
    );
  }
};


/**
 * optional KillSwitchAuthorizedUser old_user = 1;
 * @return {?proto.KillSwitchAuthorizedUser}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.getOldUser = function() {
  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
};


/**
 * @param {?proto.KillSwitchAuthorizedUser|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} returns this
*/
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.setOldUser = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} returns this
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.clearOldUser = function() {
  return this.setOldUser(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.hasOldUser = function() {
  return jspb.Message.getField(this, 1) != null;
};


/**
 * optional google.protobuf.Timestamp timestamp = 1;
 * @return {?proto.google.protobuf.Timestamp}
 */
proto.KillSwitchAuditLogEntry.prototype.getTimestamp = function() {
  return /** @type{?proto.google.protobuf.Timestamp} */ (
    jspb.Message.getWrapperField(this, google_protobuf_timestamp_pb.Timestamp, 1));
};


/**
 * @param {?proto.google.protobuf.Timestamp|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry} returns this
*/
proto.KillSwitchAuditLogEntry.prototype.setTimestamp = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry} returns this
 */
proto.KillSwitchAuditLogEntry.prototype.clearTimestamp = function() {
  return this.setTimestamp(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.prototype.hasTimestamp = function() {
  return jspb.Message.getField(this, 1) != null;
};


/**
 * optional KillSwitchAuthorizedUser user = 2;
 * @return {?proto.KillSwitchAuthorizedUser}
 */
proto.KillSwitchAuditLogEntry.prototype.getUser = function() {
  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 2));
};


/**
 * @param {?proto.KillSwitchAuthorizedUser|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry} returns this
*/
proto.KillSwitchAuditLogEntry.prototype.setUser = function(value) {
  return jspb.Message.setWrapperField(this, 2, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry} returns this
 */
proto.KillSwitchAuditLogEntry.prototype.clearUser = function() {
  return this.setUser(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.prototype.hasUser = function() {
  return jspb.Message.getField(this, 2) != null;
};


/**
 * optional KillSwitchEnabled kill_switch_enabled = 3;
 * @return {?proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
 */
proto.KillSwitchAuditLogEntry.prototype.getKillSwitchEnabled = function() {
  return /** @type{?proto.KillSwitchAuditLogEntry.KillSwitchEnabled} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.KillSwitchEnabled, 3));
};


/**
 * @param {?proto.KillSwitchAuditLogEntry.KillSwitchEnabled|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry} returns this
*/
proto.KillSwitchAuditLogEntry.prototype.setKillSwitchEnabled = function(value) {
  return jspb.Message.setOneofWrapperField(this, 3, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry} returns this
 */
proto.KillSwitchAuditLogEntry.prototype.clearKillSwitchEnabled = function() {
  return this.setKillSwitchEnabled(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.prototype.hasKillSwitchEnabled = function() {
  return jspb.Message.getField(this, 3) != null;
};


/**
 * optional KillSwitchDisabled kill_switch_disabled = 4;
 * @return {?proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
 */
proto.KillSwitchAuditLogEntry.prototype.getKillSwitchDisabled = function() {
  return /** @type{?proto.KillSwitchAuditLogEntry.KillSwitchDisabled} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.KillSwitchDisabled, 4));
};


/**
 * @param {?proto.KillSwitchAuditLogEntry.KillSwitchDisabled|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry} returns this
*/
proto.KillSwitchAuditLogEntry.prototype.setKillSwitchDisabled = function(value) {
  return jspb.Message.setOneofWrapperField(this, 4, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry} returns this
 */
proto.KillSwitchAuditLogEntry.prototype.clearKillSwitchDisabled = function() {
  return this.setKillSwitchDisabled(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.prototype.hasKillSwitchDisabled = function() {
  return jspb.Message.getField(this, 4) != null;
};


/**
 * optional AuthorizedUserAdded authorized_user_added = 5;
 * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
 */
proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserAdded = function() {
  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserAdded, 5));
};


/**
 * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry} returns this
*/
proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserAdded = function(value) {
  return jspb.Message.setOneofWrapperField(this, 5, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry} returns this
 */
proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserAdded = function() {
  return this.setAuthorizedUserAdded(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserAdded = function() {
  return jspb.Message.getField(this, 5) != null;
};


/**
 * optional AuthorizedUserUpdated authorized_user_updated = 6;
 * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
 */
proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserUpdated = function() {
  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated, 6));
};


/**
 * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry} returns this
*/
proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserUpdated = function(value) {
  return jspb.Message.setOneofWrapperField(this, 6, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry} returns this
 */
proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserUpdated = function() {
  return this.setAuthorizedUserUpdated(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserUpdated = function() {
  return jspb.Message.getField(this, 6) != null;
};


/**
 * optional AuthorizedUserDeleted authorized_user_deleted = 7;
 * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
 */
proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserDeleted = function() {
  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} */ (
    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted, 7));
};


/**
 * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted|undefined} value
 * @return {!proto.KillSwitchAuditLogEntry} returns this
*/
proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserDeleted = function(value) {
  return jspb.Message.setOneofWrapperField(this, 7, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.KillSwitchAuditLogEntry} returns this
 */
proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserDeleted = function() {
  return this.setAuthorizedUserDeleted(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserDeleted = function() {
  return jspb.Message.getField(this, 7) != null;
};


goog.object.extend(exports, proto);
