// 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.MarkAsReadAction', null, proto);
goog.exportSymbol('workflows.Action.MarkAsUnreadAction', 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.ReplyWithCRAction', 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.ReplyWithCRAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.ReplyWithCRAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.ReplyWithCRAction.displayName = 'proto.workflows.Action.ReplyWithCRAction';
}
/**
 * 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.Action.MarkAsReadAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.MarkAsReadAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.MarkAsReadAction.displayName = 'proto.workflows.Action.MarkAsReadAction';
}
/**
 * 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.MarkAsUnreadAction = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.workflows.Action.MarkAsUnreadAction, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.workflows.Action.MarkAsUnreadAction.displayName = 'proto.workflows.Action.MarkAsUnreadAction';
}
/**
 * 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,6,16,17,18,19,20,21]];

/**
 * @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,
  REPLY_WITH_CR_ACTION: 6,
  STAR_ACTION: 16,
  SUBSCRIBE_ACTION: 17,
  VOTE_ACTION: 18,
  REPORT_ACTION: 19,
  MARK_AS_READ_ACTION: 20,
  MARK_AS_UNREAD_ACTION: 21
};

/**
 * @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),
    replyWithCrAction: (f = msg.getReplyWithCrAction()) && proto.workflows.Action.ReplyWithCRAction.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),
    markAsReadAction: (f = msg.getMarkAsReadAction()) && proto.workflows.Action.MarkAsReadAction.toObject(includeInstance, f),
    markAsUnreadAction: (f = msg.getMarkAsUnreadAction()) && proto.workflows.Action.MarkAsUnreadAction.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 6:
      var value = new proto.workflows.Action.ReplyWithCRAction;
      reader.readMessage(value,proto.workflows.Action.ReplyWithCRAction.deserializeBinaryFromReader);
      msg.setReplyWithCrAction(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;
    case 20:
      var value = new proto.workflows.Action.MarkAsReadAction;
      reader.readMessage(value,proto.workflows.Action.MarkAsReadAction.deserializeBinaryFromReader);
      msg.setMarkAsReadAction(value);
      break;
    case 21:
      var value = new proto.workflows.Action.MarkAsUnreadAction;
      reader.readMessage(value,proto.workflows.Action.MarkAsUnreadAction.deserializeBinaryFromReader);
      msg.setMarkAsUnreadAction(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.getReplyWithCrAction();
  if (f != null) {
    writer.writeMessage(
      6,
      f,
      proto.workflows.Action.ReplyWithCRAction.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
    );
  }
  f = message.getMarkAsReadAction();
  if (f != null) {
    writer.writeMessage(
      20,
      f,
      proto.workflows.Action.MarkAsReadAction.serializeBinaryToWriter
    );
  }
  f = message.getMarkAsUnreadAction();
  if (f != null) {
    writer.writeMessage(
      21,
      f,
      proto.workflows.Action.MarkAsUnreadAction.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.ReplyWithCRAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.ReplyWithCRAction.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.ReplyWithCRAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.ReplyWithCRAction.toObject = function(includeInstance, msg) {
  var f, obj = {
    cannedResponseId: jspb.Message.getFieldWithDefault(msg, 1, 0),
    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.ReplyWithCRAction}
 */
proto.workflows.Action.ReplyWithCRAction.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.workflows.Action.ReplyWithCRAction;
  return proto.workflows.Action.ReplyWithCRAction.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.workflows.Action.ReplyWithCRAction} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.workflows.Action.ReplyWithCRAction}
 */
proto.workflows.Action.ReplyWithCRAction.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.setCannedResponseId(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.ReplyWithCRAction.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.workflows.Action.ReplyWithCRAction.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.ReplyWithCRAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.ReplyWithCRAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getCannedResponseId();
  if (f !== 0) {
    writer.writeInt64(
      1,
      f
    );
  }
  f = message.getSubscribe();
  if (f) {
    writer.writeBool(
      2,
      f
    );
  }
  f = message.getMarkAsAnswer();
  if (f) {
    writer.writeBool(
      3,
      f
    );
  }
};


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


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


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


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


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


/**
 * @param {boolean} value
 * @return {!proto.workflows.Action.ReplyWithCRAction} returns this
 */
proto.workflows.Action.ReplyWithCRAction.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.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);
};





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


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.workflows.Action.MarkAsReadAction} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.workflows.Action.MarkAsReadAction}
 */
proto.workflows.Action.MarkAsReadAction.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.MarkAsReadAction.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.workflows.Action.MarkAsReadAction.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.MarkAsReadAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.MarkAsReadAction.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.MarkAsUnreadAction.prototype.toObject = function(opt_includeInstance) {
  return proto.workflows.Action.MarkAsUnreadAction.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.MarkAsUnreadAction} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.MarkAsUnreadAction.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.MarkAsUnreadAction}
 */
proto.workflows.Action.MarkAsUnreadAction.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.workflows.Action.MarkAsUnreadAction;
  return proto.workflows.Action.MarkAsUnreadAction.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.workflows.Action.MarkAsUnreadAction} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.workflows.Action.MarkAsUnreadAction}
 */
proto.workflows.Action.MarkAsUnreadAction.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.MarkAsUnreadAction.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.workflows.Action.MarkAsUnreadAction.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.MarkAsUnreadAction} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.workflows.Action.MarkAsUnreadAction.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
};


/**
 * 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 ReplyWithCRAction reply_with_cr_action = 6;
 * @return {?proto.workflows.Action.ReplyWithCRAction}
 */
proto.workflows.Action.prototype.getReplyWithCrAction = function() {
  return /** @type{?proto.workflows.Action.ReplyWithCRAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.ReplyWithCRAction, 6));
};


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


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


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.workflows.Action.prototype.hasReplyWithCrAction = function() {
  return jspb.Message.getField(this, 6) != 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;
};


/**
 * optional MarkAsReadAction mark_as_read_action = 20;
 * @return {?proto.workflows.Action.MarkAsReadAction}
 */
proto.workflows.Action.prototype.getMarkAsReadAction = function() {
  return /** @type{?proto.workflows.Action.MarkAsReadAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.MarkAsReadAction, 20));
};


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


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


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


/**
 * optional MarkAsUnreadAction mark_as_unread_action = 21;
 * @return {?proto.workflows.Action.MarkAsUnreadAction}
 */
proto.workflows.Action.prototype.getMarkAsUnreadAction = function() {
  return /** @type{?proto.workflows.Action.MarkAsUnreadAction} */ (
    jspb.Message.getWrapperField(this, proto.workflows.Action.MarkAsUnreadAction, 21));
};


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


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


/**
 * Returns whether this field is set.
 * @return {boolean}
 */
proto.workflows.Action.prototype.hasMarkAsUnreadAction = function() {
  return jspb.Message.getField(this, 21) != 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);
