private[this] def validate[T]()

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


  private[this] def validate[T](
    maybeDescriptor: Option[Descriptor],
    context: ValidationContext[T],
    value: Any,
    groups: Seq[Class[_]]
  ): Set[ConstraintViolation[T]] = maybeDescriptor match {
    case Some(descriptor) =>
      descriptor match {
        case p: PropertyDescriptor =>
          val propertyPath = PathImpl.createCopy(context.path)
          context.fieldName.map(propertyPath.addPropertyNode)
          // validateField recurses back through validate for cascaded properties
          validateField[T](context.copy(path = propertyPath), p, value, groups)
        case c: CaseClassDescriptor[_] =>
          val memberViolations = {
            val results = new mutable.ListBuffer[ConstraintViolation[T]]()
            if (c.members.nonEmpty) {
              val keys: Iterable[String] = c.members.keys
              val keyIterator = keys.iterator
              while (keyIterator.hasNext) {
                val name = keyIterator.next()
                val propertyDescriptor = c.members(name)
                val propertyPath = PathImpl.createCopy(context.path)
                propertyPath.addPropertyNode(DescriptorFactory.unmangleName(name))
                // validateField recurses back through validate here for cascaded properties
                val fieldResults =
                  validateField[T](
                    context.copy(fieldName = Some(name), path = propertyPath),
                    propertyDescriptor,
                    findFieldValue(value, c.clazz, name),
                    groups)
                if (fieldResults.nonEmpty) results.appendAll(fieldResults)
              }
            }
            results.toSet
          }
          val methodViolations = {
            val results = new ListBuffer[ConstraintViolation[T]]()
            if (c.methods.nonEmpty) {
              var index = 0
              val length = c.methods.length
              while (index < length) {
                val methodResults = value match {
                  case null | None =>
                    Set.empty
                  case Some(obj) =>
                    validateMethod[T](context.copy(fieldName = None), c.methods(index), obj, groups)
                  case _ =>
                    validateMethod[T](
                      context.copy(fieldName = None),
                      c.methods(index),
                      value,
                      groups)
                }

                if (methodResults.nonEmpty) results.appendAll(methodResults)
                index += 1
              }
            }
            results.toSet
          }
          val clazzViolations =
            validateClazz[T](context, c.asInstanceOf[CaseClassDescriptor[T]], value, groups)

          // put them all together
          memberViolations ++ methodViolations ++ clazzViolations
      }
    case _ =>
      val clazz: Class[T] = value.getClass.asInstanceOf[Class[T]]
      if (ReflectTypes.notCaseClass(clazz))
        throw new ValidationException(s"$clazz is not a valid case class.")
      val caseClassDescriptor: CaseClassDescriptor[T] = descriptorFactory.describe(clazz)
      val context = ValidationContext(
        fieldName = None,
        rootClazz = Some(clazz),
        root = Some(value.asInstanceOf[T]),
        leaf = Some(value),
        path = PathImpl.createRootPath())
      validate[T](Some(caseClassDescriptor), context, value, groups)
  }