Skip to content

Apply @@override options bags to protocol methods - #11523

Open
m-nash wants to merge 5 commits into
microsoft:mainfrom
m-nash:fix/issue-11214
Open

Apply @@override options bags to protocol methods#11523
m-nash wants to merge 5 commits into
microsoft:mainfrom
m-nash:fix/issue-11214

Conversation

@m-nash

@m-nash m-nash commented Aug 3, 2026

Copy link
Copy Markdown
Member

Fixes #11214

When @@override groups an operation's parameters into an options bag, only the convenience method adopted the grouped shape. The protocol method kept listing every parameter individually, so a spec that hides the convenience method (or a caller that wants the protocol surface) still got a 40-parameter signature.

Before / after

// Before
public virtual Response GetWidget(string id, string filter, int? top, RequestOptions options)

// After
public virtual Response GetWidget(GetWidgetOptions options, RequestOptions requestOptions)

Behavior

The protocol method must always retain a way to send a raw payload, so grouping is applied conditionally:

Options bag contains Protocol method Raw body preserved
no body parameter (Options options, RequestOptions requestOptions) n/a
body declared outside the bag (BinaryContent content, Options options, RequestOptions requestOptions) yes
body inside the bag flattened, as today yes

Implementation

RestClientProvider

  • GetMethodParameters sources protocol parameters from serviceMethod.Parameters (the grouped shape) when grouping applies. CreateRequest continues to use the flattened operation.Parameters.
  • Body conversion now also handles InputMethodParameter { Location: Body } so a body declared outside the bag still becomes request content.
  • New ShouldGroupProtocolParameters decides applicability: at least one operation parameter carries MethodParameterSegments, and the segment root is not the request body.

ScmMethodProviderCollection

  • BuildGroupedCreateRequestArguments expands each grouped parameter back out of the bag when calling CreateRequest, carrying over the enum-to-serialized-form conversion.
  • ResolveRequestOptionsNameCollision renames the trailing request options parameter when the options bag is itself named options, which would otherwise emit a duplicate parameter name.

Tests

Three new tests cover the grouped shape, the body-outside-bag case, and the body-inside-bag fallback.

Two existing baselines changed: the convenience method now forwards the bag straight through instead of unpacking it. The client-name-mapping and enum-serialization logic those tests covered moved to the protocol-to-CreateRequest boundary, so I added assertions on the protocol body in the same tests rather than dropping that coverage.

Microsoft.TypeSpec.Generator.ClientModel 1543/1543 and Microsoft.TypeSpec.Generator 1810/1810 pass.

When `@@override` groups an operation's parameters into an options bag, the
protocol method now adopts the same grouped shape instead of listing every
parameter individually.

The protocol method keeps taking raw request content when the body is declared
outside the bag. If the body itself was folded into the bag, the protocol method
stays flattened so a raw payload can still be sent.

Fixes microsoft#11214

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69b166be-7096-4882-9251-6e998d9288ae
@pkg-pr-new

pkg-pr-new Bot commented Aug 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@11523

commit: 13bc727

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the C# http-client generator so that when @@override groups operation parameters into an options bag, the protocol method can also adopt the grouped signature (while still preserving a raw request-body escape hatch when needed), addressing #11214.

Changes:

  • Apply @@override options-bag grouping to protocol methods when safe (body not folded into the bag), keeping CreateRequest parameter flattening intact.
  • Expand grouped parameters back into flattened wire parameters when calling CreateRequest, including enum-to-serialized conversions.
  • Add/adjust tests and baselines to validate protocol/convenience behavior across grouped/no-body, body-outside-bag, and body-inside-bag scenarios.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/MethodParameterSegments_RenamedGroupedQueryParam_MapsByClientName.cs Updates baseline to forward the options bag through the convenience method.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/MethodParameterSegments_EnumGroupedQueryParam_SerializesToProtocol.cs Updates baseline to forward the options bag through the convenience method.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs Adds new test coverage for protocol-method options-bag grouping and body placement cases.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs Implements protocol-to-CreateRequest argument expansion from grouped options bags and resolves request-options naming collisions.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs Switches protocol method parameter sourcing to grouped parameters when applicable and improves body handling for grouped shapes.

TCGC does not validate that a required wire parameter maps to a required
property on the options bag, so the generated constructor may not force callers
to supply it. Grouping the protocol method in that case would silently drop the
compile-time guarantee the flattened signature provides, so grouping is skipped.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69b166be-7096-4882-9251-6e998d9288ae
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Aug 3, 2026

@jorgerangel-msft jorgerangel-msft left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m-nash and others added 2 commits August 3, 2026 15:54
An options bag can take the `options` name used by the request options
parameter, which causes that parameter to be renamed. The CreateRequest
call still bound its trailing argument by the original name, so it passed
the bag instead and the generated client did not compile.

Match ungrouped CreateRequest arguments on name and type, falling back to
a unique type match when the bag has taken the name.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69b166be-7096-4882-9251-6e998d9288ae
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 12a20512-4c49-4d6b-83d9-4e6f6261c5bf
Preserve generator parameter metadata when protocol method customizations rename grouped options parameters.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 12a20512-4c49-4d6b-83d9-4e6f6261c5bf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[http-client-csharp] Allow @@override options bag to apply to protocol methods (currently only convenience)

4 participants