code: func UnmarshalRole(data []byte, opts ...MarshalOption) (*RoleV3, error) {
  	var h ResourceHeader
  	err := json.Unmarshal(data, &h)
  	if err != nil {
  		h.Version = V2
  	}
  
  	cfg, err := collectOptions(opts)
  	if err != nil {
  		return nil, trace.Wrap(err)
  	}
  
  	switch h.Version {
  	case V2:
  		var role RoleV2
  		if err := utils.UnmarshalWithSchema(GetRoleSchema(V2, ""), &role, data); err != nil {
  			return nil, trace.BadParameter(err.Error())
  		}
  
  		if err := role.CheckAndSetDefaults(); err != nil {
  			return nil, trace.Wrap(err)
  		}
  
  		roleV3 := role.V3()
  		roleV3.SetResourceID(cfg.ID)
  		return roleV3, nil
  	case V3:
  		var role RoleV3
  		if cfg.SkipValidation {
  			if err := utils.FastUnmarshal(data, &role); err != nil {
  				return nil, trace.BadParameter(err.Error())
  			}
  		} else {
  			if err := utils.UnmarshalWithSchema(GetRoleSchema(V3, ""), &role, data); err != nil {
  				return nil, trace.BadParameter(err.Error())
  			}
  		}
  
  		if err := role.CheckAndSetDefaults(); err != nil {
  			return nil, trace.Wrap(err)
  		}
  
  		if cfg.ID != 0 {
  			role.SetResourceID(cfg.ID)
  		}
  		if !cfg.Expires.IsZero() {
  			role.SetExpiry(cfg.Expires)
  		}
  		return &role, nil
  	}
  
  	return nil, trace.BadParameter("role version %q is not supported", h.Version)
  }
docs: // UnmarshalRole unmarshals role from JSON, sets defaults, and checks schema.