You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[WIP]Add experimental SSE support to Java emitter - #12312
Add experimental typed SSE generation for explicitly named, nonliteral JSON events in the Azure v1 flavor.
Generate asynchronous Flux<Event> and synchronous CloseableIterableStream<Event> convenience APIs with a base event type and typed subtypes.
Support named model, scalar, array, dictionary, and recursive collection payloads, including @data extraction. Decode scalar wire types with existing wire-to-client conversion, including encoded durations in nested collections. Deliver named terminal events inclusively.
Keep TCGC metadata in a canonical CID-keyed CodeModel.sseStreams catalog referenced by operations, without structural metadata fingerprints. Register payload models only when typed convenience APIs are generated.
Preserve customized operation names, visibility, protocol *WithResponse binary APIs, generation gates, SDK-only wrapper constructors, and strict generated-name/source-path checks. Qualify colliding payload references and resolve event, container, converter, and runtime-helper references against the complete client import set, including request models and enums on other methods. Preserve Reactor references in versioned-parameter validation and generate historical sync/async parameter overloads for older service versions.
Reuse incremental framing, cancellation, and resource-closure helpers. Unknown event names produce name-only, nonterminal wrappers.
Experimental scope
Unnamed events, mixed named/unnamed unions, all event-payload literals including [DONE], and unsupported nullable event payloads are diagnosed and retain ordinary binary APIs rather than generating partial typed output. Unnamed support is deferred to a follow-up PR. Nullable properties inside ordinary model payloads are unaffected. Reconnection and historical Search wrapper/customization migration are outside this change.
Supported Azure v1 streams are generated automatically; no dev-options.enable-sse option is required or supported. Other flavors and unsupported streams retain their existing APIs.
Cleanup
Keep exactly one SSE test source under tsptest: ServerSentEventStreamTests.java.
Consolidate emitter SSE fixtures into emitter/test/fixtures/sse.tsp, with comments separating scenarios and isolated virtual service entrypoints for each test.
Remove direct/default/literal generation paths, obsolete fixtures, and the redundant SSE-specific file-cleanup test.
Restore usage.md to its pre-PR content.
Consolidate the SSE changelog into one feature entry: “Support generating APIs for server-sent events (SSE).”
Validation
Added failing regressions before fixing unsupported-shape handling, temporal decoding, nullable fallback, protocol-only payload usage, generated type/import collisions, empty descriptions for short stream names, versioned-parameter error handling, and historical SSE overloads.
Full Java package build/tests, focused generator regressions, and 62 emitter tests passed.
Generated Java 11 module/client compilation reproduced request model/enum, container, runtime-helper, converter, versioned-validation, and missing historical-overload errors before the fixes and passed afterward.
Verified one emitter SSE fixture, one tsptest SSE test source, no usage.md diff against the base, and one SSE changeset.
Copilot review of final head 9a7cdb5ba reports No open issues, with zero inline comments, no actionable body-only findings, and no unresolved review threads. This is a COMMENTED review, not human approval; the PR remains draft.
Curious why this is opt-in rather than just enabled?
Since we already had SSE customization code for Search GA Java SDK, my initial gut feeling is that we don't do major emitter changes before Search GA release.
Though current generated code is almost identical without customization, guess I could remove this opt-in once this PR's mature.
This accepts named events without checking event.payloadContentType, including string payloads explicitly marked @contentType("text/plain") (supported by packages/events/lib/decorators.tsp:41). Their unquoted SSE data is then passed to JsonProviders.createReader by SseEventConverterTemplate.java:146, so valid streams fail decoding; reject non-JSON payload content types through the existing unsupported-stream diagnostic and retain the raw APIs.
Generate stream callbacks from wire types before client conversion
Calling getClientType() before generating the JSON callback discards wire encodings: a seconds-encoded duration maps to Duration and is decoded with Duration.parse(...) rather than reading the numeric seconds (PrimitiveMapper.java:113–126, ClassType.java:466), so valid payloads fail during iteration, including inside collections. Generate callbacks from the mapped wire type and then convert the decoded value to its client type, as StreamSerializationModelTemplate.java:1564–1599 does.
Calling getClientType() before building the JSON callback discards wire encodings: for example, a seconds-encoded duration becomes Duration and generates Duration.parse(reader.getString()), which fails on a valid numeric SSE payload such as 42. Deserialize using the wire type and then apply its client conversion (as WireTypeClientTypeConverter.java:105–120 does), recursively for collection elements, or retain the raw API for these encodings.
Transport SSE definitions by union CID and bind canonical references before Java mapping. Emit only mapped definitions, preserve named output, and generate direct unnamed payloads or typed mixed and primitive-literal wrappers with strict matching and inclusive termination.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
Inline operation metadata and collect used SSE artifacts by CID.
Rename event converters to serializers, merge stream helpers, and use
ordinary Java imports. Strengthen metadata validation and coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Conflicting SSE type imports can make generated Java code fail compilation, while validation ordering can incorrectly abort generation for unsupported streams.
Compose inline synthetic base and event schemas in the emitter, consume their identities and relationships in Java, and remove obsolete wrapper naming plumbing.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 14ecbaeb-e976-401b-b4ef-40d8cbcd7bd3
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Unresolved SSE import and type-name collisions with request models and JDK payload types can generate uncompilable clients, event envelopes, and serializers.
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
emitter:client:javaIssue for the Java client emitter: @typespec/http-client-java
3 participants
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
Add experimental typed SSE generation for explicitly named, nonliteral JSON events in the Azure v1 flavor.
Flux<Event>and synchronousCloseableIterableStream<Event>convenience APIs with a base event type and typed subtypes.@dataextraction. Decode scalar wire types with existing wire-to-client conversion, including encoded durations in nested collections. Deliver named terminal events inclusively.CodeModel.sseStreamscatalog referenced by operations, without structural metadata fingerprints. Register payload models only when typed convenience APIs are generated.*WithResponsebinary APIs, generation gates, SDK-only wrapper constructors, and strict generated-name/source-path checks. Qualify colliding payload references and resolve event, container, converter, and runtime-helper references against the complete client import set, including request models and enums on other methods. Preserve Reactor references in versioned-parameter validation and generate historical sync/async parameter overloads for older service versions.Experimental scope
Unnamed events, mixed named/unnamed unions, all event-payload literals including
[DONE], and unsupported nullable event payloads are diagnosed and retain ordinary binary APIs rather than generating partial typed output. Unnamed support is deferred to a follow-up PR. Nullable properties inside ordinary model payloads are unaffected. Reconnection and historical Search wrapper/customization migration are outside this change.Supported Azure v1 streams are generated automatically; no
dev-options.enable-sseoption is required or supported. Other flavors and unsupported streams retain their existing APIs.Cleanup
tsptest:ServerSentEventStreamTests.java.emitter/test/fixtures/sse.tsp, with comments separating scenarios and isolated virtual service entrypoints for each test.usage.mdto its pre-PR content.Validation
git diff --checkpassed.tsptestSSE test source, nousage.mddiff against the base, and one SSE changeset.9a7cdb5bareports No open issues, with zero inline comments, no actionable body-only findings, and no unresolved review threads. This is aCOMMENTEDreview, not human approval; the PR remains draft.