@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] == Welcome.MESSAGE_TYPE)

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

        session = check_or_raise_id(wmsg[1], u"'session' in WELCOME")
        details = check_or_raise_extra(wmsg[2], u"'details' in WELCOME")

        # FIXME: tigher value checking (types, URIs etc)
        realm = details.get(u'realm', None)
        authid = details.get(u'authid', None)
        authrole = details.get(u'authrole', None)
        authmethod = details.get(u'authmethod', None)
        authprovider = details.get(u'authprovider', None)
        authextra = details.get(u'authextra', None)

        roles = {}

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

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

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

        for role in details_roles:
            if role not in [u'broker', u'dealer']:
                raise ProtocolError("invalid role '{0}' in 'roles' in 'details' in WELCOME".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 WELCOME".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 WELCOME".format(role))

                role_features = role_cls(**details_roles[role][u'features'])

            else:
                role_features = role_cls()

            roles[role] = role_features

        custom = {}
        for k in details:
            if _CUSTOM_ATTRIBUTE.match(k):
                custom[k] = details[k]

        obj = Welcome(session, roles, realm, authid, authrole, authmethod, authprovider, authextra, custom)

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