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