All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalapb.GeneratedExtension.scala Maven / Gradle / Ivy

The newest version!
package scalapb

import com.google.protobuf.{ByteString, CodedInputStream, InvalidProtocolBufferException}
import scalapb.lenses.{Lens, Mutation}

case class GeneratedExtension[C <: ExtendableMessage[C], T](lens: Lens[C, T]) extends Lens[C, T] {
  def get(c: C): T = lens.get(c)

  def set(t: T): Mutation[C] = lens.set(t)

  def withLens[B](other: Lens[T, B]) = GeneratedExtension(lens.compose(other))
}

object GeneratedExtension {
  /* To be used only be generated code */
  def readMessageFromByteString[T <: GeneratedMessage](
      cmp: GeneratedMessageCompanion[T]
  )(bs: ByteString): T = {
    cmp.parseFrom(bs.newCodedInput())
  }

  def singleUnknownFieldLens[E, T](fromBase: E => T, toBase: T => E, default: T): Lens[Seq[E], T] =
    Lens[Seq[E], T](c => c.lastOption.map(fromBase).getOrElse(default))((_, t) => Vector(toBase(t)))

  def optionalUnknownFieldLens[E, T](fromBase: E => T, toBase: T => E): Lens[Seq[E], Option[T]] =
    Lens[Seq[E], Option[T]](c => c.lastOption.map(fromBase))((_, t) => t.map(toBase).toVector)

  // For messages we concatenate all ByteStrings (https://github.com/scalapb/ScalaPB/issues/574)
  def singleUnknownMessageFieldLens[T](
      fromBase: ByteString => T,
      toBase: T => ByteString,
      default: T
  ): Lens[Seq[ByteString], T] =
    Lens[Seq[ByteString], T](c =>
      c.reduceOption((bs1, bs2) => bs1.concat(bs2)).lastOption.map(fromBase).getOrElse(default)
    )((_, t) => Vector(toBase(t)))

  def optionalUnknownMessageFieldLens[T](
      fromBase: ByteString => T,
      toBase: T => ByteString
  ): Lens[Seq[ByteString], Option[T]] =
    Lens[Seq[ByteString], Option[T]](c =>
      c.reduceOption((bs1, bs2) => bs1.concat(bs2)).map(fromBase)
    )((_, t) => t.map(toBase).toVector)

  private def unpackLengthDelimited[E, T, Coll](
      bss: Seq[ByteString],
      fromBase: E => T,
      unpack: CodedInputStream => E
  )(implicit ca: CollectionAdapter[T, Coll]): Coll = {
    val v = ca.newBuilder
    bss.foreach { ld =>
      val ci = ld.newCodedInput()
      while (ci.getBytesUntilLimit > 0) {
        v += fromBase(unpack(ci))
      }
    }
    v.result().toOption.get
  }

  @deprecated("Use repeatedLensUnpackable", "0.11.14")
  def repeatedUnknownFieldLensUnpackable[E, T, Coll](
      fromBase: E => T,
      toBase: T => E
  ): Lens[Seq[E], Seq[T]] =
    Lens[Seq[E], Seq[T]]({ es => es.map(fromBase) })({ (_, t) => t.map(toBase) })

  def repeatedLensUnpackable[E, T, Coll](
      fromBase: E => T,
      toBase: T => E
  )(implicit ca: CollectionAdapter[T, Coll]): Lens[Seq[E], Coll] =
    Lens[Seq[E], Coll]({ es =>
      val b = ca.newBuilder
      es.foreach { e =>
        b += fromBase(e)
      }
      b.result().toOption.get
    })({ (_, t) =>
      ca.toIterator(t).map(toBase).toSeq
    })

  @deprecated("Use repeatedLensPackable", "0.11.14")
  def repeatedUnknownFieldLensPackable[E, T](
      fromBase: E => T,
      toBase: T => E,
      unpack: CodedInputStream => E
  ): Lens[(Seq[E], Seq[ByteString]), Seq[T]] =
    repeatedLensPackable[E, T, Seq[T]](fromBase, toBase, unpack)

  def repeatedLensPackable[E, T, Coll](
      fromBase: E => T,
      toBase: T => E,
      unpack: CodedInputStream => E
  )(implicit ca: CollectionAdapter[T, Coll]): Lens[(Seq[E], Seq[ByteString]), Coll] =
    Lens[(Seq[E], Seq[ByteString]), Coll]({ case (es, bss) =>
      if (bss.nonEmpty) {
        if (es.nonEmpty) {
          throw new InvalidProtocolBufferException("Mixed packed and unpacked data.")
        }
        unpackLengthDelimited(bss, fromBase, unpack)
      } else {
        ca.fromIteratorUnsafe(es.iterator.map(fromBase))
      }
    })(
      { case ((_, bss), t) =>
        val v = Vector.newBuilder[E]
        if (bss.nonEmpty) {
          bss.foreach { ld =>
            val ci = ld.newCodedInput()
            while (ci.getBytesUntilLimit > 0) {
              v += unpack(ci)
            }
          }
        }
        v ++= ca.toIterator(t).map(toBase)
        (v.result(), Vector.empty[ByteString])
      }
    )

  def forUnknownField[C <: ExtendableMessage[C], E](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[E]]
  ): GeneratedExtension[C, Seq[E]] = {
    GeneratedExtension[C, Seq[E]](
      ExtendableMessage.unknownFieldsLen(fieldNumber).compose(listLens)
    )
  }

  def forSingularUnknownField[C <: ExtendableMessage[C], E, T](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[E]]
  )(fromBase: E => T, toBase: T => E, default: T): GeneratedExtension[C, T] =
    forUnknownField(fieldNumber, listLens)
      .withLens(singleUnknownFieldLens(fromBase, toBase, default))

  def forOptionalUnknownField[C <: ExtendableMessage[C], E, T](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[E]]
  )(fromBase: E => T, toBase: T => E): GeneratedExtension[C, Option[T]] =
    forUnknownField(fieldNumber, listLens)
      .withLens(optionalUnknownFieldLens(fromBase, toBase))

  def forSingularUnknownMessageField[C <: ExtendableMessage[C], T](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[ByteString]]
  )(fromBase: ByteString => T, toBase: T => ByteString, default: T): GeneratedExtension[C, T] =
    forUnknownField(fieldNumber, listLens)
      .withLens(singleUnknownMessageFieldLens(fromBase, toBase, default))

  def forOptionalUnknownMessageField[C <: ExtendableMessage[C], T](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[ByteString]]
  )(fromBase: ByteString => T, toBase: T => ByteString): GeneratedExtension[C, Option[T]] =
    forUnknownField(fieldNumber, listLens)
      .withLens(optionalUnknownMessageFieldLens(fromBase, toBase))

  @deprecated("Use forRepeatedPackable", "0.11.14")
  def forRepeatedUnknownFieldPackable[C <: ExtendableMessage[C], E, T](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[E]]
  )(
      fromBase: E => T,
      toBase: T => E,
      unpack: CodedInputStream => E
  ): GeneratedExtension[C, Seq[T]] =
    forRepeatedPackable[C, E, T, Seq[T]](fieldNumber, listLens)(fromBase, toBase, unpack)

  def forRepeatedPackable[C <: ExtendableMessage[C], E, T, Coll](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[E]]
  )(
      fromBase: E => T,
      toBase: T => E,
      unpack: CodedInputStream => E
  )(implicit ca: CollectionAdapter[T, Coll]): GeneratedExtension[C, Coll] = {
    GeneratedExtension(
      ExtendableMessage
        .unknownFieldsLen(fieldNumber)
        .compose(listLens zip UnknownFieldSet.Field.lengthDelimitedLens)
        .compose(
          repeatedLensPackable(
            fromBase,
            toBase,
            unpack
          )
        )
    )
  }

  @deprecated("Use forRepeatedUnpackable", "0.11.14")
  def forRepeatedUnknownFieldUnpackable[C <: ExtendableMessage[C], E, T](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[E]]
  )(fromBase: E => T, toBase: T => E): GeneratedExtension[C, Seq[T]] =
    forRepeatedUnpackable[C, E, T, Seq[T]](fieldNumber, listLens)(fromBase, toBase)

  def forRepeatedUnpackable[C <: ExtendableMessage[C], E, T, Coll](
      fieldNumber: Int,
      listLens: Lens[UnknownFieldSet.Field, Seq[E]]
  )(fromBase: E => T, toBase: T => E)(implicit
      ca: CollectionAdapter[T, Coll]
  ): GeneratedExtension[C, Coll] = {
    GeneratedExtension(
      ExtendableMessage
        .unknownFieldsLen(fieldNumber)
        .compose(listLens)
        .compose(repeatedLensUnpackable(fromBase, toBase))
    )
  }

  object Internal {
    def bool2Long(b: Boolean) = if (b) 1L else 0L
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy