protocol-buffers - 将第三方 .proto 文件引入 ScalaPB

标签 protocol-buffers scalapb

我怎么知道ScalaPB它应该从 Internet 获取 .proto 依赖项,例如

google/api/annotations.proto 来自 https://github.com/googleapis/googleapis/tree/master/google/api

背景:

目的是通过 gRPC 从 Scala 读取 etcd v3 API。

我从他们的项目中挑选了 etcd 特定的 .proto 文件,并放在我的下面。有用。然而,依赖关系开始深入,必须有更好的方法。

https://github.com/googleapis/googleapis/tree/master/google/api

最佳答案

更新:sbt-protoc 可以从 maven 下载和提取带有 protos 的 jar。它还可以设置为为那些第三方原型(prototype)生成 Scala 代码。

这是如何做到的。在你的 build.sbt 中:

import scalapb.compiler.Version.scalapbVersion

val GrpcProtosArtifact = "com.google.api.grpc" % "grpc-google-common-protos" % "1.17.0"

scalaVersion := "2.12.10"

// This sub-project will hold the compiled Scala classes from the external
// jar.
lazy val googleCommonProtos = (project in file("google-common-protos"))
  .settings(
    name := "google-common-protos",

    // Dependencies marked with "protobuf" get extracted to target / protobuf_external
    libraryDependencies ++= Seq(
      GrpcProtosArtifact % "protobuf"
    ),

    // In addition to the JAR we care about, the protobuf_external directory
    // is going to contain protos from Google's standard protos.  
    // In order to avoid compiling things we don't use, we restrict what's
    // compiled to a subdirectory of protobuf_external
    PB.protoSources in Compile += target.value / "protobuf_external" / "google" / "type",

    PB.targets in Compile := Seq(
      scalapb.gen() -> (sourceManaged in Compile).value
    )
  )

// This sub-project is where your code goes. It contains proto file that imports a proto
// from the external proto jar.
lazy val myProject = (project in file("my-project"))
  .settings(
    name := "my-project",

    // The protos in this sub-project depend on the protobufs in
    // GrpcProtosArtifact, so we need to have them extracted here too. This
    // time we do not add them to `PB.protoSources` so they do not compile.
    libraryDependencies ++= Seq(
      GrpcProtosArtifact % "protobuf"
    ),

    PB.targets in Compile := Seq(
      scalapb.gen() -> (sourceManaged in Compile).value
    ),

  )
  .dependsOn(googleCommonProtos)  // brings the compiled Scala classes from googleCommonProtos

完整示例在这里:https://github.com/thesamet/sbt-protoc/tree/master/examples/google-apis-external-jar


旧答案,已过时:

ScalaPB 不处理第三方依赖项的下载,但是让 SBT 为您下载它们并告诉 ScalaPB 构建下载的原型(prototype)是相当容易的。

以下示例 build.sbt 定义了一个 extractProtos 任务,它从 github 下载您链接到的 repo 的 master 分支作为 zip 文件并将其解压缩。在执行任何操作之前,它会检查目标目录是否不存在,以防止每次编译时都重复下载 zip。

由于里面有很多proto,我们过滤zip文件。源根目录被提取到 target/scala-2.12/resource_managed/googleapis-master,我们将其添加到 PB.protocSources in Compile,因此当调用 protoc 时,它会处理这些文件。

您可以在 src/main/protobuf 中添加更多源,并让它们 "import "google/rpc/..."

scalaVersion := "2.12.2"

libraryDependencies ++= Seq(
    "io.grpc" % "grpc-netty" % com.trueaccord.scalapb.compiler.Version.grpcJavaVersion,
    "com.trueaccord.scalapb" %% "scalapb-runtime-grpc" % com.trueaccord.scalapb.compiler.Version.scalapbVersion
)

PB.targets in Compile := Seq(
  scalapb.gen() -> (sourceManaged in Compile).value
)

PB.generate in Compile := (PB.generate in Compile).dependsOn(extractProtos).value

PB.protoSources in Compile += resourceManaged.value / "googleapis-master"

lazy val extractProtos = Def.task {
  if (!(resourceManaged.value / "googleapis-master").exists) {
    val zipUrl = "https://github.com/googleapis/googleapis/archive/master.zip"
    println(s"Unzipping $zipUrl.")
    IO.unzipURL(
        from=url(zipUrl),
        filter=(
          "googleapis-master/google/bigtable/admin/v2/*" |
          "googleapis-master/google/api/*" | 
          "googleapis-master/google/logging/*" |
          "googleapis-master/google/longrunning/*" |
          "googleapis-master/google/rpc/*" |
          "googleapis-master/google/type/*"
        ),
        toDirectory=resourceManaged.value)
  }
}

libraryDependencies += "com.trueaccord.scalapb" %% "scalapb-runtime" %
  com.trueaccord.scalapb.compiler.Version.scalapbVersion % "protobuf"

关于protocol-buffers - 将第三方 .proto 文件引入 ScalaPB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44282240/

相关文章:

protocol-buffers - Protobuf3 : How to describe map of repeated string?

scala - 如何使用 ScalaPB 序列化/反序列化使用 'oneof' 的 protobuf 消息?

scala - 对象不是包的成员

java - 带有数字的 Protobuf 字段名称以意想不到的方式大写

go - 在 go 中按顺序将 protobuf 消息写入文件

java - 使用 ScalaPB 中的 Protocol Buffers 生成 Java 和 Scala 类

protocol-buffers - 如何使用 ScalaPB 将 protobuf Enum 生成为字符串?

c# - protobuf-csharp-port 是否支持 Windows RT?

java - GRPC 服务器响应延迟