The service half of protoc-gen-clojure's generated-code contract.
A generated file with a service emits exactly two calls here:
(def Greeter (rts/service file-descriptor "Greeter"))
(def greeter-methods (rts/methods-map Greeter))
service derives everything else — method names, streaming shapes,
request/response prototypes, and (lazily) grpc-java MethodDescriptors with
protobuf marshallers — from the FileDescriptor. The methods map is the bridge
both the server and client builders consume.
Pool discipline, the one subtle thing here: request/response prototypes must live in the same descriptor pool — and on the same codec — as the generated namespace's message prototypes, or the generated proto->X fns crash on parsed messages (protobuf-java forbids cross-pool field access). So the service chooses nothing: it hands each method's request and response Descriptor — the instance the namespace's own FileDescriptor owns — to clj-protobuf.runtime/prototype, which derives the Java class hint by the emitter's own rule and picks the arm rt/message gave the namespace for that message: the generated class, its compiled codec, or DynamicMessage under -Dclj-protobuf.codec=dynamic. One rule, in one place, on both sides of the wire; being wrong costs the optimisation, never correctness.
The service half of protoc-gen-clojure's generated-code contract.
A generated file with a service emits exactly two calls here:
(def Greeter (rts/service file-descriptor "Greeter"))
(def greeter-methods (rts/methods-map Greeter))
`service` derives everything else — method names, streaming shapes,
request/response prototypes, and (lazily) grpc-java MethodDescriptors with
protobuf marshallers — from the FileDescriptor. The methods map is the bridge
both the server and client builders consume.
Pool discipline, the one subtle thing here: request/response prototypes must
live in the same descriptor pool — and on the same codec — as the generated
namespace's message prototypes, or the generated proto->X fns crash on
parsed messages (protobuf-java forbids cross-pool field access). So the
service chooses nothing: it hands each method's request and response
Descriptor — the instance the namespace's own FileDescriptor owns — to
clj-protobuf.runtime/prototype, which derives the Java class hint by the
emitter's own rule and picks the arm rt/message gave the namespace for
that message: the generated class, its compiled codec, or DynamicMessage
under -Dclj-protobuf.codec=dynamic. One rule, in one place, on both sides
of the wire; being wrong costs the optimisation, never correctness.(methods-map svc){:kebab-method-key Method, ...} — the bridge shape the server and client builders consume.
{:kebab-method-key Method, ...} — the bridge shape the server and client
builders consume.(service fd service-name)The service value for a service declared in file-descriptor — the whole
generated-code contract for services.
The service value for a service declared in `file-descriptor` — the whole generated-code contract for services.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |