code: func (a *ACL) RoleResolve(args *structs.ACLRoleBatchGetRequest, reply *structs.ACLRoleBatchResponse) error {
  	if err := a.aclPreCheck(); err != nil {
  		return err
  	}
  
  	if done, err := a.srv.forward("ACL.RoleResolve", args, args, reply); done {
  		return err
  	}
  
  	// get full list of roles for this token
  	identity, roles, err := a.srv.acls.resolveTokenToIdentityAndRoles(args.Token)
  	if err != nil {
  		return err
  	}
  
  	idMap := make(map[string]*structs.ACLRole)
  	for _, roleID := range identity.RoleIDs() {
  		idMap[roleID] = nil
  	}
  	for _, role := range roles {
  		idMap[role.ID] = role
  	}
  
  	for _, roleID := range args.RoleIDs {
  		if role, ok := idMap[roleID]; ok {
  			// only add non-deleted roles
  			if role != nil {
  				reply.Roles = append(reply.Roles, role)
  			}
  		} else {
  			// send a permission denied to indicate that the request included
  			// role ids not associated with this token
  			return acl.ErrPermissionDenied
  		}
  	}
  
  	a.srv.setQueryMeta(&reply.QueryMeta)
  
  	return nil
  }
docs: // RoleResolve is used to retrieve a subset of the roles associated with a given token
  // The role ids in the args simply act as a filter on the role set assigned to the token