def length()

in scalding-serialization/src/main/scala/com/twitter/scalding/serialization/macros/impl/ordered_serialization/ProductLike.scala [87:160]


  def length(c: Context)(element: c.Tree)(
      elementData: List[(c.universe.Type, c.universe.TermName, TreeOrderedBuf[c.type])]
  ): CompileTimeLengthTypes[c.type] = {
    import c.universe._
    import CompileTimeLengthTypes._
    val (constSize, dynamicFunctions, maybeLength, noLength) =
      elementData.foldLeft((0, Vector[c.Tree](), Vector[c.Tree](), 0)) {
        case ((constantLength, dynamicLength, maybeLength, noLength), (tpe, accessorSymbol, tBuf)) =>
          tBuf.length(q"$element.$accessorSymbol") match {
            case const: ConstantLengthCalculation[_] =>
              (
                constantLength + const.asInstanceOf[ConstantLengthCalculation[c.type]].toInt,
                dynamicLength,
                maybeLength,
                noLength
              )
            case f: FastLengthCalculation[_] =>
              (
                constantLength,
                dynamicLength :+ f.asInstanceOf[FastLengthCalculation[c.type]].t,
                maybeLength,
                noLength
              )
            case m: MaybeLengthCalculation[_] =>
              (
                constantLength,
                dynamicLength,
                maybeLength :+ m.asInstanceOf[MaybeLengthCalculation[c.type]].t,
                noLength
              )
            case _: NoLengthCalculationAvailable[_] =>
              (constantLength, dynamicLength, maybeLength, noLength + 1)
          }
      }

    val combinedDynamic = dynamicFunctions.foldLeft(q"""$constSize""") { case (prev, t) =>
      q"$prev + $t"
    }

    if (noLength > 0) {
      NoLengthCalculationAvailable(c)
    } else {
      if (maybeLength.isEmpty && dynamicFunctions.isEmpty) {
        ConstantLengthCalculation(c)(constSize)
      } else {
        if (maybeLength.isEmpty) {
          FastLengthCalculation(c)(combinedDynamic)
        } else {

          val const =
            q"_root_.com.twitter.scalding.serialization.macros.impl.ordered_serialization.runtime_helpers.ConstLen"
          val dyn =
            q"_root_.com.twitter.scalding.serialization.macros.impl.ordered_serialization.runtime_helpers.DynamicLen"
          val noLen =
            q"_root_.com.twitter.scalding.serialization.macros.impl.ordered_serialization.runtime_helpers.NoLengthCalculation"
          // Contains an MaybeLength
          val combinedMaybe: Tree = maybeLength.reduce { (hOpt, nxtOpt) =>
            q"""$hOpt + $nxtOpt"""
          }
          if (dynamicFunctions.nonEmpty || constSize != 0) {
            MaybeLengthCalculation(c)(q"""
            $combinedMaybe match {
              case $const(l) => $dyn(l + $combinedDynamic)
              case $dyn(l) => $dyn(l + $combinedDynamic)
              case $noLen => $noLen
            }
          """)
          } else {
            MaybeLengthCalculation(c)(combinedMaybe)
          }
        }
      }
    }
  }