From db190ab8899fefffb0e5a192f3e0822f33352f6f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 23 Oct 2026 17:08:09 +0000 Subject: [PATCH 1/2] docs(sdks): XML-encoded types: text-first child builders, C# indented output, Ruby/PHP declaration aliases, Java varargs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- fern/products/sdks/deep-dives/xml-encoded-types.mdx | 10 ++++++---- .../sdks/legacy/deep-dives/xml-encoded-types.mdx | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/fern/products/sdks/deep-dives/xml-encoded-types.mdx b/fern/products/sdks/deep-dives/xml-encoded-types.mdx index 75567c7b33..5c18d12cb5 100644 --- a/fern/products/sdks/deep-dives/xml-encoded-types.mdx +++ b/fern/products/sdks/deep-dives/xml-encoded-types.mdx @@ -55,20 +55,22 @@ This definition describes documents like: ``` -Element names, attributes, text bodies, nested and union children, repeated children, wrapped lists, list separators on attributes and text, namespaces, prefixes, and escaping are all honored. +Element names, attributes, text bodies, nested and union children, repeated children, wrapped lists, list separators on attributes and text, namespaces, prefixes, and escaping are all honored. Element text escapes `&`, `<`, and `>`; attribute values also escape `"`. ## Generated methods Every XML-encoded type gets three capabilities, named idiomatically per language: -- **Serialize**: `toXml()` (`to_xml` in Python and Ruby, `ToXml()` in C# and Go) returns the element as an XML document prefixed with the `` declaration. Pass `false` to omit the declaration: `toXml(false)` in TypeScript, Java, and PHP, `ToXml(false)` in C#, `to_xml(xml_declaration=False)` in Python, and `to_xml(xml_declaration: false)` in Ruby. Go's `ToXml()` always includes it. Nested children are always written without a declaration. +- **Serialize**: `toXml()` (`to_xml` in Python and Ruby, `ToXml()` in C# and Go) returns the element as an XML document prefixed with the `` declaration. Pass `false` to omit the declaration: `toXml(false)` in TypeScript, Java, and PHP, `ToXml(false)` in C#, `to_xml(xml_declaration=False)` in Python, and `to_xml(false)` or `to_xml(xml_declaration: false)` in Ruby (`to_s(false)` also works). PHP also exposes `asXML()` as an alias for `toXml()`. In C#, `ToXml(xmlDeclaration, indent)` returns indented XML; the other overloads and `ToString()` return compact XML. Go's `ToXml()` always includes the declaration. Nested children are always written without a declaration. - **Parse**: `fromXml(xml)` (`from_xml` in Python and Ruby, `FromXml()` in C#, `FromXml()` in Go) parses an XML string back into the model. Parsing validates the root element name and scalar values, and rejects malformed input and `DOCTYPE` declarations. Enum values are open in Go, PHP, and Ruby, and in TypeScript with `enableForwardCompatibleEnums: true`: a value the enum doesn't declare (for example, one added to the API after the SDK was generated) is kept and re-emitted by `toXml`. -- **Build**: one fluent method per child element type, named after the XML tag (for example, `garden.plant(...)`). In TypeScript, Python, Ruby, and PHP, each method constructs the child, appends it, and returns the child so its own children can be added. In C# and Go, it appends the child and returns the parent so calls chain (`response.Say(...).Say(...)`). A child method gets an `add` prefix (`addPlant`, `add_plant`, `AddPlant`) when its tag collides with a property or method of the parent, or when the name is a reserved word (`addBreak` in TypeScript, `break_` in Python and Ruby). +- **Build**: one fluent method per child element type, named after the XML tag (for example, `garden.plant(...)`). In TypeScript, Python, Ruby, and PHP, each method constructs the child, appends it, and returns the child so its own children can be added. In C# and Go, it appends the child and returns the parent so calls chain (`response.Say(...).Say(...)`). A child method gets an `add` prefix (`addPlant`, `add_plant`, `AddPlant`) when its tag collides with a property or method of the parent, or when the name is a reserved word (`addBreak` in TypeScript, `break_` in Python and Ruby). In Java, the typed overload under the tag name (`number(Number)` on `Dial.Builder`) is generated alongside `addNumber(Number)` even when a text or attribute setter already uses that name, as long as the parameter types differ. + +Child methods for elements that carry text take that text first. In TypeScript, pass the text as a string or pass a fields object (`response.say("hi")` or `response.say({ message: "hi", voice: "alice" })`). In C#, the value overload lists the element text first, then required attributes, then optional attributes (`response.Say("hi", voice: "alice")`). In Java, a type whose text is required gets a `builder(text)` factory (`Body.builder("hi")`), and each list-valued attribute setter accepts varargs as well as a `List` (`Gather.builder().input(GatherInputItem.DTMF, GatherInputItem.SPEECH)`). ```ts TypeScript const garden = SeedApi.Garden.builder({ climate: "temperate" }); -garden.plant("Fern", { sunlight: "full" }); +garden.plant({ name: "Fern", sunlight: "full" }); const xml = garden.toXml(); const parsed = SeedApi.Garden.fromXml(xml); // immutable model diff --git a/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx b/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx index 0fbed79035..09ba2d081b 100644 --- a/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx +++ b/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx @@ -57,20 +57,22 @@ This definition describes documents like: ``` -Element names, attributes, text bodies, nested and union children, repeated children, wrapped lists, list separators on attributes and text, namespaces, prefixes, and escaping are all honored. +Element names, attributes, text bodies, nested and union children, repeated children, wrapped lists, list separators on attributes and text, namespaces, prefixes, and escaping are all honored. Element text escapes `&`, `<`, and `>`; attribute values also escape `"`. ## Generated methods Every XML-encoded type gets three capabilities, named idiomatically per language: -- **Serialize**: `toXml()` (`to_xml` in Python and Ruby, `ToXml()` in C# and Go) returns the element as an XML document prefixed with the `` declaration. Pass `false` to omit the declaration: `toXml(false)` in TypeScript, Java, and PHP, `ToXml(false)` in C#, `to_xml(xml_declaration=False)` in Python, and `to_xml(xml_declaration: false)` in Ruby. Go's `ToXml()` always includes it. Nested children are always written without a declaration. +- **Serialize**: `toXml()` (`to_xml` in Python and Ruby, `ToXml()` in C# and Go) returns the element as an XML document prefixed with the `` declaration. Pass `false` to omit the declaration: `toXml(false)` in TypeScript, Java, and PHP, `ToXml(false)` in C#, `to_xml(xml_declaration=False)` in Python, and `to_xml(false)` or `to_xml(xml_declaration: false)` in Ruby (`to_s(false)` also works). PHP also exposes `asXML()` as an alias for `toXml()`. In C#, `ToXml(xmlDeclaration, indent)` returns indented XML; the other overloads and `ToString()` return compact XML. Go's `ToXml()` always includes the declaration. Nested children are always written without a declaration. - **Parse**: `fromXml(xml)` (`from_xml` in Python and Ruby, `FromXml()` in C#, `FromXml()` in Go) parses an XML string back into the model. Parsing validates the root element name and scalar values, and rejects malformed input and `DOCTYPE` declarations. Enum values are open in Go, PHP, and Ruby, and in TypeScript with `enableForwardCompatibleEnums: true`: a value the enum doesn't declare (for example, one added to the API after the SDK was generated) is kept and re-emitted by `toXml`. -- **Build**: one fluent method per child element type, named after the XML tag (for example, `garden.plant(...)`). In TypeScript, Python, Ruby, and PHP, each method constructs the child, appends it, and returns the child so its own children can be added. In C# and Go, it appends the child and returns the parent so calls chain (`response.Say(...).Say(...)`). A child method gets an `add` prefix (`addPlant`, `add_plant`, `AddPlant`) when its tag collides with a property or method of the parent, or when the name is a reserved word (`addBreak` in TypeScript, `break_` in Python and Ruby). +- **Build**: one fluent method per child element type, named after the XML tag (for example, `garden.plant(...)`). In TypeScript, Python, Ruby, and PHP, each method constructs the child, appends it, and returns the child so its own children can be added. In C# and Go, it appends the child and returns the parent so calls chain (`response.Say(...).Say(...)`). A child method gets an `add` prefix (`addPlant`, `add_plant`, `AddPlant`) when its tag collides with a property or method of the parent, or when the name is a reserved word (`addBreak` in TypeScript, `break_` in Python and Ruby). In Java, the typed overload under the tag name (`number(Number)` on `Dial.Builder`) is generated alongside `addNumber(Number)` even when a text or attribute setter already uses that name, as long as the parameter types differ. + +Child methods for elements that carry text take that text first. In TypeScript, pass the text as a string or pass a fields object (`response.say("hi")` or `response.say({ message: "hi", voice: "alice" })`). In C#, the value overload lists the element text first, then required attributes, then optional attributes (`response.Say("hi", voice: "alice")`). In Java, a type whose text is required gets a `builder(text)` factory (`Body.builder("hi")`), and each list-valued attribute setter accepts varargs as well as a `List` (`Gather.builder().input(GatherInputItem.DTMF, GatherInputItem.SPEECH)`). ```ts TypeScript const garden = SeedApi.Garden.builder({ climate: "temperate" }); -garden.plant("Fern", { sunlight: "full" }); +garden.plant({ name: "Fern", sunlight: "full" }); const xml = garden.toXml(); const parsed = SeedApi.Garden.fromXml(xml); // immutable model From 81275d21cf9bf7404ab69f5af6843e7f395d05ce Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sat, 24 Oct 2026 17:09:36 +0000 Subject: [PATCH 2/2] docs(sdks): Go xmlTextFirstBuilders text-first XML child builders and Ptr helper Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- fern/products/sdks/deep-dives/xml-encoded-types.mdx | 2 +- .../sdks/legacy/deep-dives/xml-encoded-types.mdx | 2 +- .../sdks/legacy/generators/go/configuration.mdx | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/fern/products/sdks/deep-dives/xml-encoded-types.mdx b/fern/products/sdks/deep-dives/xml-encoded-types.mdx index 5c18d12cb5..152df6f77d 100644 --- a/fern/products/sdks/deep-dives/xml-encoded-types.mdx +++ b/fern/products/sdks/deep-dives/xml-encoded-types.mdx @@ -65,7 +65,7 @@ Every XML-encoded type gets three capabilities, named idiomatically per language - **Parse**: `fromXml(xml)` (`from_xml` in Python and Ruby, `FromXml()` in C#, `FromXml()` in Go) parses an XML string back into the model. Parsing validates the root element name and scalar values, and rejects malformed input and `DOCTYPE` declarations. Enum values are open in Go, PHP, and Ruby, and in TypeScript with `enableForwardCompatibleEnums: true`: a value the enum doesn't declare (for example, one added to the API after the SDK was generated) is kept and re-emitted by `toXml`. - **Build**: one fluent method per child element type, named after the XML tag (for example, `garden.plant(...)`). In TypeScript, Python, Ruby, and PHP, each method constructs the child, appends it, and returns the child so its own children can be added. In C# and Go, it appends the child and returns the parent so calls chain (`response.Say(...).Say(...)`). A child method gets an `add` prefix (`addPlant`, `add_plant`, `AddPlant`) when its tag collides with a property or method of the parent, or when the name is a reserved word (`addBreak` in TypeScript, `break_` in Python and Ruby). In Java, the typed overload under the tag name (`number(Number)` on `Dial.Builder`) is generated alongside `addNumber(Number)` even when a text or attribute setter already uses that name, as long as the parameter types differ. -Child methods for elements that carry text take that text first. In TypeScript, pass the text as a string or pass a fields object (`response.say("hi")` or `response.say({ message: "hi", voice: "alice" })`). In C#, the value overload lists the element text first, then required attributes, then optional attributes (`response.Say("hi", voice: "alice")`). In Java, a type whose text is required gets a `builder(text)` factory (`Body.builder("hi")`), and each list-valued attribute setter accepts varargs as well as a `List` (`Gather.builder().input(GatherInputItem.DTMF, GatherInputItem.SPEECH)`). +Child methods for elements that carry text take that text first. In TypeScript, pass the text as a string or pass a fields object (`response.say("hi")` or `response.say({ message: "hi", voice: "alice" })`). In C#, the value overload lists the element text first, then required attributes, then optional attributes (`response.Say("hi", voice: "alice")`). In Java, a type whose text is required gets a `builder(text)` factory (`Body.builder("hi")`), and each list-valued attribute setter accepts varargs as well as a `List` (`Gather.builder().input(GatherInputItem.DTMF, GatherInputItem.SPEECH)`). In Go, text-first child methods are opt-in through the [`xmlTextFirstBuilders`](/learn/sdks/legacy/generators/go/configuration#xmltextfirstbuilders) option: each child method then takes the element text followed by functional options for its attributes (`response.Say("hi", WithSayVoice("alice"))`, or `response.Pause(WithPauseLength(1))` for an element without text), and the typed variant moves to the `Add` prefix (`response.AddSay(&Say{...})`). Each `With` option takes the value itself rather than a pointer. Generated Go SDKs also include a generic `Ptr(v)` helper alongside `String`, `Int`, and `Bool` for setting any pointer-typed field (`&Say{Message: Ptr("hi")}`). ```ts TypeScript diff --git a/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx b/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx index 09ba2d081b..39c47a2918 100644 --- a/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx +++ b/fern/products/sdks/legacy/deep-dives/xml-encoded-types.mdx @@ -67,7 +67,7 @@ Every XML-encoded type gets three capabilities, named idiomatically per language - **Parse**: `fromXml(xml)` (`from_xml` in Python and Ruby, `FromXml()` in C#, `FromXml()` in Go) parses an XML string back into the model. Parsing validates the root element name and scalar values, and rejects malformed input and `DOCTYPE` declarations. Enum values are open in Go, PHP, and Ruby, and in TypeScript with `enableForwardCompatibleEnums: true`: a value the enum doesn't declare (for example, one added to the API after the SDK was generated) is kept and re-emitted by `toXml`. - **Build**: one fluent method per child element type, named after the XML tag (for example, `garden.plant(...)`). In TypeScript, Python, Ruby, and PHP, each method constructs the child, appends it, and returns the child so its own children can be added. In C# and Go, it appends the child and returns the parent so calls chain (`response.Say(...).Say(...)`). A child method gets an `add` prefix (`addPlant`, `add_plant`, `AddPlant`) when its tag collides with a property or method of the parent, or when the name is a reserved word (`addBreak` in TypeScript, `break_` in Python and Ruby). In Java, the typed overload under the tag name (`number(Number)` on `Dial.Builder`) is generated alongside `addNumber(Number)` even when a text or attribute setter already uses that name, as long as the parameter types differ. -Child methods for elements that carry text take that text first. In TypeScript, pass the text as a string or pass a fields object (`response.say("hi")` or `response.say({ message: "hi", voice: "alice" })`). In C#, the value overload lists the element text first, then required attributes, then optional attributes (`response.Say("hi", voice: "alice")`). In Java, a type whose text is required gets a `builder(text)` factory (`Body.builder("hi")`), and each list-valued attribute setter accepts varargs as well as a `List` (`Gather.builder().input(GatherInputItem.DTMF, GatherInputItem.SPEECH)`). +Child methods for elements that carry text take that text first. In TypeScript, pass the text as a string or pass a fields object (`response.say("hi")` or `response.say({ message: "hi", voice: "alice" })`). In C#, the value overload lists the element text first, then required attributes, then optional attributes (`response.Say("hi", voice: "alice")`). In Java, a type whose text is required gets a `builder(text)` factory (`Body.builder("hi")`), and each list-valued attribute setter accepts varargs as well as a `List` (`Gather.builder().input(GatherInputItem.DTMF, GatherInputItem.SPEECH)`). In Go, text-first child methods are opt-in through the [`xmlTextFirstBuilders`](/learn/sdks/legacy/generators/go/configuration#xmltextfirstbuilders) option: each child method then takes the element text followed by functional options for its attributes (`response.Say("hi", WithSayVoice("alice"))`, or `response.Pause(WithPauseLength(1))` for an element without text), and the typed variant moves to the `Add` prefix (`response.AddSay(&Say{...})`). Each `With` option takes the value itself rather than a pointer. Generated Go SDKs also include a generic `Ptr(v)` helper alongside `String`, `Int`, and `Bool` for setting any pointer-typed field (`&Say{Message: Ptr("hi")}`). ```ts TypeScript diff --git a/fern/products/sdks/legacy/generators/go/configuration.mdx b/fern/products/sdks/legacy/generators/go/configuration.mdx index 12da868022..d0d990ae43 100644 --- a/fern/products/sdks/legacy/generators/go/configuration.mdx +++ b/fern/products/sdks/legacy/generators/go/configuration.mdx @@ -215,4 +215,17 @@ config: ``` This sends `User-Agent: plantstore-go-sdk/0.1.0`. With [`includePlatformHeaders`](#includeplatformheaders) enabled, the resolved value leads the structured header: `User-Agent: plantstore-go-sdk/0.1.0 (linux; x86_64) Go/1.22.0`. A value that doesn't end in a version, such as `plantstore/sdk-go`, is used as-is. The [`allowUserAgentAppInfo`](#allowuseragentappinfo) token is appended after either form. + + + +When enabled, child builder methods on [XML-encoded types](/learn/sdks/legacy/deep-dives/xml-encoded-types#generated-methods) take the element text first and set attributes through functional options, and the typed builder moves to the `Add` prefix: + +```go +r := &Response{} +r.Say("hi", WithSayVoice("alice"), WithSayLoop(2)). + Pause(WithPauseLength(1)) +r.AddSay(&Say{Message: Ptr("typed")}) +``` + +Each XML-encoded type gets a `Option` type and one `With` option per attribute. When disabled, child methods take the typed child (`r.Say(&Say{...})`). \ No newline at end of file