This is an automated email from the ASF dual-hosted git repository.
fanningpj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko-grpc.git
The following commit(s) were added to refs/heads/main by this push:
new f6aca6ea Add 'using' for implicit args in Scala 3 sources (#597)
f6aca6ea is described below
commit f6aca6ea846ed16aefa521fe388f82bb72f6caba
Author: PJ Fanning <[email protected]>
AuthorDate: Thu Jan 22 10:37:27 2026 +0100
Add 'using' for implicit args in Scala 3 sources (#597)
* Add 'using' for implicit args in Scala 3 sources.
Generate 'using' for explicitly invoked implicit arg lists.
Silences warnings in Scala 3 and -Xsource:3 compilation.
* new test
Update helloworld.proto
* Update helloworld.proto
* Fix configuration key for HTTP2 in application.conf
---------
Co-authored-by: Tim Whittington <[email protected]>
---
.../grpc/gen/scaladsl/ScalaCompatConstants.scala | 2 +
.../twirl/templates/ScalaServer/Handler.scala.txt | 4 +-
.../sbt-test/scala3/02-scala3-sourcegen/build.sbt | 19 +++++++++
.../scala3/02-scala3-sourcegen/project/plugins.sbt | 10 +++++
.../src/main/protobuf/helloworld.proto | 35 ++++++++++++++++
.../src/main/resources/application.conf | 7 ++++
.../myapp/helloworld/GreeterServiceImpl.scala | 32 +++++++++++++++
.../myapp/helloworld/GreeterServiceSpec.scala | 47 ++++++++++++++++++++++
.../src/sbt-test/scala3/02-scala3-sourcegen/test | 1 +
9 files changed, 155 insertions(+), 2 deletions(-)
diff --git
a/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCompatConstants.scala
b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCompatConstants.scala
index 1389f359..847f96bc 100644
---
a/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCompatConstants.scala
+++
b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCompatConstants.scala
@@ -20,4 +20,6 @@ package org.apache.pekko.grpc.gen.scaladsl
private[scaladsl] class ScalaCompatConstants(emitScala3Sources: Boolean =
false) {
// val WildcardType: String = if (emitScala3Sources) "?" else "_"
val WildcardImport: String = if (emitScala3Sources) "*" else "_"
+
+ val ImplicitUsing: String = if (emitScala3Sources) "using " else ""
}
diff --git a/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt
b/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt
index 697f8741..42c46584 100644
--- a/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt
+++ b/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt
@@ -129,9 +129,9 @@ object @{serviceName}Handler {
@for(method <- service.methods) {
case "@method.grpcName" =>
@{if(powerApis) { "val metadata =
MetadataBuilder.fromHeaders(request.headers)" } else { "" }}
- @{method.unmarshal}(request.entity)(@method.deserializer.name,
mat, reader)
+
@{method.unmarshal}(request.entity)(@{service.scalaCompatConstants.ImplicitUsing}@method.deserializer.name,
mat, reader)
.@{if(method.outputStreaming) { "map" } else { "flatMap"
}}(implementation.@{method.nameSafe}(_@{if(powerApis) { ", metadata" } else {
"" }}))
- .map(e => @{method.marshal}(e,
eHandler)(@method.serializer.name, writer, system))
+ .map(e => @{method.marshal}(e,
eHandler)(@{service.scalaCompatConstants.ImplicitUsing}@method.serializer.name,
writer, system))
}
case m => scala.concurrent.Future.failed(new
NotImplementedError(s"Not implemented: $m"))
})
diff --git a/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/build.sbt
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/build.sbt
new file mode 100644
index 00000000..c218d549
--- /dev/null
+++ b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/build.sbt
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * license agreements; and to You under the Apache License, version 2.0:
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * This file is part of the Apache Pekko project, which was derived from Akka.
+ */
+
+scalaVersion := "3.3.7"
+
+scalacOptions += "-Xfatal-warnings"
+
+enablePlugins(PekkoGrpcPlugin)
+
+resolvers += Resolver.ApacheMavenSnapshotsRepo
+
+libraryDependencies ++= Seq(
+ "org.scalatest" %% "scalatest" % "3.2.19" % Test)
diff --git
a/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/project/plugins.sbt
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/project/plugins.sbt
new file mode 100644
index 00000000..5eb2b655
--- /dev/null
+++ b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/project/plugins.sbt
@@ -0,0 +1,10 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * license agreements; and to You under the Apache License, version 2.0:
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * This file is part of the Apache Pekko project, which was derived from Akka.
+ */
+
+addSbtPlugin("org.apache.pekko" % "pekko-grpc-sbt-plugin" %
sys.props("project.version"))
diff --git
a/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/protobuf/helloworld.proto
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/protobuf/helloworld.proto
new file mode 100644
index 00000000..7692f603
--- /dev/null
+++
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/protobuf/helloworld.proto
@@ -0,0 +1,35 @@
+syntax = "proto3";
+
+import "scalapb/scalapb.proto";
+
+option java_multiple_files = true;
+option java_package = "example.myapp.helloworld.grpc";
+option java_outer_classname = "HelloWorldProto";
+
+option (scalapb.options) = {
+ scala3_sources: true
+};
+
+package helloworld;
+
+// The greeting service definition.
+service GreeterService {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+
+ rpc ItKeepsTalking (stream HelloRequest) returns (HelloReply) {}
+
+ rpc ItKeepsReplying (HelloRequest) returns (stream HelloReply) {}
+
+ rpc StreamHellos (stream HelloRequest) returns (stream HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}
diff --git
a/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/resources/application.conf
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/resources/application.conf
new file mode 100644
index 00000000..1608dd09
--- /dev/null
+++
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/resources/application.conf
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: Apache-2.0
+
+pekko.http.server.enable-http2 = on
+
+pekko.grpc.client."*" {
+ backend = "pekko-http"
+}
diff --git
a/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/scala/example/myapp/helloworld/GreeterServiceImpl.scala
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/scala/example/myapp/helloworld/GreeterServiceImpl.scala
new file mode 100644
index 00000000..f2528e90
--- /dev/null
+++
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/main/scala/example/myapp/helloworld/GreeterServiceImpl.scala
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * license agreements; and to You under the Apache License, version 2.0:
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * This file is part of the Apache Pekko project, which was derived from Akka.
+ */
+
+package example.myapp.helloworld
+
+import scala.concurrent.Future
+
+import org.apache.pekko
+import pekko.NotUsed
+import pekko.stream.scaladsl.Source
+
+import example.myapp.helloworld.grpc._
+
+class GreeterServiceImpl extends GreeterService:
+
+ override def sayHello(in: HelloRequest): Future[HelloReply] =
+ Future.successful(HelloReply(s"Hello, ${in.name}!"))
+
+ override def streamHellos(in: Source[HelloRequest, NotUsed]):
Source[HelloReply, NotUsed] =
+ ???
+
+ override def itKeepsTalking(in: Source[HelloRequest, NotUsed]):
Future[HelloReply] =
+ ???
+
+ override def itKeepsReplying(in: HelloRequest): Source[HelloReply, NotUsed] =
+ ???
diff --git
a/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/test/scala/example/myapp/helloworld/GreeterServiceSpec.scala
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/test/scala/example/myapp/helloworld/GreeterServiceSpec.scala
new file mode 100644
index 00000000..e13799f6
--- /dev/null
+++
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/src/test/scala/example/myapp/helloworld/GreeterServiceSpec.scala
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * license agreements; and to You under the Apache License, version 2.0:
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * This file is part of the Apache Pekko project, which was derived from Akka.
+ */
+
+package example.myapp.helloworld;
+
+import scala.concurrent.duration._
+
+import org.apache.pekko
+import pekko.actor.ActorSystem
+import pekko.http.scaladsl.Http
+
+import pekko.grpc.GrpcClientSettings
+
+import example.myapp.helloworld.grpc._
+
+import org.scalatest.concurrent.ScalaFutures
+import org.scalatest.concurrent.PatienceConfiguration
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.time.{ Millis, Seconds, Span }
+import org.scalatest.wordspec.AnyWordSpec
+
+class GreeterServiceSpec extends AnyWordSpec with Matchers with ScalaFutures:
+ implicit val system: ActorSystem = ActorSystem("GreeterServiceSpec")
+
+ val binding = Http()
+ .newServerAt("localhost", 0)
+ .bind(GreeterServiceHandler(new GreeterServiceImpl()))
+ .futureValue
+
+ val client = GreeterServiceClient(
+ GrpcClientSettings.connectToServiceAt(
+ "localhost",
+ binding.localAddress.getPort).withTls(false))
+
+ "A GreeterService" should {
+ "respond to a unary request" in {
+ val reply = client.sayHello(HelloRequest("Dave"))
+ val r = scala.concurrent.Await.result(reply, 10.seconds)
+ r.message shouldBe "Hello, Dave!"
+ }
+ }
diff --git a/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/test
b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/test
new file mode 100644
index 00000000..dfffb838
--- /dev/null
+++ b/sbt-plugin/src/sbt-test/scala3/02-scala3-sourcegen/test
@@ -0,0 +1 @@
+> test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]