/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
"use strict";

var $protobuf = require("protobufjs/minimal");

// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;

// Exported root namespace
var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});

$root.mls = (function() {

    /**
     * Namespace mls.
     * @exports mls
     * @namespace
     */
    var mls = {};

    /**
     * GroupInfoType enum.
     * @name mls.GroupInfoType
     * @enum {number}
     * @property {number} PUBLIC_GROUP_STATE=1 PUBLIC_GROUP_STATE value
     * @property {number} GROUP_INFO=2 GROUP_INFO value
     * @property {number} GROUP_INFO_JWE=3 GROUP_INFO_JWE value
     */
    mls.GroupInfoType = (function() {
        var valuesById = {}, values = Object.create(valuesById);
        values[valuesById[1] = "PUBLIC_GROUP_STATE"] = 1;
        values[valuesById[2] = "GROUP_INFO"] = 2;
        values[valuesById[3] = "GROUP_INFO_JWE"] = 3;
        return values;
    })();

    /**
     * RatchetTreeType enum.
     * @name mls.RatchetTreeType
     * @enum {number}
     * @property {number} FULL=1 FULL value
     * @property {number} DELTA=2 DELTA value
     * @property {number} REFERENCE=3 REFERENCE value
     */
    mls.RatchetTreeType = (function() {
        var valuesById = {}, values = Object.create(valuesById);
        values[valuesById[1] = "FULL"] = 1;
        values[valuesById[2] = "DELTA"] = 2;
        values[valuesById[3] = "REFERENCE"] = 3;
        return values;
    })();

    mls.GroupInfoBundle = (function() {

        /**
         * Properties of a GroupInfoBundle.
         * @memberof mls
         * @interface IGroupInfoBundle
         * @property {mls.GroupInfoType} groupInfoType GroupInfoBundle groupInfoType
         * @property {mls.RatchetTreeType} ratchetTreeType GroupInfoBundle ratchetTreeType
         * @property {Uint8Array} groupInfo GroupInfoBundle groupInfo
         */

        /**
         * Constructs a new GroupInfoBundle.
         * @memberof mls
         * @classdesc Represents a GroupInfoBundle.
         * @implements IGroupInfoBundle
         * @constructor
         * @param {mls.IGroupInfoBundle=} [properties] Properties to set
         */
        function GroupInfoBundle(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * GroupInfoBundle groupInfoType.
         * @member {mls.GroupInfoType} groupInfoType
         * @memberof mls.GroupInfoBundle
         * @instance
         */
        GroupInfoBundle.prototype.groupInfoType = 1;

        /**
         * GroupInfoBundle ratchetTreeType.
         * @member {mls.RatchetTreeType} ratchetTreeType
         * @memberof mls.GroupInfoBundle
         * @instance
         */
        GroupInfoBundle.prototype.ratchetTreeType = 1;

        /**
         * GroupInfoBundle groupInfo.
         * @member {Uint8Array} groupInfo
         * @memberof mls.GroupInfoBundle
         * @instance
         */
        GroupInfoBundle.prototype.groupInfo = $util.newBuffer([]);

        /**
         * Creates a new GroupInfoBundle instance using the specified properties.
         * @function create
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {mls.IGroupInfoBundle=} [properties] Properties to set
         * @returns {mls.GroupInfoBundle} GroupInfoBundle instance
         */
        GroupInfoBundle.create = function create(properties) {
            return new GroupInfoBundle(properties);
        };

        /**
         * Encodes the specified GroupInfoBundle message. Does not implicitly {@link mls.GroupInfoBundle.verify|verify} messages.
         * @function encode
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {mls.IGroupInfoBundle} message GroupInfoBundle message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GroupInfoBundle.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            writer.uint32(/* id 1, wireType 0 =*/8).int32(message.groupInfoType);
            writer.uint32(/* id 2, wireType 0 =*/16).int32(message.ratchetTreeType);
            writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.groupInfo);
            return writer;
        };

        /**
         * Encodes the specified GroupInfoBundle message, length delimited. Does not implicitly {@link mls.GroupInfoBundle.verify|verify} messages.
         * @function encodeDelimited
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {mls.IGroupInfoBundle} message GroupInfoBundle message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GroupInfoBundle.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a GroupInfoBundle message from the specified reader or buffer.
         * @function decode
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {mls.GroupInfoBundle} GroupInfoBundle
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GroupInfoBundle.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.mls.GroupInfoBundle();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1: {
                        message.groupInfoType = reader.int32();
                        break;
                    }
                case 2: {
                        message.ratchetTreeType = reader.int32();
                        break;
                    }
                case 3: {
                        message.groupInfo = reader.bytes();
                        break;
                    }
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            if (!message.hasOwnProperty("groupInfoType"))
                throw $util.ProtocolError("missing required 'groupInfoType'", { instance: message });
            if (!message.hasOwnProperty("ratchetTreeType"))
                throw $util.ProtocolError("missing required 'ratchetTreeType'", { instance: message });
            if (!message.hasOwnProperty("groupInfo"))
                throw $util.ProtocolError("missing required 'groupInfo'", { instance: message });
            return message;
        };

        /**
         * Decodes a GroupInfoBundle message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {mls.GroupInfoBundle} GroupInfoBundle
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GroupInfoBundle.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a GroupInfoBundle message.
         * @function verify
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        GroupInfoBundle.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            switch (message.groupInfoType) {
            default:
                return "groupInfoType: enum value expected";
            case 1:
            case 2:
            case 3:
                break;
            }
            switch (message.ratchetTreeType) {
            default:
                return "ratchetTreeType: enum value expected";
            case 1:
            case 2:
            case 3:
                break;
            }
            if (!(message.groupInfo && typeof message.groupInfo.length === "number" || $util.isString(message.groupInfo)))
                return "groupInfo: buffer expected";
            return null;
        };

        /**
         * Creates a GroupInfoBundle message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {mls.GroupInfoBundle} GroupInfoBundle
         */
        GroupInfoBundle.fromObject = function fromObject(object) {
            if (object instanceof $root.mls.GroupInfoBundle)
                return object;
            var message = new $root.mls.GroupInfoBundle();
            switch (object.groupInfoType) {
            default:
                if (typeof object.groupInfoType === "number") {
                    message.groupInfoType = object.groupInfoType;
                    break;
                }
                break;
            case "PUBLIC_GROUP_STATE":
            case 1:
                message.groupInfoType = 1;
                break;
            case "GROUP_INFO":
            case 2:
                message.groupInfoType = 2;
                break;
            case "GROUP_INFO_JWE":
            case 3:
                message.groupInfoType = 3;
                break;
            }
            switch (object.ratchetTreeType) {
            default:
                if (typeof object.ratchetTreeType === "number") {
                    message.ratchetTreeType = object.ratchetTreeType;
                    break;
                }
                break;
            case "FULL":
            case 1:
                message.ratchetTreeType = 1;
                break;
            case "DELTA":
            case 2:
                message.ratchetTreeType = 2;
                break;
            case "REFERENCE":
            case 3:
                message.ratchetTreeType = 3;
                break;
            }
            if (object.groupInfo != null)
                if (typeof object.groupInfo === "string")
                    $util.base64.decode(object.groupInfo, message.groupInfo = $util.newBuffer($util.base64.length(object.groupInfo)), 0);
                else if (object.groupInfo.length >= 0)
                    message.groupInfo = object.groupInfo;
            return message;
        };

        /**
         * Creates a plain object from a GroupInfoBundle message. Also converts values to other types if specified.
         * @function toObject
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {mls.GroupInfoBundle} message GroupInfoBundle
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        GroupInfoBundle.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.groupInfoType = options.enums === String ? "PUBLIC_GROUP_STATE" : 1;
                object.ratchetTreeType = options.enums === String ? "FULL" : 1;
                if (options.bytes === String)
                    object.groupInfo = "";
                else {
                    object.groupInfo = [];
                    if (options.bytes !== Array)
                        object.groupInfo = $util.newBuffer(object.groupInfo);
                }
            }
            if (message.groupInfoType != null && message.hasOwnProperty("groupInfoType"))
                object.groupInfoType = options.enums === String ? $root.mls.GroupInfoType[message.groupInfoType] === undefined ? message.groupInfoType : $root.mls.GroupInfoType[message.groupInfoType] : message.groupInfoType;
            if (message.ratchetTreeType != null && message.hasOwnProperty("ratchetTreeType"))
                object.ratchetTreeType = options.enums === String ? $root.mls.RatchetTreeType[message.ratchetTreeType] === undefined ? message.ratchetTreeType : $root.mls.RatchetTreeType[message.ratchetTreeType] : message.ratchetTreeType;
            if (message.groupInfo != null && message.hasOwnProperty("groupInfo"))
                object.groupInfo = options.bytes === String ? $util.base64.encode(message.groupInfo, 0, message.groupInfo.length) : options.bytes === Array ? Array.prototype.slice.call(message.groupInfo) : message.groupInfo;
            return object;
        };

        /**
         * Converts this GroupInfoBundle to JSON.
         * @function toJSON
         * @memberof mls.GroupInfoBundle
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        GroupInfoBundle.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for GroupInfoBundle
         * @function getTypeUrl
         * @memberof mls.GroupInfoBundle
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        GroupInfoBundle.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/mls.GroupInfoBundle";
        };

        return GroupInfoBundle;
    })();

    mls.CommitBundle = (function() {

        /**
         * Properties of a CommitBundle.
         * @memberof mls
         * @interface ICommitBundle
         * @property {Uint8Array} commit CommitBundle commit
         * @property {Uint8Array|null} [welcome] CommitBundle welcome
         * @property {mls.IGroupInfoBundle} groupInfoBundle CommitBundle groupInfoBundle
         */

        /**
         * Constructs a new CommitBundle.
         * @memberof mls
         * @classdesc Represents a CommitBundle.
         * @implements ICommitBundle
         * @constructor
         * @param {mls.ICommitBundle=} [properties] Properties to set
         */
        function CommitBundle(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CommitBundle commit.
         * @member {Uint8Array} commit
         * @memberof mls.CommitBundle
         * @instance
         */
        CommitBundle.prototype.commit = $util.newBuffer([]);

        /**
         * CommitBundle welcome.
         * @member {Uint8Array} welcome
         * @memberof mls.CommitBundle
         * @instance
         */
        CommitBundle.prototype.welcome = $util.newBuffer([]);

        /**
         * CommitBundle groupInfoBundle.
         * @member {mls.IGroupInfoBundle} groupInfoBundle
         * @memberof mls.CommitBundle
         * @instance
         */
        CommitBundle.prototype.groupInfoBundle = null;

        /**
         * Creates a new CommitBundle instance using the specified properties.
         * @function create
         * @memberof mls.CommitBundle
         * @static
         * @param {mls.ICommitBundle=} [properties] Properties to set
         * @returns {mls.CommitBundle} CommitBundle instance
         */
        CommitBundle.create = function create(properties) {
            return new CommitBundle(properties);
        };

        /**
         * Encodes the specified CommitBundle message. Does not implicitly {@link mls.CommitBundle.verify|verify} messages.
         * @function encode
         * @memberof mls.CommitBundle
         * @static
         * @param {mls.ICommitBundle} message CommitBundle message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CommitBundle.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.commit);
            if (message.welcome != null && Object.hasOwnProperty.call(message, "welcome"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.welcome);
            $root.mls.GroupInfoBundle.encode(message.groupInfoBundle, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified CommitBundle message, length delimited. Does not implicitly {@link mls.CommitBundle.verify|verify} messages.
         * @function encodeDelimited
         * @memberof mls.CommitBundle
         * @static
         * @param {mls.ICommitBundle} message CommitBundle message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CommitBundle.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CommitBundle message from the specified reader or buffer.
         * @function decode
         * @memberof mls.CommitBundle
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {mls.CommitBundle} CommitBundle
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CommitBundle.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.mls.CommitBundle();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1: {
                        message.commit = reader.bytes();
                        break;
                    }
                case 2: {
                        message.welcome = reader.bytes();
                        break;
                    }
                case 3: {
                        message.groupInfoBundle = $root.mls.GroupInfoBundle.decode(reader, reader.uint32());
                        break;
                    }
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            if (!message.hasOwnProperty("commit"))
                throw $util.ProtocolError("missing required 'commit'", { instance: message });
            if (!message.hasOwnProperty("groupInfoBundle"))
                throw $util.ProtocolError("missing required 'groupInfoBundle'", { instance: message });
            return message;
        };

        /**
         * Decodes a CommitBundle message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof mls.CommitBundle
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {mls.CommitBundle} CommitBundle
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CommitBundle.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CommitBundle message.
         * @function verify
         * @memberof mls.CommitBundle
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CommitBundle.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (!(message.commit && typeof message.commit.length === "number" || $util.isString(message.commit)))
                return "commit: buffer expected";
            if (message.welcome != null && message.hasOwnProperty("welcome"))
                if (!(message.welcome && typeof message.welcome.length === "number" || $util.isString(message.welcome)))
                    return "welcome: buffer expected";
            {
                var error = $root.mls.GroupInfoBundle.verify(message.groupInfoBundle);
                if (error)
                    return "groupInfoBundle." + error;
            }
            return null;
        };

        /**
         * Creates a CommitBundle message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof mls.CommitBundle
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {mls.CommitBundle} CommitBundle
         */
        CommitBundle.fromObject = function fromObject(object) {
            if (object instanceof $root.mls.CommitBundle)
                return object;
            var message = new $root.mls.CommitBundle();
            if (object.commit != null)
                if (typeof object.commit === "string")
                    $util.base64.decode(object.commit, message.commit = $util.newBuffer($util.base64.length(object.commit)), 0);
                else if (object.commit.length >= 0)
                    message.commit = object.commit;
            if (object.welcome != null)
                if (typeof object.welcome === "string")
                    $util.base64.decode(object.welcome, message.welcome = $util.newBuffer($util.base64.length(object.welcome)), 0);
                else if (object.welcome.length >= 0)
                    message.welcome = object.welcome;
            if (object.groupInfoBundle != null) {
                if (typeof object.groupInfoBundle !== "object")
                    throw TypeError(".mls.CommitBundle.groupInfoBundle: object expected");
                message.groupInfoBundle = $root.mls.GroupInfoBundle.fromObject(object.groupInfoBundle);
            }
            return message;
        };

        /**
         * Creates a plain object from a CommitBundle message. Also converts values to other types if specified.
         * @function toObject
         * @memberof mls.CommitBundle
         * @static
         * @param {mls.CommitBundle} message CommitBundle
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CommitBundle.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.commit = "";
                else {
                    object.commit = [];
                    if (options.bytes !== Array)
                        object.commit = $util.newBuffer(object.commit);
                }
                if (options.bytes === String)
                    object.welcome = "";
                else {
                    object.welcome = [];
                    if (options.bytes !== Array)
                        object.welcome = $util.newBuffer(object.welcome);
                }
                object.groupInfoBundle = null;
            }
            if (message.commit != null && message.hasOwnProperty("commit"))
                object.commit = options.bytes === String ? $util.base64.encode(message.commit, 0, message.commit.length) : options.bytes === Array ? Array.prototype.slice.call(message.commit) : message.commit;
            if (message.welcome != null && message.hasOwnProperty("welcome"))
                object.welcome = options.bytes === String ? $util.base64.encode(message.welcome, 0, message.welcome.length) : options.bytes === Array ? Array.prototype.slice.call(message.welcome) : message.welcome;
            if (message.groupInfoBundle != null && message.hasOwnProperty("groupInfoBundle"))
                object.groupInfoBundle = $root.mls.GroupInfoBundle.toObject(message.groupInfoBundle, options);
            return object;
        };

        /**
         * Converts this CommitBundle to JSON.
         * @function toJSON
         * @memberof mls.CommitBundle
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CommitBundle.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * Gets the default type url for CommitBundle
         * @function getTypeUrl
         * @memberof mls.CommitBundle
         * @static
         * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
         * @returns {string} The default type url
         */
        CommitBundle.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
            if (typeUrlPrefix === undefined) {
                typeUrlPrefix = "type.googleapis.com";
            }
            return typeUrlPrefix + "/mls.CommitBundle";
        };

        return CommitBundle;
    })();

    return mls;
})();

module.exports = $root;
