private[this] def validateExecutableParameters[T]()

in util-validator/src/main/scala/com/twitter/util/validation/ScalaValidator.scala [849:959]


  private[this] def validateExecutableParameters[T](
    executableDescriptor: ExecutableDescriptor,
    root: Option[T],
    leaf: Option[Any],
    parameterValues: Array[Any],
    parameterNames: Option[Array[String]],
    groups: Seq[Class[_]]
  ): Set[ConstraintViolation[T]] = {
    if (executableDescriptor.members.size != parameterValues.length)
      throw new IllegalArgumentException(
        s"Invalid number of arguments for method ${executableDescriptor.executable.getName}.")
    val results = new mutable.ListBuffer[ConstraintViolation[T]]()
    val parameters: Array[Parameter] = executableDescriptor.executable.getParameters
    val parameterNamesList: Array[String] =
      (parameterNames match {
        case Some(names) =>
          names
        case _ =>
          getExecutableParameterNames(executableDescriptor.executable)
      }).map { maybeMangled =>
        DescriptorFactory.unmangleName(
          maybeMangled
        ) // parameter names are encoded since Scala 2.13.5
      }

    // executable parameter constraints
    var index = 0
    val parametersLength = parameterNamesList.length
    while (index < parametersLength) {
      val parameter = parameters(index)
      val parameterValue = parameterValues(index)
      // only for property path use to affect error reporting
      val parameterName = parameterNamesList(index)

      val parameterPath =
        PathImpl.createPathForExecutable(getExecutableMetaData(executableDescriptor.executable))
      parameterPath.addParameterNode(parameterName, index)

      val propertyDescriptor = executableDescriptor.members(parameter.getName)
      val validateFieldContext =
        ValidationContext[T](
          Some(parameterName),
          Some(executableDescriptor.executable.getDeclaringClass.asInstanceOf[Class[T]]),
          root,
          leaf,
          parameterPath)
      val parameterViolations = validateField[T](
        validateFieldContext,
        propertyDescriptor,
        parameterValue,
        groups
      )
      if (parameterViolations.nonEmpty) results.appendAll(parameterViolations)

      index += 1
    }
    results.toSet

    // executable cross-parameter constraints
    val crossParameterPath = PathImpl
      .createPathForExecutable(getExecutableMetaData(executableDescriptor.executable))
    crossParameterPath.addCrossParameterNode()
    val constraints = executableDescriptor.annotations
    index = 0
    val constraintsLength = constraints.length
    while (index < constraintsLength) {
      val constraint = constraints(index)
      val scalaType = Reflector.scalaTypeOf(parameterValues.getClass)

      val validators =
        findConstraintValidators(constraint.annotationType())
          .filter(parametersValidationTargetFilter)

      val validatorsIterator = validators.iterator
      while (validatorsIterator.hasNext) {
        val validator = validatorsIterator.next().asInstanceOf[ConstraintValidator[Annotation, _]]
        val constraintDescriptor = constraintDescriptorFactory
          .newConstraintDescriptor(
            name = executableDescriptor.executable.getName,
            clazz = scalaType.erasure,
            declaringClazz = executableDescriptor.executable.getDeclaringClass,
            annotation = constraint,
            constrainedElementKind = ConstrainedElementKind.METHOD
          )
        if (groupsEnabled(constraintDescriptor, groups)) {
          // initialize validator
          validator.initialize(constraint)
          val validateCrossParameterContext =
            ValidationContext[T](
              None,
              Some(executableDescriptor.executable.getDeclaringClass.asInstanceOf[Class[T]]),
              root,
              leaf,
              crossParameterPath)
          results.appendAll(
            isValid(
              context = validateCrossParameterContext,
              constraint = constraint,
              scalaType = scalaType,
              value = parameterValues,
              constraintDescriptorOption = Some(constraintDescriptor),
              validatorOption = Some(validator.asInstanceOf[ConstraintValidator[Annotation, Any]]),
              groups = groups
            )
          )
        }
      }
      index += 1
    }
    results.toSet
  }