code: func (cat *catalog) validateTaskProto(ctx *validation.Context, t proto.Message) proto.Message {
  	var taskMsg proto.Message
  
  	v := reflect.ValueOf(t)
  	if v.Kind() != reflect.Ptr {
  		ctx.Errorf("expecting a pointer to proto message, got %T", t)
  		return nil
  	}
  	v = v.Elem()
  
  	for i := 0; i < v.NumField(); i++ {
  		// Skip unset, scalar and repeated fields and fields that do not correspond
  		// to registered task types.
  		field := v.Field(i)
  		if field.Kind() != reflect.Ptr || field.IsNil() || field.Elem().Kind() != reflect.Struct {
  			continue
  		}
  		fieldVal, _ := field.Interface().(proto.Message)
  		if fieldVal != nil && cat.GetTaskManager(fieldVal) != nil {
  			if taskMsg != nil {
  				ctx.Errorf("only one field with task definition must be set, at least two are given (%T and %T)", taskMsg, fieldVal)
  				return nil
  			}
  			taskMsg = fieldVal
  		}
  	}
  
  	if taskMsg == nil {
  		ctx.Errorf("can't find a recognized task definition inside %T", t)
  		return nil
  	}
  
  	taskMan := cat.GetTaskManager(taskMsg)
  	ctx.Enter("task")
  	taskMan.ValidateProtoMessage(ctx, taskMsg)
  	ctx.Exit()
  	if ctx.Finalize() != nil {
  		return nil
  	}
  	return taskMsg
  }
docs: // validateTaskProto visits all fields of a proto and sniffs ones that correspond
  // to task definitions (as registered via RegisterTaskManager). It ensures
  // there's one and only one such field, validates it, and returns it.
  //
  // Errors are returned via validation.Context.