in util-jackson/src/main/scala/com/twitter/util/jackson/caseclass/CaseClassDeserializer.scala [725:787]
private[this] def getBeanPropertyDefinitions(
parameters: Array[Parameter],
annotatedWithParams: AnnotatedWithParams,
fromCompanion: Boolean = false
): Array[PropertyDefinition] = {
// need to find the scala description which carries the full type information
val constructorParamDescriptors =
findConstructorDescriptor(parameters) match {
case Some(constructorDescriptor) =>
constructorDescriptor.params
case _ =>
throw InvalidDefinitionException.from(
CaseClassDeserializer.EmptyJsonParser,
s"Unable to locate suitable constructor for class: ${clazz.getName}",
javaType)
}
for ((parameter, index) <- parameters.zipWithIndex) yield {
val constructorParamDescriptor = constructorParamDescriptors(index)
val scalaType = constructorParamDescriptor.argType
val parameterJavaType =
if (!javaType.getBindings.isEmpty &&
shouldFullyDefineParameterizedType(scalaType, parameter)) {
// what types are bound to the generic case class parameters
val boundTypeParameters: Array[JavaType] =
ReflectionTypes
.parameterizedTypeNames(parameter.getParameterizedType)
.map(javaType.getBindings.findBoundType)
Types
.javaType(
config.getTypeFactory,
scalaType,
boundTypeParameters
)
} else {
Types.javaType(config.getTypeFactory, scalaType)
}
val annotatedParameter =
newAnnotatedParameter(
typeResolutionContext = new TypeResolutionContext.Basic(
config.getTypeFactory,
javaType.getBindings
), // use the TypeBindings from the top-level JavaType, not the parameter JavaType
owner = annotatedWithParams,
annotations = annotatedWithParams.getParameterAnnotations(index),
javaType = parameterJavaType,
index = index
)
PropertyDefinition(
parameterJavaType,
scalaType,
SimpleBeanPropertyDefinition
.construct(
config,
annotatedParameter,
new PropertyName(constructorParamDescriptor.name)
)
)
}
}