feat: generated-service layer (GenericService) + grpc_tools_ruby_protoc codegen - #3
Merged
Merged
Conversation
…oc codegen Close the service-codegen surface of the grpc gem on top of the existing pure-Go runtime. GenericService ports GRPC::GenericService — the mixin a generated *_services_pb.rb Service base class includes: NewGenericService(name) + RPC(...) (the `rpc :Name, In, Out` macro), BuildService pairing declarations with handlers into a runtime Service to Handle, and StubClass deriving the client GenericStub (the gem's rpc_stub_class). The generated stub carries each rpc's marshal/unmarshal, so a caller supplies only the request(s); all four cardinalities are covered and driven end-to-end over the in-memory transport, plus a wire-interop oracle where a GenericStub calls a stock google.golang.org/grpc server with real protobuf messages. GenerateRubyServices is the grpc_tools_ruby_protoc equivalent: given a .proto's service block it emits the exact *_services_pb.rb source — byte-for-byte as the gem's generator — covering unary + all streaming shapes (stream(...)), multiple services per file, dotted/underscored packages, nested and cross-package message types, and package-less files. A differential oracle runs the real grpc_tools_ruby_protoc (grpc-tools gem) and asserts byte-equality, skip-gated when the gem is absent; inline goldens pin the format either way. CGO=0, gofmt + go vet clean, 100% coverage, -race clean, and green across the six 64-bit targets + js/wasm + wasip1/wasm. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the service-codegen surface of Ruby's
grpcgem on top of the existing pure-Go runtime (RpcServer / ClientStub / ActiveCall were already ported). Two halves:GenericService— the generatedServicebase (GRPC::GenericService)NewGenericService(name)+RPC(RpcDesc{...})mirrorself.service_name = ...and therpc :Name, In, Outclass macro;RpcDescs,LookupRPC, chainable declaration, duplicate-replace.BuildService(Handlers)pairs the declarations with handlers into a runtimeServiceforRpcServer.Handle(mirrors implementing the generated subclass' instance methods).StubClass(*ClientStub)derives the client*GenericStub— the gem'srpc_stub_class. The generated stub carries each rpc's marshal/unmarshal, so a caller supplies only the request(s):RequestResponse/ClientStreamer/ServerStreamer/BidiStreamer.GenerateRubyServices— thegrpc_tools_ruby_protocequivalentGiven a
.proto's service block (ServiceFile/ServiceGen/MethodGen), emits the exact*_services_pb.rbsource byte-for-byte as the gem's generator: unary + all streaming shapes (stream(...)), multiple services per file, dotted & underscored packages, nested and cross-package message types, and package-less files.gRPC surface implemented vs residual
Codegen: ✅ server base +
Stub, all cardinalities, byte-faithful.Residual (named): message-
.protoparsing / message codegen stay in go-ruby-protobuf (runtime descriptor builder); a Ruby constant for a nested type imported from another package is approximated (same-package and flat cross-package are byte-exact); TLS/ChannelCredentials, xDS, channelz, and health/reflection services are follow-ups.Interop / differential oracle
grpc_tools_ruby_protoc(grpc-toolsgem) is run per-.protoand our output is asserted equal to the byte; skip-gated when the gem is absent, with inline goldens pinning the format either way. Verified live against grpc-tools 1.83 (helloworld unary + route_guide all-streaming).GenericStubcalls a stockgoogle.golang.org/grpcserver over the in-memory transport with real protobuf messages — wire interop, not asserted shape.House rules
CGO=0,
go 1.26.4, BSD-3 + SPDX headers,gofmt+go vetclean, 100% coverage,-raceclean, builds green on amd64/arm64/riscv64/loong64/ppc64le/s390x + js/wasm + wasip1/wasm.🤖 Generated with Claude Code