From d1465710eb47196e50d3bdbd82217964054dbc81 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sun, 7 Jun 2026 12:20:41 -0400 Subject: [PATCH] Fix Go and Rust code generators Update the Go generator to avoid discriminator method collisions only when a generated variant field would otherwise conflict. Update the Rust generator to keep RPC methods using internal schemas crate-private and allow intentionally unused generated internal items. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- rust/src/generated/api_types.rs | 1 + rust/src/generated/rpc.rs | 1 + scripts/codegen/go.ts | 23 ++++++++++++++++++++++- scripts/codegen/rust.ts | 20 +++++++++++++++++++- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index ff418754e..ff83db15f 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -1,6 +1,7 @@ //! Auto-generated from api.schema.json — do not edit manually. #![allow(clippy::large_enum_variant)] +#![allow(dead_code)] use std::collections::HashMap; diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs index 75dffd91d..b63dafc07 100644 --- a/rust/src/generated/rpc.rs +++ b/rust/src/generated/rpc.rs @@ -7,6 +7,7 @@ #![allow(missing_docs)] #![allow(clippy::too_many_arguments)] +#![allow(dead_code)] use super::api_types::{rpc_methods, *}; use super::session_events::SessionMode; diff --git a/scripts/codegen/go.ts b/scripts/codegen/go.ts index 82aac2a0b..a3f39048d 100644 --- a/scripts/codegen/go.ts +++ b/scripts/codegen/go.ts @@ -1731,6 +1731,27 @@ function goVariantMatchFunctionLines( return lines; } +function goDiscriminatorMethodName( + typeName: string, + discriminatorProp: string, + discGoName: string, + variants: GoDiscriminatedUnionVariant[], + ctx: GoCodegenCtx +): string { + const collidesWithVariantField = variants.some((variant) => { + const resolved = resolveSchema(variant.schema, ctx.definitions) ?? variant.schema; + const objectSchema = resolveObjectSchema(resolved, ctx.definitions) ?? resolved; + return Object.keys(objectSchema.properties ?? {}).some((propName) => { + if (propName === discriminatorProp) { + return variant.discriminatorValues.length > 1 && discGoName === "Discriminator"; + } + return toGoFieldName(propName) === discGoName; + }); + }); + + return collidesWithVariantField ? `${toGoUnexportedIdentifier(typeName)}${discGoName}` : discGoName; +} + /** * Emit a Go interface for a discriminated union (anyOf with const discriminator). */ @@ -1748,7 +1769,7 @@ function emitGoFlatDiscriminatedUnion( const mapping = discriminator.mapping; const unionVariants = [...discriminator.variants].sort((left, right) => compareGoTypeNames(left.typeName, right.typeName)); const discGoName = toGoFieldName(discriminatorProp); - const discriminatorMethodName = discGoName; + const discriminatorMethodName = goDiscriminatorMethodName(typeName, discriminatorProp, discGoName, unionVariants, ctx); let discEnumName: string | undefined; let discGoType = "bool"; if (discriminator.valueKind === "string") { diff --git a/scripts/codegen/rust.ts b/scripts/codegen/rust.ts index c6ee6a1ba..0d7dd5d77 100644 --- a/scripts/codegen/rust.ts +++ b/scripts/codegen/rust.ts @@ -1545,6 +1545,7 @@ function generateApiTypesCode( out.push("//! Auto-generated from api.schema.json — do not edit manually."); out.push(""); out.push("#![allow(clippy::large_enum_variant)]"); + out.push("#![allow(dead_code)]"); out.push(""); out.push("use std::collections::HashMap;"); out.push(""); @@ -1776,6 +1777,17 @@ function getResultTypeName( return `${toPascalCase(method.rpcMethod)}Result`; } +function methodUsesInternalSchema( + schema: JSONSchema7 | null | undefined, + defCollections: DefinitionCollections, +): boolean { + if (!schema) return false; + + const nonNullable = getNullableInner(schema) ?? schema; + const resolved = resolveSchema(nonNullable, defCollections) ?? nonNullable; + return isSchemaInternal(resolved); +} + function pushNamespaceMethodBody( out: string[], constName: string, @@ -1884,7 +1896,12 @@ function emitNamespaceMethod( }; const paramArg = hasParams ? `, params: ${paramsTypeName}` : ""; - const fnVis = method.visibility === "internal" ? "pub(crate)" : "pub"; + const fnVis = + method.visibility === "internal" || + methodUsesInternalSchema(method.params, defCollections) || + methodUsesInternalSchema(method.result, defCollections) + ? "pub(crate)" + : "pub"; if (hasParams && paramsInfo.optional) { out.push(...buildDocs(false)); @@ -1949,6 +1966,7 @@ function generateRpcCode(apiSchema: ApiSchema): string { out.push(""); out.push("#![allow(missing_docs)]"); out.push("#![allow(clippy::too_many_arguments)]"); + out.push("#![allow(dead_code)]"); out.push(""); out.push("use super::api_types::{rpc_methods, *};"); const externalTypeRefs = new Map>();