in util-validator/src/main/scala/com/twitter/util/validation/DescriptorFactory.scala [213:277]
private[this] def buildDescriptor[T](clazz: Class[T]): CaseClassDescriptor[T] = {
// for case classes, annotations for params only appear on the executable
val clazzDescriptor: ClassDescriptor = Reflector.describe(clazz).asInstanceOf[ClassDescriptor]
// map of parameter name to a class with all annotations for the parameter (including inherited)
val constructorParams: scala.collection.Map[String, ConstructorParams] =
getConstructorParams(clazz, clazzDescriptor)
val members = new mutable.HashMap[String, PropertyDescriptor]()
// we validate only declared properties of the class
val properties: Seq[json4s.PropertyDescriptor] = clazzDescriptor.properties
var index = 0
val size = properties.size
while (index < size) {
val property = properties(index)
val (fromConstructorScalaType, annotations) = {
constructorParams.get(property.mangledName) match {
case Some(constructorParam) =>
// we already have information for the field as it is an annotated executable parameter
(constructorParam.param.argType, constructorParam.annotations)
case _ =>
// we don't have information, use the property information
(property.returnType, property.field.getAnnotations)
}
}
// create property descriptorFactory
members.put(
property.mangledName,
buildPropertyDescriptor(fromConstructorScalaType, annotations)
)
index += 1
}
val constructors = new mutable.ArrayBuffer[ConstructorDescriptor]()
// create executable descriptors
var jindex = 0
val jsize = clazzDescriptor.constructors.size
while (jindex < jsize) {
constructors.append(
buildConstructorDescriptor(clazz, clazzDescriptor.constructors(jindex), None)
)
jindex += 1
}
val methods = new mutable.ArrayBuffer[MethodDescriptor]()
val clazzMethods = clazz.getMethods
if (clazzMethods.nonEmpty) {
var index = 0
val length = clazzMethods.length
while (index < length) {
val method = clazzMethods(index)
buildMethodDescriptor(method).foreach(methods.append(_))
index += 1
}
}
CaseClassDescriptor(
clazz = clazz,
scalaType = clazzDescriptor.erasure,
annotations = clazzDescriptor.erasure.erasure.getAnnotations.filter(isConstraintAnnotation),
constructors = constructors.toArray,
members = members.toMap,
methods = methods.toArray
)
}