@staticmethod
    def parse(wmsg):
        """
        Verifies and parses an unserialized raw message into an actual WAMP message instance.

        :param wmsg: The unserialized raw message.
        :type wmsg: list

        :returns: An instance of this class.
        """
        # this should already be verified by WampSerializer.unserialize
        #
        assert(len(wmsg) > 0 and wmsg[0] == Hello.MESSAGE_TYPE)

        if len(wmsg) != 3:
            raise ProtocolError("invalid message length {0} for HELLO".format(len(wmsg)))

        realm = check_or_raise_uri(wmsg[1], u"'realm' in HELLO", allow_none=True)
        details = check_or_raise_extra(wmsg[2], u"'details' in HELLO")

        roles = {}

        if u'roles' not in details:
            raise ProtocolError(u"missing mandatory roles attribute in options in HELLO")

        details_roles = check_or_raise_extra(details[u'roles'], u"'roles' in 'details' in HELLO")

        if len(details_roles) == 0:
            raise ProtocolError(u"empty 'roles' in 'details' in HELLO")

        for role in details_roles:
            if role not in [u'subscriber', u'publisher', u'caller', u'callee']:
                raise ProtocolError("invalid role '{0}' in 'roles' in 'details' in HELLO".format(role))

            role_cls = ROLE_NAME_TO_CLASS[role]

            details_role = check_or_raise_extra(details_roles[role], "role '{0}' in 'roles' in 'details' in HELLO".format(role))

            if u'features' in details_role:
                check_or_raise_extra(details_role[u'features'], "'features' in role '{0}' in 'roles' in 'details' in HELLO".format(role))

                role_features = role_cls(**details_role[u'features'])

            else:
                role_features = role_cls()

            roles[role] = role_features

        authmethods = None
        if u'authmethods' in details:
            details_authmethods = details[u'authmethods']
            if type(details_authmethods) != list:
                raise ProtocolError("invalid type {0} for 'authmethods' detail in HELLO".format(type(details_authmethods)))

            for auth_method in details_authmethods:
                if type(auth_method) != six.text_type:
                    raise ProtocolError("invalid type {0} for item in 'authmethods' detail in HELLO".format(type(auth_method)))

            authmethods = details_authmethods

        authid = None
        if u'authid' in details:
            details_authid = details[u'authid']
            if type(details_authid) != six.text_type:
                raise ProtocolError("invalid type {0} for 'authid' detail in HELLO".format(type(details_authid)))

            authid = details_authid

        authrole = None
        if u'authrole' in details:
            details_authrole = details[u'authrole']
            if type(details_authrole) != six.text_type:
                raise ProtocolError("invalid type {0} for 'authrole' detail in HELLO".format(type(details_authrole)))

            authrole = details_authrole

        authextra = None
        if u'authextra' in details:
            details_authextra = details[u'authextra']
            if type(details_authextra) != dict:
                raise ProtocolError("invalid type {0} for 'authextra' detail in HELLO".format(type(details_authextra)))

            authextra = details_authextra

        obj = Hello(realm, roles, authmethods, authid, authrole, authextra)

        return obj
dataset/ETHPy150Open crossbario/autobahn-python/autobahn/wamp/message.py/Hello.parse/original