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

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

goog.exportSymbol('workflows.Action', null, proto);
goog.exportSymbol('workflows.Action.ActionCase', null, proto);
goog.exportSymbol('workflows.Action.AttributeAction', null, proto);
goog.exportSymbol('workflows.Action.AttributeAction.AttributeAction', null, proto);
goog.exportSymbol('workflows.Action.MarkDuplicateAction', null, proto);
goog.exportSymbol('workflows.Action.MoveAction', null, proto);
goog.exportSymbol('workflows.Action.ReplyAction', null, proto);
goog.exportSymbol('workflows.Action.ReportAction', null, proto);
goog.exportSymbol('workflows.Action.ReportAction.ReportType', null, proto);
goog.exportSymbol('workflows.Action.StarAction', null, proto);
goog.exportSymbol('workflows.Action.SubscribeAction', null, proto);
goog.exportSymbol('workflows.Action.UnmarkDuplicateAction', null, proto);
goog.exportSymbol('workflows.Action.VoteAction', null, proto);
goog.exportSymbol('workflows.Action.VoteAction.Vote', null, proto);
goog.exportSymbol('workflows.Thread', null, proto);
goog.exportSymbol('workflows.Workflow', 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.workflows.Thread = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Thread, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Thread.displayName = 'proto.workflows.Thread';
}
/**
 * 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.workflows.Action = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.workflows.Action.oneofGroups_);
};
goog.inherits(proto.workflows.Action, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.displayName = 'proto.workflows.Action';
}
/**
 * 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.workflows.Action.ReplyAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.ReplyAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.ReplyAction.displayName = 'proto.workflows.Action.ReplyAction';
}
/**
 * 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.workflows.Action.MoveAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.MoveAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.MoveAction.displayName = 'proto.workflows.Action.MoveAction';
}
/**
 * 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.workflows.Action.MarkDuplicateAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.MarkDuplicateAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.MarkDuplicateAction.displayName = 'proto.workflows.Action.MarkDuplicateAction';
}
/**
 * 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.workflows.Action.UnmarkDuplicateAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.UnmarkDuplicateAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.UnmarkDuplicateAction.displayName = 'proto.workflows.Action.UnmarkDuplicateAction';
}
/**
 * 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.workflows.Action.StarAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.StarAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.StarAction.displayName = 'proto.workflows.Action.StarAction';
}
/**
 * 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.workflows.Action.SubscribeAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.SubscribeAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.SubscribeAction.displayName = 'proto.workflows.Action.SubscribeAction';
}
/**
 * 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.workflows.Action.VoteAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.VoteAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.VoteAction.displayName = 'proto.workflows.Action.VoteAction';
}
/**
 * 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.workflows.Action.AttributeAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.AttributeAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.AttributeAction.displayName = 'proto.workflows.Action.AttributeAction';
}
/**
 * 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.workflows.Action.ReportAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.ReportAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.ReportAction.displayName = 'proto.workflows.Action.ReportAction';
}
/**
 * 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.workflows.Workflow = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, proto.workflows.Workflow.repeatedFields_, null);
};
goog.inherits(proto.workflows.Workflow, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Workflow.displayName = 'proto.workflows.Workflow';
}



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.workflows.Thread.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Thread.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.workflows.Thread} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Thread.toObject = function(includeInstance, msg) {
  var f, obj = {
    forumId: jspb.Message.getFieldWithDefault(msg, 1, 0),
    threadId: jspb.Message.getFieldWithDefault(msg, 2, 0)
  };

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


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


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


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Thread} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Thread.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getForumId();
  if (f !== 0) {
    writer.writeInt64(
      1,
      f
    );
  }
  f = message.getThreadId();
  if (f !== 0) {
    writer.writeInt64(
      2,
      f
    );
  }
};


/**
 * optional int64 forum_id = 1;
 * @return {number}
 */
proto.workflows.Thread.prototype.getForumId = function() {
  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


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


/**
 * optional int64 thread_id = 2;
 * @return {number}
 */
proto.workflows.Thread.prototype.getThreadId = function() {
  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
};


/**
 * @param {number} value
 * @return {!proto.workflows.Thread} returns this
 */
proto.workflows.Thread.prototype.setThreadId = function(value) {
  return jspb.Message.setProto3IntField(this, 2, value);
};



/**
 * 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.workflows.Action.oneofGroups_ = [[1,2,3,4,5,16,17,18,19]];

/**
 * @enum {number}
 */
proto.workflows.Action.ActionCase = {
  ACTION_NOT_SET: 0,
  REPLY_ACTION: 1,
  MOVE_ACTION: 2,
  MARK_DUPLICATE_ACTION: 3,
  UNMARK_DUPLICATE_ACTION: 4,
  ATTRIBUTE_ACTION: 5,
  STAR_ACTION: 16,
  SUBSCRIBE_ACTION: 17,
  VOTE_ACTION: 18,
  REPORT_ACTION: 19
};

/**
 * @return {proto.workflows.Action.ActionCase}
 */
proto.workflows.Action.prototype.getActionCase = function() {
  return /** @type {proto.workflows.Action.ActionCase} */(jspb.Message.computeOneofCase(this, proto.workflows.Action.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.workflows.Action.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.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.workflows.Action} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.toObject = function(includeInstance, msg) {
  var f, obj = {
    replyAction: (f = msg.getReplyAction()) && proto.workflows.Action.ReplyAction.toObject(includeInstance, f),
    moveAction: (f = msg.getMoveAction()) && proto.workflows.Action.MoveAction.toObject(includeInstance, f),
    markDuplicateAction: (f = msg.getMarkDuplicateAction()) && proto.workflows.Action.MarkDuplicateAction.toObject(includeInstance, f),
    unmarkDuplicateAction: (f = msg.getUnmarkDuplicateAction()) && proto.workflows.Action.UnmarkDuplicateAction.toObject(includeInstance, f),
    attributeAction: (f = msg.getAttributeAction()) && proto.workflows.Action.AttributeAction.toObject(includeInstance, f),
    starAction: (f = msg.getStarAction()) && proto.workflows.Action.StarAction.toObject(includeInstance, f),
    subscribeAction: (f = msg.getSubscribeAction()) && proto.workflows.Action.SubscribeAction.toObject(includeInstance, f),
    voteAction: (f = msg.getVoteAction()) && proto.workflows.Action.VoteAction.toObject(includeInstance, f),
    reportAction: (f = msg.getReportAction()) && proto.workflows.Action.ReportAction.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.workflows.Action}
 */
proto.workflows.Action.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.workflows.Action;
  return proto.workflows.Action.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.workflows.Action} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.workflows.Action}
 */
proto.workflows.Action.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = new proto.workflows.Action.ReplyAction;
      reader.readMessage(value,proto.workflows.Action.ReplyAction.deserializeBinaryFromReader);
      msg.setReplyAction(value);
      break;
    case 2:
      var value = new proto.workflows.Action.MoveAction;
      reader.readMessage(value,proto.workflows.Action.MoveAction.deserializeBinaryFromReader);
      msg.setMoveAction(value);
      break;
    case 3:
      var value = new proto.workflows.Action.MarkDuplicateAction;
      reader.readMessage(value,proto.workflows.Action.MarkDuplicateAction.deserializeBinaryFromReader);
      msg.setMarkDuplicateAction(value);
      break;
    case 4:
      var value = new proto.workflows.Action.UnmarkDuplicateAction;
      reader.readMessage(value,proto.workflows.Action.UnmarkDuplicateAction.deserializeBinaryFromReader);
      msg.setUnmarkDuplicateAction(value);
      break;
    case 5:
      var value = new proto.workflows.Action.AttributeAction;
      reader.readMessage(value,proto.workflows.Action.AttributeAction.deserializeBinaryFromReader);
      msg.setAttributeAction(value);
      break;
    case 16:
      var value = new proto.workflows.Action.StarAction;
      reader.readMessage(value,proto.workflows.Action.StarAction.deserializeBinaryFromReader);
      msg.setStarAction(value);
      break;
    case 17:
      var value = new proto.workflows.Action.SubscribeAction;
      reader.readMessage(value,proto.workflows.Action.SubscribeAction.deserializeBinaryFromReader);
      msg.setSubscribeAction(value);
      break;
    case 18:
      var value = new proto.workflows.Action.VoteAction;
      reader.readMessage(value,proto.workflows.Action.VoteAction.deserializeBinaryFromReader);
      msg.setVoteAction(value);
      break;
    case 19:
      var value = new proto.workflows.Action.ReportAction;
      reader.readMessage(value,proto.workflows.Action.ReportAction.deserializeBinaryFromReader);
      msg.setReportAction(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Action} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getReplyAction();
  if (f != null) {
    writer.writeMessage(
      1,
      f,
      proto.workflows.Action.ReplyAction.serializeBinaryToWriter
    );
  }
  f = message.getMoveAction();
  if (f != null) {
    writer.writeMessage(
      2,
      f,
      proto.workflows.Action.MoveAction.serializeBinaryToWriter
    );
  }
  f = message.getMarkDuplicateAction();
  if (f != null) {
    writer.writeMessage(
      3,
      f,
      proto.workflows.Action.MarkDuplicateAction.serializeBinaryToWriter
    );
  }
  f = message.getUnmarkDuplicateAction();
  if (f != null) {
    writer.writeMessage(
      4,
      f,
      proto.workflows.Action.UnmarkDuplicateAction.serializeBinaryToWriter
    );
  }
  f = message.getAttributeAction();
  if (f != null) {
    writer.writeMessage(
      5,
      f,
      proto.workflows.Action.AttributeAction.serializeBinaryToWriter
    );
  }
  f = message.getStarAction();
  if (f != null) {
    writer.writeMessage(
      16,
      f,
      proto.workflows.Action.StarAction.serializeBinaryToWriter
    );
  }
  f = message.getSubscribeAction();
  if (f != null) {
    writer.writeMessage(
      17,
      f,
      proto.workflows.Action.SubscribeAction.serializeBinaryToWriter
    );
  }
  f = message.getVoteAction();
  if (f != null) {
    writer.writeMessage(
      18,
      f,
      proto.workflows.Action.VoteAction.serializeBinaryToWriter
    );
  }
  f = message.getReportAction();
  if (f != null) {
    writer.writeMessage(
      19,
      f,
      proto.workflows.Action.ReportAction.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.workflows.Action.ReplyAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.ReplyAction.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.workflows.Action.ReplyAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.ReplyAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    payload: jspb.Message.getFieldWithDefault(msg, 1, ""),
    subscribe: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
    markAsAnswer: jspb.Message.getBooleanFieldWithDefault(msg, 3, 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.workflows.Action.ReplyAction}
 */
proto.workflows.Action.ReplyAction.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.workflows.Action.ReplyAction;
  return proto.workflows.Action.ReplyAction.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.workflows.Action.ReplyAction} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.workflows.Action.ReplyAction}
 */
proto.workflows.Action.ReplyAction.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setPayload(value);
      break;
    case 2:
      var value = /** @type {boolean} */ (reader.readBool());
      msg.setSubscribe(value);
      break;
    case 3:
      var value = /** @type {boolean} */ (reader.readBool());
      msg.setMarkAsAnswer(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Action.ReplyAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.ReplyAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getPayload();
  if (f.length > 0) {
    writer.writeString(
      1,
      f
    );
  }
  f = message.getSubscribe();
  if (f) {
    writer.writeBool(
      2,
      f
    );
  }
  f = message.getMarkAsAnswer();
  if (f) {
    writer.writeBool(
      3,
      f
    );
  }
};


/**
 * optional string payload = 1;
 * @return {string}
 */
proto.workflows.Action.ReplyAction.prototype.getPayload = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.workflows.Action.ReplyAction} returns this
 */
proto.workflows.Action.ReplyAction.prototype.setPayload = function(value) {
  return jspb.Message.setProto3StringField(this, 1, value);
};


/**
 * optional bool subscribe = 2;
 * @return {boolean}
 */
proto.workflows.Action.ReplyAction.prototype.getSubscribe = function() {
  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
};


/**
 * @param {boolean} value
 * @return {!proto.workflows.Action.ReplyAction} returns this
 */
proto.workflows.Action.ReplyAction.prototype.setSubscribe = function(value) {
  return jspb.Message.setProto3BooleanField(this, 2, value);
};


/**
 * optional bool mark_as_answer = 3;
 * @return {boolean}
 */
proto.workflows.Action.ReplyAction.prototype.getMarkAsAnswer = function() {
  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
};


/**
 * @param {boolean} value
 * @return {!proto.workflows.Action.ReplyAction} returns this
 */
proto.workflows.Action.ReplyAction.prototype.setMarkAsAnswer = function(value) {
  return jspb.Message.setProto3BooleanField(this, 3, 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.workflows.Action.MoveAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.MoveAction.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.workflows.Action.MoveAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.MoveAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    forumId: jspb.Message.getFieldWithDefault(msg, 1, 0),
    category: jspb.Message.getFieldWithDefault(msg, 2, ""),
    language: jspb.Message.getFieldWithDefault(msg, 3, ""),
    propertyMap: (f = msg.getPropertyMap()) ? f.toObject(includeInstance, undefined) : []
  };

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


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


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.workflows.Action.MoveAction} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.workflows.Action.MoveAction}
 */
proto.workflows.Action.MoveAction.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {number} */ (reader.readInt64());
      msg.setForumId(value);
      break;
    case 2:
      var value = /** @type {string} */ (reader.readString());
      msg.setCategory(value);
      break;
    case 3:
      var value = /** @type {string} */ (reader.readString());
      msg.setLanguage(value);
      break;
    case 4:
      var value = msg.getPropertyMap();
      reader.readMessage(value, function(message, reader) {
        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", "");
         });
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Action.MoveAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.MoveAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getForumId();
  if (f !== 0) {
    writer.writeInt64(
      1,
      f
    );
  }
  f = message.getCategory();
  if (f.length > 0) {
    writer.writeString(
      2,
      f
    );
  }
  f = message.getLanguage();
  if (f.length > 0) {
    writer.writeString(
      3,
      f
    );
  }
  f = message.getPropertyMap(true);
  if (f && f.getLength() > 0) {
    f.serializeBinary(4, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
  }
};


/**
 * optional int64 forum_id = 1;
 * @return {number}
 */
proto.workflows.Action.MoveAction.prototype.getForumId = function() {
  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


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


/**
 * optional string category = 2;
 * @return {string}
 */
proto.workflows.Action.MoveAction.prototype.getCategory = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
};


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


/**
 * optional string language = 3;
 * @return {string}
 */
proto.workflows.Action.MoveAction.prototype.getLanguage = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
};


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


/**
 * map<string, string> property = 4;
 * @param {boolean=} opt_noLazyCreate Do not create the map if
 * empty, instead returning `undefined`
 * @return {!jspb.Map<string,string>}
 */
proto.workflows.Action.MoveAction.prototype.getPropertyMap = function(opt_noLazyCreate) {
  return /** @type {!jspb.Map<string,string>} */ (
      jspb.Message.getMapField(this, 4, opt_noLazyCreate,
      null));
};


/**
 * Clears values from the map. The map will be non-null.
 * @return {!proto.workflows.Action.MoveAction} returns this
 */
proto.workflows.Action.MoveAction.prototype.clearPropertyMap = function() {
  this.getPropertyMap().clear();
  return this;};





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.workflows.Action.MarkDuplicateAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.MarkDuplicateAction.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.workflows.Action.MarkDuplicateAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.MarkDuplicateAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    destination: (f = msg.getDestination()) && proto.workflows.Thread.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.workflows.Action.MarkDuplicateAction}
 */
proto.workflows.Action.MarkDuplicateAction.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.workflows.Action.MarkDuplicateAction;
  return proto.workflows.Action.MarkDuplicateAction.deserializeBinaryFromReader(msg, reader);
};


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


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


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


/**
 * optional Thread destination = 1;
 * @return {?proto.workflows.Thread}
 */
proto.workflows.Action.MarkDuplicateAction.prototype.getDestination = function() {
  return /** @type{?proto.workflows.Thread} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Thread, 1));
};


/**
 * @param {?proto.workflows.Thread|undefined} value
 * @return {!proto.workflows.Action.MarkDuplicateAction} returns this
*/
proto.workflows.Action.MarkDuplicateAction.prototype.setDestination = function(value) {
  return jspb.Message.setWrapperField(this, 1, value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action.MarkDuplicateAction} returns this
 */
proto.workflows.Action.MarkDuplicateAction.prototype.clearDestination = function() {
  return this.setDestination(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.workflows.Action.MarkDuplicateAction.prototype.hasDestination = 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.workflows.Action.UnmarkDuplicateAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.UnmarkDuplicateAction.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.workflows.Action.UnmarkDuplicateAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.UnmarkDuplicateAction.toObject = function(includeInstance, msg) {
  var f, obj = {

  };

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


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


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


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Action.UnmarkDuplicateAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.UnmarkDuplicateAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
};





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.workflows.Action.StarAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.StarAction.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.workflows.Action.StarAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.StarAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    star: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
  };

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


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


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


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


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


/**
 * optional bool star = 1;
 * @return {boolean}
 */
proto.workflows.Action.StarAction.prototype.getStar = function() {
  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
};


/**
 * @param {boolean} value
 * @return {!proto.workflows.Action.StarAction} returns this
 */
proto.workflows.Action.StarAction.prototype.setStar = function(value) {
  return jspb.Message.setProto3BooleanField(this, 1, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.workflows.Action.SubscribeAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.SubscribeAction.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.workflows.Action.SubscribeAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.SubscribeAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    subscribe: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
  };

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


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


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


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


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


/**
 * optional bool subscribe = 1;
 * @return {boolean}
 */
proto.workflows.Action.SubscribeAction.prototype.getSubscribe = function() {
  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
};


/**
 * @param {boolean} value
 * @return {!proto.workflows.Action.SubscribeAction} returns this
 */
proto.workflows.Action.SubscribeAction.prototype.setSubscribe = function(value) {
  return jspb.Message.setProto3BooleanField(this, 1, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.workflows.Action.VoteAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.VoteAction.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.workflows.Action.VoteAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.VoteAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    vote: jspb.Message.getFieldWithDefault(msg, 1, 0)
  };

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


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


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


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Action.VoteAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.VoteAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getVote();
  if (f !== 0.0) {
    writer.writeEnum(
      1,
      f
    );
  }
};


/**
 * @enum {number}
 */
proto.workflows.Action.VoteAction.Vote = {
  NONE: 0,
  UP: 1,
  DOWN: -1
};

/**
 * optional Vote vote = 1;
 * @return {!proto.workflows.Action.VoteAction.Vote}
 */
proto.workflows.Action.VoteAction.prototype.getVote = function() {
  return /** @type {!proto.workflows.Action.VoteAction.Vote} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


/**
 * @param {!proto.workflows.Action.VoteAction.Vote} value
 * @return {!proto.workflows.Action.VoteAction} returns this
 */
proto.workflows.Action.VoteAction.prototype.setVote = function(value) {
  return jspb.Message.setProto3EnumField(this, 1, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.workflows.Action.AttributeAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.AttributeAction.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.workflows.Action.AttributeAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.AttributeAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    attributeAction: jspb.Message.getFieldWithDefault(msg, 1, 0)
  };

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


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


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


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Action.AttributeAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.AttributeAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getAttributeAction();
  if (f !== 0.0) {
    writer.writeEnum(
      1,
      f
    );
  }
};


/**
 * @enum {number}
 */
proto.workflows.Action.AttributeAction.AttributeAction = {
  AA_NONE: 0,
  AA_LOCK: 1,
  AA_UNLOCK: 2,
  AA_PIN: 3,
  AA_UNPIN: 4,
  AA_NON_ISSUE: 5,
  AA_OBSOLETE: 6,
  AA_REVERT: 7,
  AA_SET_TRENDING: 8,
  AA_UNSET_TRENDING: 9,
  AA_SET_ISSUE_RESOLVED: 10,
  AA_UNSET_ISSUE_RESOLVED: 11
};

/**
 * optional AttributeAction attribute_action = 1;
 * @return {!proto.workflows.Action.AttributeAction.AttributeAction}
 */
proto.workflows.Action.AttributeAction.prototype.getAttributeAction = function() {
  return /** @type {!proto.workflows.Action.AttributeAction.AttributeAction} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


/**
 * @param {!proto.workflows.Action.AttributeAction.AttributeAction} value
 * @return {!proto.workflows.Action.AttributeAction} returns this
 */
proto.workflows.Action.AttributeAction.prototype.setAttributeAction = function(value) {
  return jspb.Message.setProto3EnumField(this, 1, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.workflows.Action.ReportAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.ReportAction.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.workflows.Action.ReportAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.ReportAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    reportType: jspb.Message.getFieldWithDefault(msg, 1, 0)
  };

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


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


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


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Action.ReportAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.ReportAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getReportType();
  if (f !== 0.0) {
    writer.writeEnum(
      1,
      f
    );
  }
};


/**
 * @enum {number}
 */
proto.workflows.Action.ReportAction.ReportType = {
  RT_UNKNOWN: 0,
  RT_OFF_TOPIC: 1,
  RT_ABUSE: 2
};

/**
 * optional ReportType report_type = 1;
 * @return {!proto.workflows.Action.ReportAction.ReportType}
 */
proto.workflows.Action.ReportAction.prototype.getReportType = function() {
  return /** @type {!proto.workflows.Action.ReportAction.ReportType} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};


/**
 * @param {!proto.workflows.Action.ReportAction.ReportType} value
 * @return {!proto.workflows.Action.ReportAction} returns this
 */
proto.workflows.Action.ReportAction.prototype.setReportType = function(value) {
  return jspb.Message.setProto3EnumField(this, 1, value);
};


/**
 * optional ReplyAction reply_action = 1;
 * @return {?proto.workflows.Action.ReplyAction}
 */
proto.workflows.Action.prototype.getReplyAction = function() {
  return /** @type{?proto.workflows.Action.ReplyAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.ReplyAction, 1));
};


/**
 * @param {?proto.workflows.Action.ReplyAction|undefined} value
 * @return {!proto.workflows.Action} returns this
*/
proto.workflows.Action.prototype.setReplyAction = function(value) {
  return jspb.Message.setOneofWrapperField(this, 1, proto.workflows.Action.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearReplyAction = function() {
  return this.setReplyAction(undefined);
};


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


/**
 * optional MoveAction move_action = 2;
 * @return {?proto.workflows.Action.MoveAction}
 */
proto.workflows.Action.prototype.getMoveAction = function() {
  return /** @type{?proto.workflows.Action.MoveAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.MoveAction, 2));
};


/**
 * @param {?proto.workflows.Action.MoveAction|undefined} value
 * @return {!proto.workflows.Action} returns this
*/
proto.workflows.Action.prototype.setMoveAction = function(value) {
  return jspb.Message.setOneofWrapperField(this, 2, proto.workflows.Action.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearMoveAction = function() {
  return this.setMoveAction(undefined);
};


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


/**
 * optional MarkDuplicateAction mark_duplicate_action = 3;
 * @return {?proto.workflows.Action.MarkDuplicateAction}
 */
proto.workflows.Action.prototype.getMarkDuplicateAction = function() {
  return /** @type{?proto.workflows.Action.MarkDuplicateAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.MarkDuplicateAction, 3));
};


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


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearMarkDuplicateAction = function() {
  return this.setMarkDuplicateAction(undefined);
};


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


/**
 * optional UnmarkDuplicateAction unmark_duplicate_action = 4;
 * @return {?proto.workflows.Action.UnmarkDuplicateAction}
 */
proto.workflows.Action.prototype.getUnmarkDuplicateAction = function() {
  return /** @type{?proto.workflows.Action.UnmarkDuplicateAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.UnmarkDuplicateAction, 4));
};


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


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearUnmarkDuplicateAction = function() {
  return this.setUnmarkDuplicateAction(undefined);
};


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


/**
 * optional AttributeAction attribute_action = 5;
 * @return {?proto.workflows.Action.AttributeAction}
 */
proto.workflows.Action.prototype.getAttributeAction = function() {
  return /** @type{?proto.workflows.Action.AttributeAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.AttributeAction, 5));
};


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


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearAttributeAction = function() {
  return this.setAttributeAction(undefined);
};


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


/**
 * optional StarAction star_action = 16;
 * @return {?proto.workflows.Action.StarAction}
 */
proto.workflows.Action.prototype.getStarAction = function() {
  return /** @type{?proto.workflows.Action.StarAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.StarAction, 16));
};


/**
 * @param {?proto.workflows.Action.StarAction|undefined} value
 * @return {!proto.workflows.Action} returns this
*/
proto.workflows.Action.prototype.setStarAction = function(value) {
  return jspb.Message.setOneofWrapperField(this, 16, proto.workflows.Action.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearStarAction = function() {
  return this.setStarAction(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.workflows.Action.prototype.hasStarAction = function() {
  return jspb.Message.getField(this, 16) != null;
};


/**
 * optional SubscribeAction subscribe_action = 17;
 * @return {?proto.workflows.Action.SubscribeAction}
 */
proto.workflows.Action.prototype.getSubscribeAction = function() {
  return /** @type{?proto.workflows.Action.SubscribeAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.SubscribeAction, 17));
};


/**
 * @param {?proto.workflows.Action.SubscribeAction|undefined} value
 * @return {!proto.workflows.Action} returns this
*/
proto.workflows.Action.prototype.setSubscribeAction = function(value) {
  return jspb.Message.setOneofWrapperField(this, 17, proto.workflows.Action.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearSubscribeAction = function() {
  return this.setSubscribeAction(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.workflows.Action.prototype.hasSubscribeAction = function() {
  return jspb.Message.getField(this, 17) != null;
};


/**
 * optional VoteAction vote_action = 18;
 * @return {?proto.workflows.Action.VoteAction}
 */
proto.workflows.Action.prototype.getVoteAction = function() {
  return /** @type{?proto.workflows.Action.VoteAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.VoteAction, 18));
};


/**
 * @param {?proto.workflows.Action.VoteAction|undefined} value
 * @return {!proto.workflows.Action} returns this
*/
proto.workflows.Action.prototype.setVoteAction = function(value) {
  return jspb.Message.setOneofWrapperField(this, 18, proto.workflows.Action.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearVoteAction = function() {
  return this.setVoteAction(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.workflows.Action.prototype.hasVoteAction = function() {
  return jspb.Message.getField(this, 18) != null;
};


/**
 * optional ReportAction report_action = 19;
 * @return {?proto.workflows.Action.ReportAction}
 */
proto.workflows.Action.prototype.getReportAction = function() {
  return /** @type{?proto.workflows.Action.ReportAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.ReportAction, 19));
};


/**
 * @param {?proto.workflows.Action.ReportAction|undefined} value
 * @return {!proto.workflows.Action} returns this
*/
proto.workflows.Action.prototype.setReportAction = function(value) {
  return jspb.Message.setOneofWrapperField(this, 19, proto.workflows.Action.oneofGroups_[0], value);
};


/**
 * Clears the message field making it undefined.
 * @return {!proto.workflows.Action} returns this
 */
proto.workflows.Action.prototype.clearReportAction = function() {
  return this.setReportAction(undefined);
};


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.workflows.Action.prototype.hasReportAction = function() {
  return jspb.Message.getField(this, 19) != null;
};



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



if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.workflows.Workflow.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Workflow.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.workflows.Workflow} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Workflow.toObject = function(includeInstance, msg) {
  var f, obj = {
    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
    description: jspb.Message.getFieldWithDefault(msg, 2, ""),
    index: jspb.Message.getFieldWithDefault(msg, 3, 0),
    actionsList: jspb.Message.toObjectList(msg.getActionsList(),
    proto.workflows.Action.toObject, includeInstance)
  };

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


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


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.workflows.Workflow} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.workflows.Workflow}
 */
proto.workflows.Workflow.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setName(value);
      break;
    case 2:
      var value = /** @type {string} */ (reader.readString());
      msg.setDescription(value);
      break;
    case 3:
      var value = /** @type {number} */ (reader.readInt32());
      msg.setIndex(value);
      break;
    case 4:
      var value = new proto.workflows.Action;
      reader.readMessage(value,proto.workflows.Action.deserializeBinaryFromReader);
      msg.addActions(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


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


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.workflows.Workflow} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Workflow.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getName();
  if (f.length > 0) {
    writer.writeString(
      1,
      f
    );
  }
  f = message.getDescription();
  if (f.length > 0) {
    writer.writeString(
      2,
      f
    );
  }
  f = message.getIndex();
  if (f !== 0) {
    writer.writeInt32(
      3,
      f
    );
  }
  f = message.getActionsList();
  if (f.length > 0) {
    writer.writeRepeatedMessage(
      4,
      f,
      proto.workflows.Action.serializeBinaryToWriter
    );
  }
};


/**
 * optional string name = 1;
 * @return {string}
 */
proto.workflows.Workflow.prototype.getName = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.workflows.Workflow} returns this
 */
proto.workflows.Workflow.prototype.setName = function(value) {
  return jspb.Message.setProto3StringField(this, 1, value);
};


/**
 * optional string description = 2;
 * @return {string}
 */
proto.workflows.Workflow.prototype.getDescription = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
};


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


/**
 * optional int32 index = 3;
 * @return {number}
 */
proto.workflows.Workflow.prototype.getIndex = function() {
  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
};


/**
 * @param {number} value
 * @return {!proto.workflows.Workflow} returns this
 */
proto.workflows.Workflow.prototype.setIndex = function(value) {
  return jspb.Message.setProto3IntField(this, 3, value);
};


/**
 * repeated Action actions = 4;
 * @return {!Array<!proto.workflows.Action>}
 */
proto.workflows.Workflow.prototype.getActionsList = function() {
  return /** @type{!Array<!proto.workflows.Action>} */ (
    jspb.Message.getRepeatedWrapperField(this, proto.workflows.Action, 4));
};


/**
 * @param {!Array<!proto.workflows.Action>} value
 * @return {!proto.workflows.Workflow} returns this
*/
proto.workflows.Workflow.prototype.setActionsList = function(value) {
  return jspb.Message.setRepeatedWrapperField(this, 4, value);
};


/**
 * @param {!proto.workflows.Action=} opt_value
 * @param {number=} opt_index
 * @return {!proto.workflows.Action}
 */
proto.workflows.Workflow.prototype.addActions = function(opt_value, opt_index) {
  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.workflows.Action, opt_index);
};


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


goog.object.extend(exports, proto);
