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

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

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



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


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

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


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


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


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


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


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

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


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


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


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


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


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



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



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


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

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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





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


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

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


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


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


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


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


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

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


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


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


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


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


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


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


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





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


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

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


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


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


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


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


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


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


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


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


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


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


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


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





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


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

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


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


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


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


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


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


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


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


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


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


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


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


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



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

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

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



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


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

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


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


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


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


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





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


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

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


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


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


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


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


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


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


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


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





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


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

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


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


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


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


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


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


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


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


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





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


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

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


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


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


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


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


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


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


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


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





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


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

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


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


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


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


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


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


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


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


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





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


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

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


goog.object.extend(exports, proto);
