Skip to content

fix(http-client-csharp): honor @protocolAPI(false) by generating protocol method as internal#11215

Merged
jorgerangel-msft merged 3 commits into
microsoft:mainfrom
m-nash:fix/issue-11211
Jul 9, 2026
Merged

fix(http-client-csharp): honor @protocolAPI(false) by generating protocol method as internal#11215
jorgerangel-msft merged 3 commits into
microsoft:mainfrom
m-nash:fix/issue-11211

Conversation

@m-nash

@m-nash m-nash commented Jul 8, 2026

Copy link
Copy Markdown
Member

Fixes #11211

Problem

The C# emitter ignored @protocolAPI(false). The emitter emits generateProtocolMethod: false (operation-converter.ts) and InputOperation.GenerateProtocolMethod deserializes it, but the ClientModel generator never consulted the flag, so the protocol method was always generated as public.

Fix

In ScmMethodProviderCollection:

  • BuildProtocolMethod: generate the protocol method as internal (instead of public) when GenerateProtocolMethod is false. The method and its body are kept (not omitted), so the convenience method still delegates to it.
  • GetConvenienceMethodModifiers: the convenience method's public/internal accessibility now follows the service method's accessibility, decoupled from the protocol method - so the convenience method stays public even when the protocol method is internal. This is behavior-preserving for existing scenarios (an internal protocol method previously only occurred with a non-public service method).

Behavior

With @protocolAPI(false):

internal virtual ClientResult GetWidget(string id, RequestOptions options)              // now internal
public virtual ClientResult<Widget> GetWidget(string id, CancellationToken cancellationToken = default)  // still public

Tests

  • New test ProtocolMethodIsInternalWhenGenerateProtocolMethodIsFalse (test-first: failed before the fix, passes after).
  • Full Microsoft.TypeSpec.Generator.ClientModel suite: 1456 passed, 0 failed.

…ocol method as internal

The ClientModel generator deserialized InputOperation.GenerateProtocolMethod but
never used it, so @protocolAPI(false) had no effect. Generate the protocol method
as internal (not public) when the flag is false, keeping the method body and the
convenience method's delegation intact. The convenience method's accessibility now
follows the service method accessibility so it remains public.

Fixes microsoft#11211

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@m-nash m-nash requested a review from Copilot July 8, 2026 21:00
@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 Jul 8, 2026

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 fixes the C# http-client generator’s handling of @protocolAPI(false) by ensuring protocol (RequestContent-based) overloads are still generated but are no longer part of the public API surface when the flag is false, while keeping convenience methods public.

Changes:

  • Generate protocol methods as internal when InputOperation.GenerateProtocolMethod is false.
  • Decouple convenience-method accessibility from the protocol-method accessibility so convenience methods remain public when the service method is public.
  • Add a unit test asserting protocol methods become internal while convenience methods remain public, plus update shared input factory to set GenerateProtocolMethod.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs Extends InputFactory.Operation(...) to allow setting generateProtocolMethod for tests.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs Adds coverage for GenerateProtocolMethod=false ensuring protocol methods are internal and convenience methods remain public.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs Implements the accessibility changes for protocol vs convenience methods based on GenerateProtocolMethod and service accessibility.
.chronus/changes/honor-protocolapi-false-2026-7-8.md Adds a Chronus changelog entry for the change.

Comment thread .chronus/changes/honor-protocolapi-false-2026-7-8.md Outdated
Comment thread .chronus/changes/honor-protocolapi-false-2026-7-8.md Outdated
The .NET emitter (@typespec/http-client-csharp) is not managed by chronus,
so a .chronus changelog entry breaks the preview `chronus version` job.

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

@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.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

@pkg-pr-new

pkg-pr-new Bot commented Jul 8, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 0107dc4

@azure-sdk-automation

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

The Local/Sample-TypeSpec test project uses @protocolAPI(false) on the
internalProtocol and stillConvenient operations. With the fix, their protocol
methods are now generated as internal (and the public-only Argument null checks
are dropped accordingly), so the checked-in baseline is regenerated to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jorgerangel-msft jorgerangel-msft added this pull request to the merge queue Jul 9, 2026
Merged via the queue into microsoft:main with commit 8cfbe86 Jul 9, 2026
29 checks passed
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.

@protocolAPI(false) is ignored by http-client-csharp - public protocol method still generated

3 participants