private[this] def parseConstructorValues()

in util-jackson/src/main/scala/com/twitter/util/jackson/caseclass/CaseClassDeserializer.scala [519:626]


  private[this] def parseConstructorValues(
    jsonParser: JsonParser,
    context: DeserializationContext,
    jsonNode: JsonNode
  ): (Array[Object], Seq[CaseClassFieldMappingException]) = {
    /* Mutable Fields */
    var constructorValuesIdx = 0
    val constructorValues = new Array[Object](numConstructorArgs)
    val errors = mutable.ListBuffer[CaseClassFieldMappingException]()

    while (constructorValuesIdx < numConstructorArgs) {
      val field = fields(constructorValuesIdx)
      try {
        val value = field.parse(context, jsonParser.getCodec, jsonNode)
        constructorValues(constructorValuesIdx) = value //mutation
      } catch {
        case e: CaseClassFieldMappingException =>
          if (e.path == null) {
            // fill in missing path detail
            addException(
              field,
              e.withPropertyPath(CaseClassFieldMappingException.PropertyPath.leaf(field.name)),
              constructorValues,
              constructorValuesIdx,
              errors
            )
          } else {
            addException(
              field,
              e,
              constructorValues,
              constructorValuesIdx,
              errors
            )
          }
        case e: InvalidFormatException =>
          addException(
            field,
            CaseClassFieldMappingException(
              CaseClassFieldMappingException.PropertyPath.leaf(field.name),
              CaseClassFieldMappingException.Reason(
                s"'${e.getValue.toString}' is not a " +
                  s"valid ${Types.wrapperType(e.getTargetType).getSimpleName}${validValuesString(e)}",
                CaseClassFieldMappingException.JsonProcessingError(e)
              )
            ),
            constructorValues,
            constructorValuesIdx,
            errors
          )
        case e: MismatchedInputException =>
          addException(
            field,
            CaseClassFieldMappingException(
              CaseClassFieldMappingException.PropertyPath.leaf(field.name),
              CaseClassFieldMappingException.Reason(
                s"'${jsonNode.asText("")}' is not a " +
                  s"valid ${Types.wrapperType(e.getTargetType).getSimpleName}${validValuesString(e)}",
                CaseClassFieldMappingException.JsonProcessingError(e)
              )
            ),
            constructorValues,
            constructorValuesIdx,
            errors
          )
        case e: CaseClassMappingException =>
          constructorValues(constructorValuesIdx) = field.missingValue //mutation
          errors ++= e.errors.map(_.scoped(field.name))
        case e: JsonProcessingException =>
          // don't include source info since it's often blank. Consider adding e.getCause.getMessage
          e.clearLocation()
          addException(
            field,
            CaseClassFieldMappingException(
              CaseClassFieldMappingException.PropertyPath.leaf(field.name),
              CaseClassFieldMappingException.Reason(
                e.errorMessage,
                CaseClassFieldMappingException.JsonProcessingError(e)
              )
            ),
            constructorValues,
            constructorValuesIdx,
            errors
          )
        case e: java.util.NoSuchElementException if isScalaEnumerationType(field) =>
          // Scala enumeration mapping issue
          addException(
            field,
            CaseClassFieldMappingException(
              CaseClassFieldMappingException.PropertyPath.leaf(field.name),
              CaseClassFieldMappingException.Reason(e.getMessage)
            ),
            constructorValues,
            constructorValuesIdx,
            errors
          )
        case e: InjectableValuesException =>
          // we rethrow, to prevent leaking internal injection detail in the "errors" array
          throw e
        case NonFatal(e) =>
          error("Unexpected exception parsing field: " + field, e)
          throw e
      }
      constructorValuesIdx += 1
    }

    (constructorValues, errors.toSeq)
  }