Skip to content

protobuf_sources(grpc=True) has no effect on the Scala codegen backend (works for Java, silently no-ops for Scala) #23528

Description

@robertpi

Describe the bug

pants.backend.codegen.protobuf.java reads the generic ProtobufGrpcToggleField (available on both protobuf_source and protobuf_sources targets, regardless of which codegen backend is active) to decide whether to (a) enable gRPC Java stub generation and (b) inject the grpc-java runtime (grpc-netty-shaded, grpc-protobuf, grpc-stub, org.apache.tomcat:annotations-api) as an inferred dependency:

  • src/python/pants/backend/codegen/protobuf/java/rules.py:163-171 — gates the protoc-gen-grpc-java plugin invocation on request.protocol_target.get(ProtobufGrpcToggleField).value.
  • src/python/pants/backend/codegen/protobuf/java/dependency_inference.py:29-38,126-141ProtobufJavaRuntimeDependencyInferenceFieldSet requires ProtobufGrpcToggleField, and infer_protobuf_java_runtime_dependency conditionally adds the grpc-java runtime coordinates when request.field_set.grpc.value is set.

pants.backend.codegen.protobuf.scala never reads this field:

  • src/python/pants/backend/codegen/protobuf/scala/rules.py:228generate_scala_from_protobuf always invokes the ScalaPB shim with a bare f"--scala_out={output_dir}". ScalaPB's own codegen supports a colon-separated modifier on --scala_out (--scala_out=grpc:<dir>) that turns on its built-in *Grpc.scala service-stub generation — sbt-protoc/ScalaPB passes this by default whenever a .proto declares a service, but Pants's Scala backend has no code path that ever adds it. ProtobufGrpcToggleField isn't even imported in this file.
  • src/python/pants/backend/codegen/protobuf/scala/dependency_inference.py:28,79-88ScalaPBRuntimeDependencyInferenceFieldSet.required_fields is (ProtobufDependenciesField, JvmResolveField) only, and infer_scalapb_runtime_dependency unconditionally returns just the base scalapb-runtime_<binary_version> artifact. There's no equivalent of the Java backend's grpc-runtime injection, so even if (1) were fixed, generated *Grpc.scala files referencing scalapb.grpc.* / io.grpc.* would fail to compile with object grpc is not a member of package scalapb / object io is not a member of package <root>.

The net effect: protobuf_sources(grpc=True) on a target resolved by the Scala backend silently produces plain message classes with no service stubs and no gRPC runtime dependency — no error, no warning, just nothing happens. This is surprising because the field already exists generically on protobuf_source/protobuf_sources and visibly works for the Java backend, so grpc=True looks like supported, portable behavior. It's a feature-parity gap between the two backends, not a missing feature.

Pants version

Confirmed present as of main (2.33.0a0 in progress) and 2.32.0. Introduced when ScalaPB codegen/dependency-inference were added (#13853, #14898) — those predate ProtobufGrpcToggleField support even in the Java backend and were never revisited when Java gained it.

OS

N/A (backend logic bug, not platform-specific)

Additional info

  • protobuf_source/protobuf_sources' ProtobufGrpcToggleField is defined once, generically, in pants/backend/codegen/protobuf/target_types.py and consumed per-backend; it is not itself backend-specific.
  • A minimal repro: a protobuf_sources(grpc=True) target whose .proto declares a service, resolved once under a JVM resolve with the Java backend active and once with the Scala backend active. Java backend: generates FooServiceGrpc.java and injects grpc-java coordinates. Scala backend: generates only Foo.scala (message classes), no FooServiceGrpc.scala, no scalapb-runtime-grpc/io.grpc.* dependency — grpc=True has zero observable effect.
  • I have a candidate fix (mirrors the exact pattern in pants.backend.codegen.protobuf.java.dependency_inference) and am happy to open a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions