From a003c8b17761c4c26e197f24ba83acc9342117de Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Tue, 4 Aug 2026 17:18:24 +0800 Subject: [PATCH 1/7] docs(http-client-java): document emitter diagnostics Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55157ab4-99c9-4154-98f0-b0cc196be50d --- ...ava-diagnostic-docs-2026-08-04-16-55-00.md | 7 +++ .../diagnostics/auth-scheme-not-supported.md | 57 +++++++++++++++++++ .../src/diagnostics/client-required-false.md | 37 ++++++++++++ .../constant-header-in-response-removed.md | 29 ++++++++++ .../convenience-api-not-generated.md | 51 +++++++++++++++++ .../emitter/src/diagnostics/empty-name.md | 29 ++++++++++ .../header-parameter-format-not-supported.md | 33 +++++++++++ .../src/diagnostics/invalid-api-version.md | 40 +++++++++++++ .../src/diagnostics/invalid-java-namespace.md | 33 +++++++++++ .../invalid-java-sdk-dependency.md | 27 +++++++++ .../multiple-server-not-supported.md | 43 ++++++++++++++ .../emitter/src/diagnostics/no-service.md | 34 +++++++++++ .../diagnostics/protocol-api-not-generated.md | 36 ++++++++++++ .../response-headers-as-model-with-body.md | 36 ++++++++++++ ...-json-merge-patch-payload-not-supported.md | 35 ++++++++++++ .../type-not-supported-on-text-plain.md | 36 ++++++++++++ .../emitter/src/diagnostics/unknown-encode.md | 31 ++++++++++ .../src/diagnostics/unrecognized-type.md | 29 ++++++++++ packages/http-client-java/emitter/src/lib.ts | 32 ++++++++++- .../http-client-java/emitter/src/options.ts | 2 + .../http-client-java/emitter/test/lib.test.ts | 27 +++++++++ 21 files changed, 683 insertions(+), 1 deletion(-) create mode 100644 .chronus/changes/java-diagnostic-docs-2026-08-04-16-55-00.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/auth-scheme-not-supported.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/client-required-false.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/constant-header-in-response-removed.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/convenience-api-not-generated.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/empty-name.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/header-parameter-format-not-supported.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/invalid-api-version.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/invalid-java-sdk-dependency.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/no-service.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/response-headers-as-model-with-body.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/spread-json-merge-patch-payload-not-supported.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/type-not-supported-on-text-plain.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/unknown-encode.md create mode 100644 packages/http-client-java/emitter/src/diagnostics/unrecognized-type.md create mode 100644 packages/http-client-java/emitter/test/lib.test.ts diff --git a/.chronus/changes/java-diagnostic-docs-2026-08-04-16-55-00.md b/.chronus/changes/java-diagnostic-docs-2026-08-04-16-55-00.md new file mode 100644 index 00000000000..620f6f34ee7 --- /dev/null +++ b/.chronus/changes/java-diagnostic-docs-2026-08-04-16-55-00.md @@ -0,0 +1,7 @@ +--- +changeKind: internal +packages: + - "@typespec/http-client-java" +--- + +Add reference documentation for Java emitter diagnostics. diff --git a/packages/http-client-java/emitter/src/diagnostics/auth-scheme-not-supported.md b/packages/http-client-java/emitter/src/diagnostics/auth-scheme-not-supported.md new file mode 100644 index 00000000000..e27d74059ec --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/auth-scheme-not-supported.md @@ -0,0 +1,57 @@ +This diagnostic is issued when an authentication scheme cannot be represented by the selected Java client flavor. + +## Impact + +The generated client may omit the scheme or fall back to a less specific credential type. + +## ❌ Incorrect Usage + +### API key outside a header + +```typespec +@service +@useAuth(ApiKeyAuth) +namespace Contoso; +``` + +### Basic authentication for an Azure client + +```typespec +@service +@useAuth(BasicAuth) +namespace Contoso; +``` + +```yaml +options: + "@typespec/http-client-java": + flavor: azure +``` + +## Diagnostic Message + +The message identifies the unsupported scheme, location, or flavor. For example: + +```text +ApiKey auth is currently only supported for ApiKeyLocation.header. +``` + +## ✅ How to Fix + +Use OAuth2 authentication. + +```typespec +@service +@useAuth(OAuth2Auth<[OAuthFlow]>) +namespace Contoso; + +model OAuthFlow { + type: OAuth2FlowType.clientCredentials; + tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token"; + scopes: ["https://contoso.com/.default"]; +} +``` + +## Suppression + +Do not suppress this warning unless custom code will provide the intended authentication behavior. diff --git a/packages/http-client-java/emitter/src/diagnostics/client-required-false.md b/packages/http-client-java/emitter/src/diagnostics/client-required-false.md new file mode 100644 index 00000000000..55e051579f5 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/client-required-false.md @@ -0,0 +1,37 @@ +This diagnostic is issued when the Java `clientRequired` client option is explicitly set to `false`. + +## Impact + +Java client generation fails because the option only supports promoting a parameter to required; it cannot make a required parameter optional. + +## ❌ Incorrect Usage + +```typespec +model ReadOptions { + @query filter: string; +} + +op read(...ReadOptions): void; + +@@clientOption(ReadOptions.filter, "clientRequired", false, "java"); +``` + +## Diagnostic Message + +```text +Client option 'clientRequired' can only be set to 'true'. +``` + +## ✅ How to Fix + +Remove the client option, or set it to `true` for an optional TypeSpec parameter that must be required in the Java client. + +```typespec +model ReadOptions { + @query filter?: string; +} + +op read(...ReadOptions): void; + +@@clientOption(ReadOptions.filter, "clientRequired", true, "java"); +``` diff --git a/packages/http-client-java/emitter/src/diagnostics/constant-header-in-response-removed.md b/packages/http-client-java/emitter/src/diagnostics/constant-header-in-response-removed.md new file mode 100644 index 00000000000..24cb05ea3b3 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/constant-header-in-response-removed.md @@ -0,0 +1,29 @@ +This diagnostic is issued when a response content-type header has a constant value and the Java emitter removes it from the generated response-header model. + +## Impact + +The constant header is not generated as a property in the response-header model because its value cannot vary. + +## Example Usage + +```typespec +op read(): { + @statusCode statusCode: 200; + @header contentType: "application/json"; + @body body: Widget; +}; +``` + +## Diagnostic Message + +```text +Constant header 'content-type' is removed from response headers. +``` + +## How to Address + +No change is required. The TypeSpec definition is valid, and the warning only explains why the generated response-header model does not contain a property for this header. + +## Suppression + +It is safe to ignore or suppress this warning when the constant header does not need to be exposed as a property. diff --git a/packages/http-client-java/emitter/src/diagnostics/convenience-api-not-generated.md b/packages/http-client-java/emitter/src/diagnostics/convenience-api-not-generated.md new file mode 100644 index 00000000000..801b3fac441 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/convenience-api-not-generated.md @@ -0,0 +1,51 @@ +This diagnostic is issued when the Java emitter cannot form a safe convenience-method signature. + +## Impact + +The protocol API remains available, but the convenience API is omitted for the operation. + +## Multiple Content Types + +```typespec +@post +op upload(@body data: bytes, @header contentType: "application/octet-stream" | "image/png"): void; +``` + +```yaml +options: + "@typespec/http-client-java": + flavor: azure +``` + +This TypeSpec definition is valid. Customize the generated Java library to add a convenience API with the appropriate method signature and behavior for the operation. The generated protocol API can be used as the underlying implementation. + +## JSON Merge Patch Without Stream-Style Serialization + +```typespec +@patch +op update(@header contentType: "application/merge-patch+json", @body body: WidgetPatch): void; +``` + +```yaml +options: + "@typespec/http-client-java": + flavor: azure + stream-style-serialization: false +``` + +Enable stream-style serialization: + +```yaml +options: + "@typespec/http-client-java": + flavor: azure + stream-style-serialization: true +``` + +## Diagnostic Message + +The message identifies either multiple content types or JSON merge patch as the reason the convenience API was not generated. + +## Suppression + +For multiple content types, suppress the warning after adding the required convenience API customization, or when a protocol-only API surface is intentional. Do not suppress the JSON merge patch warning; enable stream-style serialization instead. diff --git a/packages/http-client-java/emitter/src/diagnostics/empty-name.md b/packages/http-client-java/emitter/src/diagnostics/empty-name.md new file mode 100644 index 00000000000..61a1772deaa --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/empty-name.md @@ -0,0 +1,29 @@ +This diagnostic is issued when TCGC supplies a model without a usable generated name. + +## Impact + +Java client generation stops because every emitted Java model requires a class name. + +## ❌ Incorrect Usage + +The diagnostic is generally caused by an anonymous or synthesized model shape for which the SDK model did not produce a name. There is no single TypeSpec construct that always triggers it. + +## Diagnostic Message + +```text +Name from TCGC is empty. +``` + +## ✅ How to Fix + +Give anonymous request or response shapes an explicit model name and reference that model from the operation. + +```typespec +model WidgetResponse { + value: string; +} + +op getWidget(): WidgetResponse; +``` + +If all involved models are already named, update the emitter dependencies and report a minimal reproduction. diff --git a/packages/http-client-java/emitter/src/diagnostics/header-parameter-format-not-supported.md b/packages/http-client-java/emitter/src/diagnostics/header-parameter-format-not-supported.md new file mode 100644 index 00000000000..b64fb4a3460 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/header-parameter-format-not-supported.md @@ -0,0 +1,33 @@ +This diagnostic is issued when an array-valued header uses any collection format other than CSV. The Java emitter supports only comma-delimited arrays for header parameters. + +## Impact + +The requested header serialization format is ignored, which can produce a request that does not match the service contract. + +## ❌ Incorrect Usage + +```typespec +op read( + @header + @encode(ArrayEncoding.pipeDelimited) + values: string[], +): void; +``` + +## Diagnostic Message + +```text +Header parameter format '' is not supported. +``` + +## ✅ How to Fix + +Use the default comma-delimited header representation. + +```typespec +op read(@header values: string[]): void; +``` + +## Suppression + +This warning should not be suppressed. Change the service contract or header encoding to CSV. diff --git a/packages/http-client-java/emitter/src/diagnostics/invalid-api-version.md b/packages/http-client-java/emitter/src/diagnostics/invalid-api-version.md new file mode 100644 index 00000000000..5231483d650 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/invalid-api-version.md @@ -0,0 +1,40 @@ +This diagnostic is issued when the `api-version` emitter option is neither a declared service version nor `latest` or `all`. + +## Impact + +The requested API-version projection cannot be selected, so Java client generation fails. + +## ❌ Incorrect Usage + +```typespec +@service +@versioned(Versions) +namespace Contoso; + +enum Versions { + v1, + v2, +} +``` + +```yaml +options: + "@typespec/http-client-java": + api-version: v3 +``` + +## Diagnostic Message + +```text +Invalid api-version option: 'v3'. The value should be an api-version, 'latest', or 'all'. +``` + +## ✅ How to Fix + +Use a version declared by the service, or use `latest` or `all`. + +```yaml +options: + "@typespec/http-client-java": + api-version: v2 +``` diff --git a/packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md b/packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md new file mode 100644 index 00000000000..29ef222c656 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md @@ -0,0 +1,33 @@ +This diagnostic is issued when a generated Java package segment is a reserved Java keyword. + +## Impact + +The emitter changes the package segment to a legal Java identifier, so the generated package differs from the requested namespace. + +## ❌ Incorrect Usage + +```typespec +@service +namespace Contoso.Public; +``` + +The derived Java namespace contains the reserved keyword `public`. + +## Diagnostic Message + +```text +Namespace 'contoso.public' contains reserved Java keywords, replaced it with 'contoso.public_'. +``` + +## ✅ How to Fix + +Rename the TypeSpec namespace or configure a Java namespace that does not contain Java keywords. + +```typespec +@service +namespace Contoso.PublicApi; +``` + +## Suppression + +Suppress the warning only when the escaped package name is intentionally accepted. diff --git a/packages/http-client-java/emitter/src/diagnostics/invalid-java-sdk-dependency.md b/packages/http-client-java/emitter/src/diagnostics/invalid-java-sdk-dependency.md new file mode 100644 index 00000000000..0361b10900c --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/invalid-java-sdk-dependency.md @@ -0,0 +1,27 @@ +This diagnostic is issued when the Java emitter cannot find a supported JDK, Java runtime, or Apache Maven installation. + +## Impact + +Java client generation cannot run because the generator process depends on these tools. + +## ❌ Incorrect Usage + +The emitter is run in an environment where `javac`, `java`, or `mvn` is missing from `PATH`, or where Java is older than the required version. + +## Diagnostic Message + +The message identifies the missing tool or unsupported Java version, for example: + +```text +Java Development Kit (JDK) is not found in PATH. Please install JDK 17 or above. +``` + +## ✅ How to Fix + +Install JDK 17 or later and Apache Maven, add their executable directories to `PATH`, and verify: + +```shell +javac -version +java -version +mvn -version +``` diff --git a/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md b/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md new file mode 100644 index 00000000000..25e36b6d535 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md @@ -0,0 +1,43 @@ +This diagnostic is issued when a generated client has more than two alternative server endpoints. + +## Impact + +Java client generation stops because the emitter cannot select a supported client initialization shape for the server union. + +## ❌ Incorrect Usage + +```typespec +@service +@server( + "https://{region}.example.com", + "Regional", + { + region: string, + } +) +@server("https://example.com", "Global") +@server("http://localhost:3000", "Local") +namespace Contoso; +``` + +## Diagnostic Message + +```text +Multiple server on client is not supported. +``` + +## ✅ How to Fix + +Expose one server endpoint, or reduce the alternatives to a supported endpoint configuration. Prefer a single templated server when the endpoints differ only by a parameter. + +```typespec +@service +@server( + "https://{region}.example.com", + "Service endpoint", + { + region: string, + } +) +namespace Contoso; +``` diff --git a/packages/http-client-java/emitter/src/diagnostics/no-service.md b/packages/http-client-java/emitter/src/diagnostics/no-service.md new file mode 100644 index 00000000000..b2aab779a3a --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/no-service.md @@ -0,0 +1,34 @@ +This diagnostic is issued when the TypeSpec program does not contain a namespace marked with `@service`. + +## Impact + +No Java client is generated because the emitter cannot identify the service root. + +## ❌ Incorrect Usage + +```typespec +namespace Contoso; + +op ping(): void; +``` + +## Diagnostic Message + +```text +No service found in this TypeSpec. Client will not be generated. +``` + +## ✅ How to Fix + +Mark the service namespace with `@service`. + +```typespec +@service +namespace Contoso; + +op ping(): void; +``` + +## Suppression + +Suppress this warning only when the file intentionally defines reusable types and is not intended to generate a client. diff --git a/packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md b/packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md new file mode 100644 index 00000000000..04bb96d8f4a --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md @@ -0,0 +1,36 @@ +This diagnostic is issued when an Azure-flavored multipart operation would produce a protocol API that is not usable with the generated request shape. + +## Impact + +The convenience API is generated, but the protocol API is omitted for the operation. + +## ❌ Incorrect Usage + +```typespec +model UploadForm { + file: HttpPart; +} + +@post +op upload(@header contentType: "multipart/form-data", @multipartBody body: UploadForm): void; +``` + +```yaml +options: + "@typespec/http-client-java": + flavor: azure +``` + +## Diagnostic Message + +```text +Operation 'upload' is of content-type 'multipart/form-data'. Protocol API is not usable and hence not generated. +``` + +## ✅ How to Fix + +Use the generated convenience API. If a protocol API is required, redesign the operation to use a supported non-multipart request body. + +## Suppression + +The warning can be suppressed when omitting the protocol API is expected and the convenience API is sufficient. diff --git a/packages/http-client-java/emitter/src/diagnostics/response-headers-as-model-with-body.md b/packages/http-client-java/emitter/src/diagnostics/response-headers-as-model-with-body.md new file mode 100644 index 00000000000..30fe27f9e1c --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/response-headers-as-model-with-body.md @@ -0,0 +1,36 @@ +This diagnostic is issued when `responseHeadersAsModel` is enabled for an operation that also returns a response body. + +## Impact + +Java client generation fails because the option is only defined for returning significant response headers from bodyless operations. + +## ❌ Incorrect Usage + +```typespec +op getWidget(): { + @statusCode statusCode: 200; + @header eTag: string; + @body body: Widget; +}; + +@@clientOption(getWidget, "responseHeadersAsModel", true, "java"); +``` + +## Diagnostic Message + +```text +Client option 'responseHeadersAsModel' cannot be used on operation 'getWidget', because it has a response body. +``` + +## ✅ How to Fix + +Remove the option for operations with response bodies. Use it only when the response contains significant headers and no body. + +```typespec +op getWidgetMetadata(): { + @statusCode statusCode: 200; + @header eTag: string; +}; + +@@clientOption(getWidgetMetadata, "responseHeadersAsModel", true, "java"); +``` diff --git a/packages/http-client-java/emitter/src/diagnostics/spread-json-merge-patch-payload-not-supported.md b/packages/http-client-java/emitter/src/diagnostics/spread-json-merge-patch-payload-not-supported.md new file mode 100644 index 00000000000..ce0945776e4 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/spread-json-merge-patch-payload-not-supported.md @@ -0,0 +1,35 @@ +This diagnostic is issued when an operation spreads a JSON merge-patch body into method parameters. + +## Impact + +The body is kept as a model parameter because separate Java parameters cannot distinguish an omitted property from a property explicitly set to `null`. + +## ❌ Incorrect Usage + +```typespec +model WidgetPatch { + name?: string | null; +} + +@patch +op update(@header contentType: "application/merge-patch+json", ...WidgetPatch): void; +``` + +## Diagnostic Message + +```text +Spread JSON merge-patch payload is not supported. +``` + +## ✅ How to Fix + +Pass the patch model as the request body instead of spreading its properties. + +```typespec +@patch +op update(@header contentType: "application/merge-patch+json", @body body: WidgetPatch): void; +``` + +## Suppression + +This warning should not be suppressed because the generated method shape intentionally changes to preserve merge-patch semantics. diff --git a/packages/http-client-java/emitter/src/diagnostics/type-not-supported-on-text-plain.md b/packages/http-client-java/emitter/src/diagnostics/type-not-supported-on-text-plain.md new file mode 100644 index 00000000000..e69eec5e1e9 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/type-not-supported-on-text-plain.md @@ -0,0 +1,36 @@ +This diagnostic is issued when an operation uses an enum request or response body with `text/plain`. + +## Impact + +The emitter substitutes `String` for the unsupported Java type on the request or response body. + +## ❌ Incorrect Usage + +```typespec +enum Color { + red, + blue, +} + +@post +op setColor(@header contentType: "text/plain", @body color: Color): void; +``` + +## Diagnostic Message + +```text +Complex SDK type is not supported for "text/plain" content-type. Emitter would use string type on 'setColor' request body. +``` + +## ✅ How to Fix + +Use `string` for a text payload, or use a structured content type such as `application/json` when the SDK type should remain strongly typed. + +```typespec +@post +op setColor(@header contentType: "text/plain", @body color: string): void; +``` + +## Suppression + +Suppress the warning only when the generated `String` API is the intended contract. diff --git a/packages/http-client-java/emitter/src/diagnostics/unknown-encode.md b/packages/http-client-java/emitter/src/diagnostics/unknown-encode.md new file mode 100644 index 00000000000..193fd58c8e3 --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/unknown-encode.md @@ -0,0 +1,31 @@ +This diagnostic is issued when a bytes, duration, or date-time type uses an encoding that the Java emitter does not recognize. + +## Impact + +The emitter falls back to the wire type or a string representation, so the generated Java type may not preserve the intended encoding. + +## ❌ Incorrect Usage + +```typespec +@encode("custom-datetime") +scalar CustomDateTime extends utcDateTime; +``` + +## Diagnostic Message + +```text +Encode 'custom-datetime' is not supported. +``` + +## ✅ How to Fix + +Use a standard encoding supported by the corresponding TypeSpec scalar. + +```typespec +@encode(DateTimeKnownEncoding.rfc3339) +scalar CustomDateTime extends utcDateTime; +``` + +## Suppression + +Do not suppress this warning unless the fallback Java representation and wire format have been verified. diff --git a/packages/http-client-java/emitter/src/diagnostics/unrecognized-type.md b/packages/http-client-java/emitter/src/diagnostics/unrecognized-type.md new file mode 100644 index 00000000000..8862d1078da --- /dev/null +++ b/packages/http-client-java/emitter/src/diagnostics/unrecognized-type.md @@ -0,0 +1,29 @@ +This diagnostic is issued when the Java emitter receives an SDK type kind that it cannot map to a Java schema. Specialized messages identify unsupported union or multipart property kinds. + +## Impact + +Java client generation stops because the emitter cannot determine a safe Java representation. + +## ❌ Incorrect Usage + +This usually indicates an unsupported TypeSpec shape or a version mismatch between the Java emitter and `@azure-tools/typespec-client-generator-core`. It can also occur when a union or multipart model contains a type kind that the emitter does not support. + +## Diagnostic Message + +Messages include: + +```text +Unrecognized type, kind ''. Updating the version of the emitter may resolve this issue. +``` + +```text +Unrecognized type for Union, kind ''. +``` + +```text +Unrecognized type for multipart form data, kind ''. +``` + +## ✅ How to Fix + +Update the Java emitter and TypeSpec dependencies together. If the error identifies a union or multipart property, replace the unsupported member with a supported scalar, model, array, or file type. If the kind should be supported, report an emitter issue with a minimal TypeSpec reproduction. diff --git a/packages/http-client-java/emitter/src/lib.ts b/packages/http-client-java/emitter/src/lib.ts index 9074269eda4..73a4a582612 100644 --- a/packages/http-client-java/emitter/src/lib.ts +++ b/packages/http-client-java/emitter/src/lib.ts @@ -1,5 +1,18 @@ import { createTypeSpecLibrary, paramMessage } from "@typespec/compiler"; -import { EmitterOptionsSchema, LIB_NAME } from "./options.js"; +import { DIAGNOSTIC_DOCS_BASE_URL, EmitterOptionsSchema, LIB_NAME } from "./options.js"; + +/** + * Build the source documentation reference and published URL for a diagnostic. + */ +function doc(code: string) { + return { + docs: { + kind: "file-ref" as const, + path: `emitter/src/diagnostics/${code}.md`, + }, + url: `${DIAGNOSTIC_DOCS_BASE_URL}/${code}`, + }; +} export const $lib = createTypeSpecLibrary({ name: LIB_NAME, @@ -18,6 +31,7 @@ export const $lib = createTypeSpecLibrary({ }, }, "invalid-java-sdk-dependency": { + ...doc("invalid-java-sdk-dependency"), severity: "error", messages: { default: @@ -30,18 +44,21 @@ export const $lib = createTypeSpecLibrary({ }, }, "multiple-server-not-supported": { + ...doc("multiple-server-not-supported"), severity: "error", messages: { default: "Multiple server on client is not supported.", }, }, "invalid-api-version": { + ...doc("invalid-api-version"), severity: "error", messages: { default: paramMessage`Invalid api-version option: '${"apiVersion"}'. The value should be an api-version, 'latest', or 'all'.`, }, }, "unrecognized-type": { + ...doc("unrecognized-type"), severity: "error", messages: { default: paramMessage`Unrecognized type, kind '${"typeKind"}'. Updating the version of the emitter may resolve this issue.`, @@ -50,6 +67,7 @@ export const $lib = createTypeSpecLibrary({ }, }, "empty-name": { + ...doc("empty-name"), severity: "error", messages: { default: "Name from TCGC is empty.", @@ -64,12 +82,14 @@ export const $lib = createTypeSpecLibrary({ }, }, "no-service": { + ...doc("no-service"), severity: "warning", messages: { default: "No service found in this TypeSpec. Client will not be generated.", }, }, "auth-scheme-not-supported": { + ...doc("auth-scheme-not-supported"), severity: "warning", messages: { oauth2Unbranded: @@ -79,12 +99,14 @@ export const $lib = createTypeSpecLibrary({ }, }, "protocol-api-not-generated": { + ...doc("protocol-api-not-generated"), severity: "warning", messages: { multipartFormData: paramMessage`Operation '${"operationName"}' is of content-type 'multipart/form-data'. Protocol API is not usable and hence not generated.`, }, }, "convenience-api-not-generated": { + ...doc("convenience-api-not-generated"), severity: "warning", messages: { multipleContentType: paramMessage`Operation '${"operationName"}' can be invoked with multiple content-type. It is difficult to form a correct method signature for convenience API, and hence the convenience API is not generated.`, @@ -92,30 +114,35 @@ export const $lib = createTypeSpecLibrary({ }, }, "header-parameter-format-not-supported": { + ...doc("header-parameter-format-not-supported"), severity: "warning", messages: { default: paramMessage`Header parameter format '${"format"}' is not supported.`, }, }, "unknown-encode": { + ...doc("unknown-encode"), severity: "warning", messages: { default: paramMessage`Encode '${"encode"}' is not supported.`, }, }, "invalid-java-namespace": { + ...doc("invalid-java-namespace"), severity: "warning", messages: { default: paramMessage`Namespace '${"namespace"}' contains reserved Java keywords, replaced it with '${"processedNamespace"}'.`, }, }, "constant-header-in-response-removed": { + ...doc("constant-header-in-response-removed"), severity: "warning", messages: { default: paramMessage`Constant header '${"headerName"}' is removed from response headers.`, }, }, "spread-json-merge-patch-payload-not-supported": { + ...doc("spread-json-merge-patch-payload-not-supported"), severity: "warning", messages: { default: @@ -123,18 +150,21 @@ export const $lib = createTypeSpecLibrary({ }, }, "type-not-supported-on-text-plain": { + ...doc("type-not-supported-on-text-plain"), severity: "warning", messages: { default: paramMessage`Complex SDK type is not supported for "text/plain" content-type. Emitter would use string type on '${"operationName"}' ${"payloadKind"}.`, }, }, "client-required-false": { + ...doc("client-required-false"), severity: "error", messages: { default: "Client option 'clientRequired' can only be set to 'true'.", }, }, "response-headers-as-model-with-body": { + ...doc("response-headers-as-model-with-body"), severity: "error", messages: { default: paramMessage`Client option 'responseHeadersAsModel' cannot be used on operation '${"operationName"}', because it has a response body. It is only applicable to operations that have response headers but no response body.`, diff --git a/packages/http-client-java/emitter/src/options.ts b/packages/http-client-java/emitter/src/options.ts index a825f378502..f9bc8dedc3b 100644 --- a/packages/http-client-java/emitter/src/options.ts +++ b/packages/http-client-java/emitter/src/options.ts @@ -5,6 +5,8 @@ import type { JSONSchemaType } from "@typespec/compiler"; // If add/remove "export" here, please also check typespec-java in autorest.java repository. export const LIB_NAME = "@typespec/http-client-java"; +export const DIAGNOSTIC_DOCS_BASE_URL = + "https://typespec.io/docs/emitters/clients/http-client-java/reference/diagnostics"; export interface DevOptions { "generate-code-model"?: boolean; diff --git a/packages/http-client-java/emitter/test/lib.test.ts b/packages/http-client-java/emitter/test/lib.test.ts new file mode 100644 index 00000000000..8cd158f27a8 --- /dev/null +++ b/packages/http-client-java/emitter/test/lib.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from "vitest"; +import { $lib } from "../src/lib.js"; +import { DIAGNOSTIC_DOCS_BASE_URL } from "../src/options.js"; + +describe("diagnostic documentation", () => { + it("links non-generic diagnostics to their documentation", () => { + const genericDiagnostics = new Set(["unknown-error", "generator-error", "generator-warning"]); + + for (const [code, diagnostic] of Object.entries($lib.diagnostics)) { + const definition = diagnostic as { + docs?: { kind: string; path: string }; + url?: string; + }; + + if (genericDiagnostics.has(code)) { + expect(definition.docs).toBeUndefined(); + expect(definition.url).toBeUndefined(); + } else { + expect(definition.docs).toEqual({ + kind: "file-ref", + path: `emitter/src/diagnostics/${code}.md`, + }); + expect(definition.url).toBe(`${DIAGNOSTIC_DOCS_BASE_URL}/${code}`); + } + } + }); +}); From 0012844f1e0ddcdfc63417518d3caa0f35671b10 Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Tue, 4 Aug 2026 17:21:41 +0800 Subject: [PATCH 2/7] docs(http-client-java): correct namespace diagnostic example Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55157ab4-99c9-4154-98f0-b0cc196be50d --- .../emitter/src/diagnostics/invalid-java-namespace.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md b/packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md index 29ef222c656..c1a23af4610 100644 --- a/packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md +++ b/packages/http-client-java/emitter/src/diagnostics/invalid-java-namespace.md @@ -2,7 +2,7 @@ This diagnostic is issued when a generated Java package segment is a reserved Ja ## Impact -The emitter changes the package segment to a legal Java identifier, so the generated package differs from the requested namespace. +The emitter appends `namespace` to the reserved package segment, so the generated package differs from the requested namespace. ## ❌ Incorrect Usage @@ -16,7 +16,7 @@ The derived Java namespace contains the reserved keyword `public`. ## Diagnostic Message ```text -Namespace 'contoso.public' contains reserved Java keywords, replaced it with 'contoso.public_'. +Namespace 'contoso.public' contains reserved Java keywords, replaced it with 'contoso.publicnamespace'. ``` ## ✅ How to Fix @@ -30,4 +30,4 @@ namespace Contoso.PublicApi; ## Suppression -Suppress the warning only when the escaped package name is intentionally accepted. +Suppress the warning only when the adjusted package name is intentionally accepted. From b6e948eae6044bd48b131abe2ed07f840787974f Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Tue, 4 Aug 2026 17:25:36 +0800 Subject: [PATCH 3/7] docs(http-client-java): fix multiple server diagnostic example Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55157ab4-99c9-4154-98f0-b0cc196be50d --- .../src/diagnostics/multiple-server-not-supported.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md b/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md index 25e36b6d535..a004fefce3c 100644 --- a/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md +++ b/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md @@ -17,7 +17,9 @@ Java client generation stops because the emitter cannot select a supported clien ) @server("https://example.com", "Global") @server("http://localhost:3000", "Local") -namespace Contoso; +namespace Contoso { + op read(): string; +} ``` ## Diagnostic Message @@ -39,5 +41,7 @@ Expose one server endpoint, or reduce the alternatives to a supported endpoint c region: string, } ) -namespace Contoso; +namespace Contoso { + op read(): string; +} ``` From 44016c0f75319dae5b68a1e4ba2362f9403bcb12 Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Tue, 4 Aug 2026 17:29:39 +0800 Subject: [PATCH 4/7] docs(http-client-java): document model-only generation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55157ab4-99c9-4154-98f0-b0cc196be50d --- .../emitter/src/diagnostics/no-service.md | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/http-client-java/emitter/src/diagnostics/no-service.md b/packages/http-client-java/emitter/src/diagnostics/no-service.md index b2aab779a3a..84b74efde97 100644 --- a/packages/http-client-java/emitter/src/diagnostics/no-service.md +++ b/packages/http-client-java/emitter/src/diagnostics/no-service.md @@ -2,16 +2,24 @@ This diagnostic is issued when the TypeSpec program does not contain a namespace ## Impact -No Java client is generated because the emitter cannot identify the service root. +No Java client is generated because the emitter cannot identify the service root. Models with explicit usage and access metadata can still be generated. -## ❌ Incorrect Usage +## Valid Model-Only Usage ```typespec -namespace Contoso; +import "@azure-tools/typespec-client-generator-core"; -op ping(): void; +using Azure.ClientGenerator.Core; + +@access(Access.public) +@usage(Usage.input | Usage.output) +model Widget { + name: string; +} ``` +This generates the public `Widget` Java model without generating a service client. The warning is expected for this use case. + ## Diagnostic Message ```text @@ -20,15 +28,15 @@ No service found in this TypeSpec. Client will not be generated. ## ✅ How to Fix -Mark the service namespace with `@service`. +If a Java client is intended, mark the service namespace with `@service` and define its operations. ```typespec @service -namespace Contoso; - -op ping(): void; +namespace Contoso { + op ping(): void; +} ``` ## Suppression -Suppress this warning only when the file intentionally defines reusable types and is not intended to generate a client. +It is safe to suppress this warning when the TypeSpec intentionally generates only model classes. From 3540c32373f0c259cd764c8962f3af0117ccafb2 Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Tue, 4 Aug 2026 17:31:15 +0800 Subject: [PATCH 5/7] docs(http-client-java): clarify protocol API notification Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55157ab4-99c9-4154-98f0-b0cc196be50d --- .../src/diagnostics/protocol-api-not-generated.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md b/packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md index 04bb96d8f4a..944110a2a8b 100644 --- a/packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md +++ b/packages/http-client-java/emitter/src/diagnostics/protocol-api-not-generated.md @@ -4,7 +4,7 @@ This diagnostic is issued when an Azure-flavored multipart operation would produ The convenience API is generated, but the protocol API is omitted for the operation. -## ❌ Incorrect Usage +## Example Usage ```typespec model UploadForm { @@ -15,22 +15,16 @@ model UploadForm { op upload(@header contentType: "multipart/form-data", @multipartBody body: UploadForm): void; ``` -```yaml -options: - "@typespec/http-client-java": - flavor: azure -``` - ## Diagnostic Message ```text Operation 'upload' is of content-type 'multipart/form-data'. Protocol API is not usable and hence not generated. ``` -## ✅ How to Fix +## How to Address -Use the generated convenience API. If a protocol API is required, redesign the operation to use a supported non-multipart request body. +No change is required. Use the generated convenience API for the multipart operation. ## Suppression -The warning can be suppressed when omitting the protocol API is expected and the convenience API is sufficient. +It is safe to ignore or suppress this notification when the generated convenience API is sufficient. From 157951113b75377bf0f0a53a298c306cb2d4151d Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Tue, 4 Aug 2026 17:34:26 +0800 Subject: [PATCH 6/7] docs(http-client-java): clarify encoding suppression guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55157ab4-99c9-4154-98f0-b0cc196be50d --- .../http-client-java/emitter/src/diagnostics/unknown-encode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/http-client-java/emitter/src/diagnostics/unknown-encode.md b/packages/http-client-java/emitter/src/diagnostics/unknown-encode.md index 193fd58c8e3..350b7e9754a 100644 --- a/packages/http-client-java/emitter/src/diagnostics/unknown-encode.md +++ b/packages/http-client-java/emitter/src/diagnostics/unknown-encode.md @@ -28,4 +28,4 @@ scalar CustomDateTime extends utcDateTime; ## Suppression -Do not suppress this warning unless the fallback Java representation and wire format have been verified. +Suppress this warning only when the fallback Java representation and wire format have been verified, or when the generated Java library will be customized to implement the intended encoding. From 361d6fbfb9f7f21072fe5bd520cd31a92c1ef0aa Mon Sep 17 00:00:00 2001 From: Weidong Xu Date: Wed, 5 Aug 2026 13:12:16 +0800 Subject: [PATCH 7/7] docs(http-client-java): clarify multiple server limitation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55157ab4-99c9-4154-98f0-b0cc196be50d --- .../src/diagnostics/multiple-server-not-supported.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md b/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md index a004fefce3c..eb126211cfe 100644 --- a/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md +++ b/packages/http-client-java/emitter/src/diagnostics/multiple-server-not-supported.md @@ -1,10 +1,10 @@ -This diagnostic is issued when a generated client has more than two alternative server endpoints. +This diagnostic is issued when a service declares multiple alternative ways to specify its endpoint. ## Impact -Java client generation stops because the emitter cannot select a supported client initialization shape for the server union. +The service definition is valid, but the Java emitter currently supports only one server definition when constructing the client endpoint. -## ❌ Incorrect Usage +## Valid Usage ```typespec @service @@ -28,9 +28,9 @@ namespace Contoso { Multiple server on client is not supported. ``` -## ✅ How to Fix +## How to Address -Expose one server endpoint, or reduce the alternatives to a supported endpoint configuration. Prefer a single templated server when the endpoints differ only by a parameter. +If the service supports multiple endpoint forms, no change to the service contract is required. Until the Java emitter supports this pattern, select one server definition for generation and customize the Java library to expose the additional endpoint forms. ```typespec @service