Add gRPC-Web client codegen mirroring the OpenAPI pattern#5099
Open
shai-almog wants to merge 5 commits into
Open
Add gRPC-Web client codegen mirroring the OpenAPI pattern#5099shai-almog wants to merge 5 commits into
shai-almog wants to merge 5 commits into
Conversation
Generate typed gRPC clients from proto3 .proto files the same way cn1:generate-openapi turns OpenAPI specs into REST clients: a Maven goal emits user-edited @ProtoMessage / @ProtoEnum / @GrpcClient sources into src/main/java, two build-time annotation processors emit the protobuf codecs + gRPC-Web call sites into target/generated-sources, and a pair of bootstrap classes plug everything into the runtime registries before Display.init. Wire protocol is gRPC-Web binary (application/grpc-web+proto) -- plain HTTP/2 gRPC requires trailers that ConnectionRequest does not expose, but gRPC-Web is the standard mobile/browser variant that works with Envoy, the official grpcweb Go proxy, and the gRPC-Web filter shipped with modern gRPC server implementations. Scope of v1: unary RPCs, proto3, all scalar types, nested messages, enums, repeated fields. Streaming, map<K,V>, well-known types, and `import` are out -- the parser errors cleanly on each. Also closes a pre-existing gap where cn1app.RestClientBootstrap was generated by the OpenAPI processor but never spliced into the Executor stub / JavaSEPort class-forname loop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
Contributor
Cloudflare Preview
|
Ant build uses a CLDC11.jar bootclasspath that lacks Float .floatToRawIntBits / Double.doubleToRawLongBits. Switch to the plain floatToIntBits / doubleToLongBits variants -- the only behavioural difference is that NaN bit patterns collapse to the canonical NaN, which protobuf does not distinguish anyway. Also: Vale Microsoft.Contractions wanted "doesn't" over "does not" in the appendix; LanguageTool's English dictionary did not recognise "protobuf", "varint", and "enums" so add them to the developer-guide accept list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
Compared 122 screenshots: 122 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
Collaborator
Author
|
Compared 11 screenshots: 11 matched. |
Collaborator
Author
|
Compared 122 screenshots: 122 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
Collaborator
Author
|
Compared 122 screenshots: 122 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
Collaborator
Author
|
Compared 47 screenshots: 47 matched. |
The inner GrpcConnection extends ConnectionRequest and adds state (response codec, callback, failure flags). SpotBugs flagged the missing equals/hashCode override; match the pattern used by RequestBuilder.Connection (delegate to super then compare the new fields). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PMD's ControlStatementBraces rule rejects every `if (cond) stmt;` style one-liner; brace the body so the rule passes. 28 sites across ProtoWriter / ProtoReader / GrpcWeb. No behaviour change. Also drop `public` from `WireKind` enum nested inside the `@ProtoField` annotation -- members of an annotation type are implicitly public, so PMD's UnnecessaryModifier rule flags the qualifier as redundant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Checkstyle requires `{` to be followed by a line break, which the
previous round of PMD ControlStatementBraces fixes violated by
braceing the same-line form (`if (cond) { stmt; }`). Expand each
flagged site to the canonical multi-line shape:
if (cond) {
stmt;
}
28 sites across ProtoWriter / ProtoReader / GrpcWeb; no behaviour
change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
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
cn1:generate-grpcMaven goal that turns proto3.protofiles into hand-editable@ProtoMessage/@ProtoEnum/@GrpcClientsources, point-for-point matching the developer experience of the recently-addedcn1:generate-openapigoal.com.codename1.io.grpc.*) and build-time annotation processors that emit binary protobuf codecs and gRPC-Web call sites intotarget/generated-sourcesso the project source stays clean.application/grpc-web+proto). Plain HTTP/2 gRPC needs trailers thatConnectionRequestdoesn't expose; gRPC-Web is the standard mobile/browser variant that works with Envoy, the officialgrpcwebGo proxy, and the gRPC-Web filter shipped with modern gRPC server implementations.cn1app.RestClientBootstrapwas generated by the OpenAPI processor but never spliced intoExecutor.annotationFrameworksInstallSourceorJavaSEPort.postInit.What lands where
Runtime (cn1-core):
com.codename1.annotations.grpc—@GrpcClient,@Rpc,@ProtoMessage,@ProtoField,@ProtoEnumcom.codename1.io.grpc—ProtoWriter/ProtoReader/ProtoCodec/ProtoCodecs,GrpcWeb(framing + trailer parsing),GrpcResponse,GrpcException,GrpcClientsregistryMaven plugin:
GenerateGrpcMojo— hand-rolled proto3 parser + emitter (noprotocdependency)ProtoMessageAnnotationProcessor— emits per-class<T>ProtoCodec+cn1app.ProtoBootstrapGrpcClientAnnotationProcessor— emits<Service>Impl+cn1app.GrpcClientBootstrapExecutor+JavaSEPortto install the three new bootstrapsCall site
Scope of v1
repeatedfields.map<K, V>, well-known types, andimportare explicitly out — the parser errors cleanly on each.Test plan
-source 1.5 -target 1.5.helloworld.proto, point at an Envoygrpc-webproxy, run a unary RPC end-to-end from the simulator.Docs
docs/developer-guide/appendix_goal_generate_grpc.adocadded and included inMaven-Appendix-Goals.adoc.🤖 Generated with Claude Code