Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/scala.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
- uses: actions/checkout@v2
- name: Setup protoc
uses: arduino/setup-protoc@v1
with:
version: '3.17.3'
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
Expand Down
3 changes: 2 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ maxColumn = 160
includeCurlyBraceInSelectChains = false
project.git = true
project.excludeFilters = ["target/"]
version = 2.6.4
version = 3.2.1
runner.dialect = scala3
73 changes: 38 additions & 35 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,59 +1,62 @@
import sbt._

lazy val scala213 = "2.13.6"
lazy val scala212 = "2.12.12"
lazy val scala212 = "2.12.14"
lazy val scala3 = "3.1.0"

lazy val supportedScalaVersions = List(scala212, scala213)
lazy val supportedScalaVersions = List(scala212, scala213, scala3)

val commonSettings = Seq(
scalaVersion := scala213,
scalacOptions += "-language:experimental.macros",
organization := "com.github.changvvb",
crossScalaVersions := supportedScalaVersions,
releasePublishArtifactsAction := PgpKeys.publishSigned.value
scalaVersion := scala3,
scalacOptions += "-language:experimental.macros",
organization := "com.github.changvvb",
crossScalaVersions := supportedScalaVersions,
releasePublishArtifactsAction := PgpKeys.publishSigned.value
)

lazy val `scala-protobuf-java-macro` = project.in(file("pbconverts-macro"))
.settings(libraryDependencies ++= Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value))
.settings(commonSettings)
.enablePlugins(ProtobufPlugin)

lazy val `scala-protobuf-java` = project.in(file("pbconverts"))
.settings(libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.0" % "test")
lazy val `scala-protobuf-java` = project
.in(file("pbconverts"))
.settings(libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.9" % "test")
.settings(libraryDependencies ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, _)) => Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value)
case _ => Nil
}
})
.settings(commonSettings)
.dependsOn(`scala-protobuf-java-macro`)
.enablePlugins(ProtobufTestPlugin)

lazy val root = project.in(file(".")).withId("root")
.aggregate(`scala-protobuf-java`, `scala-protobuf-java-macro`)
lazy val root = project
.in(file("."))
.withId("root")
.aggregate(`scala-protobuf-java`)
.settings(publishArtifact := false)

scalafmtOnCompile in ThisBuild := true

// publish
ThisBuild / scalafmtOnCompile := true

releasePublishArtifactsAction in ThisBuild := releaseStepCommandAndRemaining("+publishSigned")
ThisBuild / releasePublishArtifactsAction := releaseStepCommandAndRemaining("+publishSigned")

publishTo in ThisBuild := {
val nexus = "https://oss.sonatype.org/"
if (version.value.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
ThisBuild / publishTo := {
val nexus = "https://oss.sonatype.org/"
if (version.value.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

publishMavenStyle in ThisBuild := true
ThisBuild / publishMavenStyle := true

credentials in ThisBuild += Credentials(Path.userHome / ".ivy2" / ".credentials_sonatype")
ThisBuild / credentials += Credentials(Path.userHome / ".ivy2" / ".credentials_sonatype")

publishArtifact in Test := false
Test / publishArtifact := false

pomIncludeRepository in ThisBuild := { _ => false }
ThisBuild / pomIncludeRepository := { _ => false }

homepage in ThisBuild := Some(url("https://github.com/changvvb/scala-protobuf-java"))
ThisBuild / homepage := Some(url("https://github.com/changvvb/scala-protobuf-java"))

pomExtra in ThisBuild := {
<licenses>
ThisBuild / pomExtra := {
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
Expand All @@ -74,5 +77,5 @@ pomExtra in ThisBuild := {
</developers>
}

publishConfiguration in ThisBuild := publishConfiguration.value.withOverwrite(true)
publishLocalConfiguration in ThisBuild := publishLocalConfiguration.value.withOverwrite(true)
ThisBuild / publishConfiguration := publishConfiguration.value.withOverwrite(true)
ThisBuild / publishLocalConfiguration := publishLocalConfiguration.value.withOverwrite(true)
Original file line number Diff line number Diff line change
Expand Up @@ -319,19 +319,18 @@ class ProtoScalableMacro(val c: whitebox.Context) {
val caseClassType = resolveType[T]
val protoType = resolveType[M]
val customTrees = MacroCache.builderFunctionTrees.getOrElse(getBuilderId(), mutable.Map.empty)
val (fixedCustomTrees, preTrees) = customTrees.map {
case (key, tree) ⇒
tree match { // setField
case buildFunction: Function ⇒
val functionName = TermName("builderFunction$" + MacroCache.getIdentityId)
val fromType = buildFunction.tpe.typeArgs.last // buildFunction 的返回值
val buildExpr = new ToProtoProcessor(q"$functionName($entityIdent)", fromType, caseClassType, protoType, key).tree.get
(key -> buildExpr) -> q"val $functionName = $buildFunction"
case value: Tree ⇒ // setFieldValue
val identity = TermName("identity$" + MacroCache.getIdentityId)
val buildExpr = new ToProtoProcessor(q"$identity", value.tpe, caseClassType, protoType, key).tree.get
(key -> buildExpr) -> q"val $identity = $value"
}
val (fixedCustomTrees, preTrees) = customTrees.map { case (key, tree) ⇒
tree match { // setField
case buildFunction: Function ⇒
val functionName = TermName("builderFunction$" + MacroCache.getIdentityId)
val fromType = buildFunction.tpe.typeArgs.last // buildFunction 的返回值
val buildExpr = new ToProtoProcessor(q"$functionName($entityIdent)", fromType, caseClassType, protoType, key).tree.get
(key -> buildExpr) -> q"val $functionName = $buildFunction"
case value: Tree ⇒ // setFieldValue
val identity = TermName("identity$" + MacroCache.getIdentityId)
val buildExpr = new ToProtoProcessor(q"$identity", value.tpe, caseClassType, protoType, key).tree.get
(key -> buildExpr) -> q"val $identity = $value"
}
}.unzip
val protoableFieldConvertTrees = (defaultProtoableFieldConvertTrees(caseClassType, protoType) ++ fixedCustomTrees.toMap).values
protosImpl(caseClassType, protoType, protoableFieldConvertTrees, preTrees)
Expand All @@ -344,19 +343,18 @@ class ProtoScalableMacro(val c: whitebox.Context) {
val customTrees = MacroCache.builderFunctionTrees.getOrElse(builderId, mutable.Map.empty)
val entityType = resolveType[T]

val (fixedCustomTrees, preTrees) = customTrees.map {
case (key, tree) ⇒
val selector = entityType.member(TermName(key))
tree match {
case buildFunction: Function ⇒ // setField
val functionName = TermName("builderFunction$" + MacroCache.getIdentityId)
val expr = new ToScalaProcessor(selector.asMethod, q"$functionName($protoIdent)", buildFunction.body.tpe, resolveType[T], resolveType[M]).tree.get
(key -> expr) -> q"val $functionName = $buildFunction"
case value: Tree ⇒ // setFieldValue
val identity = TermName("identity$" + MacroCache.getIdentityId)
val expr = new ToScalaProcessor(selector.asMethod, q"$identity", value.tpe, resolveType[T], resolveType[M]).tree.get
(key -> expr) -> q"val $identity = $value"
}
val (fixedCustomTrees, preTrees) = customTrees.map { case (key, tree) ⇒
val selector = entityType.member(TermName(key))
tree match {
case buildFunction: Function ⇒ // setField
val functionName = TermName("builderFunction$" + MacroCache.getIdentityId)
val expr = new ToScalaProcessor(selector.asMethod, q"$functionName($protoIdent)", buildFunction.body.tpe, resolveType[T], resolveType[M]).tree.get
(key -> expr) -> q"val $functionName = $buildFunction"
case value: Tree ⇒ // setFieldValue
val identity = TermName("identity$" + MacroCache.getIdentityId)
val expr = new ToScalaProcessor(selector.asMethod, q"$identity", value.tpe, resolveType[T], resolveType[M]).tree.get
(key -> expr) -> q"val $identity = $value"
}
}.unzip

val scalableFieldConvertTrees = (defalutScalableFieldConvertTrees(caseClassType, protoType) ++ fixedCustomTrees.toMap).values
Expand Down
7 changes: 7 additions & 0 deletions pbconverts/src/main/scala-3/pbconverts/MacroCache.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package pbconverts

import scala.collection.mutable

object MacroCache {
lazy val builderFunctionTrees: mutable.Map[String, mutable.Map[String, Any]] = mutable.Map.empty
}
18 changes: 18 additions & 0 deletions pbconverts/src/main/scala-3/pbconverts/ProtoScalable.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package pbconverts

import com.google.protobuf.Message

trait ProtoScalable[S, P] extends Protoable[S, P] with Scalable[S, P]

object ProtoScalable {

inline def apply[S <: Product, P <: Message]: ProtoScalable[S, P] = ProtoScalableMacro.protoScalable[S, P]

def apply[S, P](toProtoFun: S ⇒ P, toScalaFun: P ⇒ S): ProtoScalable[S, P] =
new ProtoScalable[S, P] {

override def toScala(proto: P): S = toScalaFun(proto)

override def toProto(entity: S): P = toProtoFun(entity)
}
}
Loading