You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by gi...@apache.org on 2021/10/02 06:03:17 UTC

[beam] branch asf-site updated: Publishing website 2021/10/02 06:02:45 at commit b9457b7

This is an automated email from the ASF dual-hosted git repository.

git-site-role pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 39fc301  Publishing website 2021/10/02 06:02:45 at commit b9457b7
39fc301 is described below

commit 39fc301df36a239e676d921c95f0b09321b0775e
Author: jenkins <bu...@apache.org>
AuthorDate: Sat Oct 2 06:02:45 2021 +0000

    Publishing website 2021/10/02 06:02:45 at commit b9457b7
---
 website/generated-content/documentation/index.xml  | 259 +++++++++++++++++++--
 .../documentation/programming-guide/index.html     | 211 ++++++++++++++---
 website/generated-content/sitemap.xml              |   2 +-
 3 files changed, 425 insertions(+), 47 deletions(-)

diff --git a/website/generated-content/documentation/index.xml b/website/generated-content/documentation/index.xml
index 9c698e5..56112c0 100644
--- a/website/generated-content/documentation/index.xml
+++ b/website/generated-content/documentation/index.xml
@@ -5898,7 +5898,7 @@ determined by the input data, or depend on a different branch of your pipeline.&
 &lt;span class="kd">var&lt;/span> &lt;span class="nx">cutOff&lt;/span> &lt;span class="kt">float64&lt;/span>
 &lt;span class="nx">ok&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nf">lengthCutOffIter&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nx">cutOff&lt;/span>&lt;span class="p">)&lt;/span>
 &lt;span class="k">if&lt;/span> &lt;span class="p">!&lt;/span>&lt;span class="nx">ok&lt;/span> &lt;span class="p">{&lt;/span>
-&lt;span class="k">return&lt;/span> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Errorf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;No length cutoff provided.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Errorf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;no length cutoff provided&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
 &lt;span class="p">}&lt;/span>
 &lt;span class="k">if&lt;/span> &lt;span class="nb">float64&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">word&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">&amp;gt;&lt;/span> &lt;span class="nx">cutOff&lt;/span> &lt;span class="p">{&lt;/span>
 &lt;span class="nf">emitAboveCutoff&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">word&lt;/span>&lt;span class="p">)&lt;/span>
@@ -5948,7 +5948,7 @@ a different view of the side input each time.&lt;/p>
 latest trigger firing. This is particularly useful if you use a side input with
 a single global window and specify a trigger.&lt;/p>
 &lt;h3 id="additional-outputs">4.5. Additional outputs&lt;/h3>
-&lt;p class="language-java language-python">While &lt;code>ParDo&lt;/code> always produces a main output &lt;code>PCollection&lt;/code> (as the return value
+&lt;p class="language-java language-py">While &lt;code>ParDo&lt;/code> always produces a main output &lt;code>PCollection&lt;/code> (as the return value
 from &lt;code>apply&lt;/code>), you can also have your &lt;code>ParDo&lt;/code> produce any number of additional
 output &lt;code>PCollection&lt;/code>s. If you choose to have multiple outputs, your &lt;code>ParDo&lt;/code>
 returns all of the output &lt;code>PCollection&lt;/code>s (including the main output) bundled
@@ -6875,6 +6875,8 @@ having Beam understand their element schemas.&lt;/p>
 &lt;p class="language-java">In Java you could use the following set of classes to represent the purchase schema. Beam will automatically
 infer the correct schema based on the members of the class.&lt;/p>
 &lt;p class="language-py">In Python you can use the following set of classes to represent the purchase schema. Beam will automatically infer the correct schema based on the members of the class.&lt;/p>
+&lt;p class="language-go">In Go, schema encoding is used by default for struct types, with Exported fields becoming part of the schema.
+Beam will automatically infer the schema based on the fields and field tags of the struct, and their order.&lt;/p>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
 &lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
@@ -6941,6 +6943,38 @@ infer the correct schema based on the members of the class.&lt;/p>
 &lt;span class="n">purchase_amount&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">float&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
 &lt;/div>
 &lt;/div>
+&lt;div class='language-go snippet'>
+&lt;div class="notebook-skip code-snippet">
+&lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
+&lt;img src="/images/copy-icon.svg"/>
+&lt;/a>
+&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="kd">type&lt;/span> &lt;span class="nx">Purchase&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="c1">// ID of the user who made the purchase.
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="nx">UserID&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;userId&amp;#34;`&lt;/span>
+&lt;span class="c1">// Identifier of the item that was purchased.
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="nx">ItemID&lt;/span> &lt;span class="kt">int64&lt;/span> &lt;span class="s">`beam:&amp;#34;itemId&amp;#34;`&lt;/span>
+&lt;span class="c1">// The shipping address, a nested type.
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="nx">ShippingAddress&lt;/span> &lt;span class="nx">ShippingAddress&lt;/span> &lt;span class="s">`beam:&amp;#34;shippingAddress&amp;#34;`&lt;/span>
+&lt;span class="c1">// The cost of the item in cents.
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="nx">Cost&lt;/span> &lt;span class="kt">int64&lt;/span> &lt;span class="s">`beam:&amp;#34;cost&amp;#34;`&lt;/span>
+&lt;span class="c1">// The transactions that paid for this purchase.
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="c1">// A slice since the purchase might be spread out over multiple
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="c1">// credit cards.
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="nx">Transactions&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="nx">Transaction&lt;/span> &lt;span class="s">`beam:&amp;#34;transactions&amp;#34;`&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="kd">type&lt;/span> &lt;span class="nx">ShippingAddress&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="nx">StreetAddress&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;streetAddress&amp;#34;`&lt;/span>
+&lt;span class="nx">City&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;city&amp;#34;`&lt;/span>
+&lt;span class="nx">State&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;state&amp;#34;`&lt;/span>
+&lt;span class="nx">Country&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;country&amp;#34;`&lt;/span>
+&lt;span class="nx">PostCode&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;postCode&amp;#34;`&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="kd">type&lt;/span> &lt;span class="nx">Transaction&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="nx">Bank&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;bank&amp;#34;`&lt;/span>
+&lt;span class="nx">PurchaseAmount&lt;/span> &lt;span class="kt">float64&lt;/span> &lt;span class="s">`beam:&amp;#34;purchaseAmount&amp;#34;`&lt;/span>
+&lt;span class="p">}&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
+&lt;/div>
+&lt;/div>
 &lt;p class="language-java">Using JavaBean classes as above is one way to map a schema to Java classes. However multiple Java classes might have
 the same schema, in which case the different Java types can often be used interchangeably. Beam will add implicit
 conversions between types that have matching schemas. For example, the above
@@ -7087,6 +7121,9 @@ a nanosecond timestamp, with the INT64 field representing seconds and the INT32
 limited-precision decimal type would have an integer argument indicating how many digits of precision are represented.
 The argument is represented by a schema type, so can itself be a complex type.&lt;/p>
 &lt;p class="language-java">In Java, a logical type is specified as a subclass of the &lt;code>LogicalType&lt;/code> class. A custom Java class can be specified to represent the logical type and conversion functions must be supplied to convert back and forth between this Java class and the underlying Schema type representation. For example, the logical type representing nanosecond timestamp might be implemented as follows&lt;/p>
+&lt;p class="language-go">In Go, a logical type is specified with a custom implementation of the &lt;code>beam.SchemaProvider&lt;/code> interface.
+For example, the logical type provider representing nanosecond timestamps
+might be implemented as follows&lt;/p>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
 &lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
@@ -7110,9 +7147,91 @@ The argument is represented by a schema type, so can itself be a complex type.&l
 &lt;span class="o">}&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
 &lt;/div>
 &lt;/div>
+&lt;div class='language-go snippet'>
+&lt;div class="notebook-skip code-snippet">
+&lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
+&lt;img src="/images/copy-icon.svg"/>
+&lt;/a>
+&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="c1">// Define a logical provider like so:
+&lt;/span>&lt;span class="c1">&lt;/span>
+&lt;span class="c1">// TimestampNanos is a logical type using time.Time, but
+&lt;/span>&lt;span class="c1">// encodes as a schema type.
+&lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="kd">type&lt;/span> &lt;span class="nx">TimestampNanos&lt;/span> &lt;span class="nx">time&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Time&lt;/span>
+&lt;span class="kd">func&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">tn&lt;/span> &lt;span class="nx">TimestampNanos&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nf">Seconds&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kt">int64&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="nx">time&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Time&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tn&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nf">Unix&lt;/span>&lt;span class="p">()&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="kd">func&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">tn&lt;/span> &lt;span class="nx">TimestampNanos&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nf">Nanos&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kt">int32&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="nb">int32&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">time&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Time&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tn&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nf">UnixNano&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">1000000000&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="c1">// tnStorage is the storage schema for TimestampNanos.
+&lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="kd">type&lt;/span> &lt;span class="nx">tnStorage&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="nx">Seconds&lt;/span> &lt;span class="kt">int64&lt;/span> &lt;span class="s">`beam:&amp;#34;seconds&amp;#34;`&lt;/span>
+&lt;span class="nx">Nanos&lt;/span> &lt;span class="kt">int32&lt;/span> &lt;span class="s">`beam:&amp;#34;nanos&amp;#34;`&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="kd">var&lt;/span> &lt;span class="p">(&lt;/span>
+&lt;span class="c1">// reflect.Type of the Value type of TimestampNanos
+&lt;/span>&lt;span class="c1">&lt;/span> &lt;span class="nx">tnType&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">TypeOf&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="nx">TimestampNanos&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="kc">nil&lt;/span>&lt;span class="p">)).&lt;/span>&lt;span class="nf">Elem&lt;/span>&lt;span class="p">()&lt;/span>
+&lt;span class="nx">tnStorageType&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">TypeOf&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="nx">tnStorage&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="kc">nil&lt;/span>&lt;span class="p">)).&lt;/span>&lt;span class="nf">Elem&lt;/span>&lt;span class="p">()&lt;/span>
+&lt;span class="p">)&lt;/span>
+&lt;span class="c1">// TimestampNanosProvider implements the beam.SchemaProvider interface.
+&lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="kd">type&lt;/span> &lt;span class="nx">TimestampNanosProvider&lt;/span> &lt;span class="kd">struct&lt;/span>&lt;span class="p">{}&lt;/span>
+&lt;span class="c1">// FromLogicalType converts checks if the given type is TimestampNanos, and if so
+&lt;/span>&lt;span class="c1">// returns the storage type.
+&lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="kd">func&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">p&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="nx">TimestampNanosProvider&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nf">FromLogicalType&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">rt&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Type&lt;/span>&lt;span class="p">)&lt;/span> &l [...]
+&lt;span class="k">if&lt;/span> &lt;span class="nx">rt&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="nx">tnType&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Errorf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;unable to provide schema.LogicalType for type %v, want %v&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">rt&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">tnType&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="nx">tnStorageType&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">nil&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="c1">// BuildEncoder builds a Beam schema encoder for the TimestampNanos type.
+&lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="kd">func&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">p&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="nx">TimestampNanosProvider&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nf">BuildEncoder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">rt&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Type&lt;/span>&lt;span class="p">)&lt;/span> &lt;s [...]
+&lt;span class="k">if&lt;/span> &lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">FromLogicalType&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">rt&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="nx">enc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">coder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">RowEncoderForStruct&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tnStorageType&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kd">func&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">iface&lt;/span> &lt;span class="kd">interface&lt;/span>&lt;span class="p">{},&lt;/span> &lt;span class="nx">w&lt;/span> &lt;span class="nx">io&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Writer&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kt">error&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="nx">v&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">iface&lt;/span>&lt;span class="p">.(&lt;/span>&lt;span class="nx">TimestampNanos&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="nf">enc&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tnStorage&lt;/span>&lt;span class="p">{&lt;/span>
+&lt;span class="nx">Seconds&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nx">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Seconds&lt;/span>&lt;span class="p">(),&lt;/span>
+&lt;span class="nx">Nanos&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nx">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Nanos&lt;/span>&lt;span class="p">(),&lt;/span>
+&lt;span class="p">},&lt;/span> &lt;span class="nx">w&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="p">},&lt;/span> &lt;span class="kc">nil&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="c1">// BuildDecoder builds a Beam schema decoder for the TimestampNanos type.
+&lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="kd">func&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">p&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="nx">TimestampNanosProvider&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nf">BuildDecoder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">rt&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Type&lt;/span>&lt;span class="p">)&lt;/span> &lt;s [...]
+&lt;span class="k">if&lt;/span> &lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">p&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">FromLogicalType&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">rt&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="nx">dec&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">coder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">RowDecoderForStruct&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tnStorageType&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kd">func&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">r&lt;/span> &lt;span class="nx">io&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Reader&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kd">interface&lt;/span>&lt;span class="p">{},&lt;/span> &lt;span class="kt">error&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="nx">s&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nf">dec&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">r&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="nx">tn&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">s&lt;/span>&lt;span class="p">.(&lt;/span>&lt;span class="nx">tnStorage&lt;/span>&lt;span class="p">)&lt;/span>
+&lt;span class="k">return&lt;/span> &lt;span class="nf">TimestampNanos&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">time&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Unix&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tn&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Seconds&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">int64&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tn&lt;/span>&lt;span class="p">.&lt;/sp [...]
+&lt;span class="p">},&lt;/span> &lt;span class="kc">nil&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="c1">// Register it like so:
+&lt;/span>&lt;span class="c1">&lt;/span>
+&lt;span class="nx">beam&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">RegisterSchemaProvider&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">tnType&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nx">TimestampNanosProvider&lt;/span>&lt;span class="p">{})&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
+&lt;/div>
+&lt;/div>
 &lt;h4 id="built-in-logical-types">6.4.2. Useful logical types&lt;/h4>
+&lt;p class="language-py">Currently the Python SDK provides minimal convenience logical types,
+other than to handle &lt;code>MicrosInstant&lt;/code>.&lt;/p>
+&lt;p class="language-go">Currently the Go SDK provides minimal convenience logical types,
+other than to handle additional integer primitives, and &lt;code>time.Time&lt;/code>.&lt;/p>
 &lt;h5 id="enumerationtype">&lt;strong>EnumerationType&lt;/strong>&lt;/h5>
-&lt;p>This logical type allows creating an enumeration type consisting of a set of named constants.&lt;/p>
+&lt;p class="language-py">This convenience builder doesn&amp;rsquo;t yet exist for the Python SDK.&lt;/p>
+&lt;p class="language-go">This convenience builder doesn&amp;rsquo;t yet exist for the Go SDK.&lt;/p>
+&lt;p class="language-java">This logical type allows creating an enumeration type consisting of a set of named constants.&lt;/p>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
 &lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
@@ -7124,7 +7243,7 @@ The argument is represented by a schema type, so can itself be a complex type.&l
 &lt;span class="o">.&lt;/span>&lt;span class="na">build&lt;/span>&lt;span class="o">();&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
 &lt;/div>
 &lt;/div>
-&lt;p>The value of this field is stored in the row as an INT32 type, however the logical type defines a value type that lets
+&lt;p class="language-java">The value of this field is stored in the row as an INT32 type, however the logical type defines a value type that lets
 you access the enumeration either as a string or a value. For example:&lt;/p>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
@@ -7136,7 +7255,7 @@ you access the enumeration either as a string or a value. For example:&lt;/p>
 &lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="n">enumValue&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">toString&lt;/span>&lt;span class="o">();&lt;/span> &lt;span class="o">//&lt;/span> &lt;span class="n">Returns&lt;/span> &lt;span class="s">&amp;#34;RED&amp;#34;&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">the&lt;/span> &lt;span class="n">string&lt;/span> &lt;span class="n">value&lt;/span> &lt;span class="n">of&lt;/span> &lt;span class="n">the&lt;/ [...]
 &lt;/div>
 &lt;/div>
-&lt;p>Given a row object with an enumeration field, you can also extract the field as the enumeration value.&lt;/p>
+&lt;p class="language-java">Given a row object with an enumeration field, you can also extract the field as the enumeration value.&lt;/p>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
 &lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
@@ -7145,10 +7264,12 @@ you access the enumeration either as a string or a value. For example:&lt;/p>
 &lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="n">EnumerationType&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">Value&lt;/span> &lt;span class="n">enumValue&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">getLogicalTypeValue&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="s">&amp;#34;color&amp;#34;&lt;/span>&lt;span class="o">,&l [...]
 &lt;/div>
 &lt;/div>
-&lt;p>Automatic schema inference from Java POJOs and JavaBeans automatically converts Java enums to EnumerationType logical
+&lt;p class="language-java">Automatic schema inference from Java POJOs and JavaBeans automatically converts Java enums to EnumerationType logical
 types.&lt;/p>
 &lt;h5 id="oneoftype">&lt;strong>OneOfType&lt;/strong>&lt;/h5>
-&lt;p>OneOfType allows creating a disjoint union type over a set of schema fields. For example:&lt;/p>
+&lt;p class="language-py">This convenience builder doesn&amp;rsquo;t yet exist for the Python SDK.&lt;/p>
+&lt;p class="language-go">This convenience builder doesn&amp;rsquo;t yet exist for the Go SDK.&lt;/p>
+&lt;p class="language-java">OneOfType allows creating a disjoint union type over a set of schema fields. For example:&lt;/p>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
 &lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
@@ -7163,7 +7284,7 @@ types.&lt;/p>
 &lt;span class="o">.&lt;/span>&lt;span class="na">build&lt;/span>&lt;span class="o">();&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
 &lt;/div>
 &lt;/div>
-&lt;p>The value of this field is stored in the row as another Row type, where all the fields are marked as nullable. The
+&lt;p class="language-java">The value of this field is stored in the row as another Row type, where all the fields are marked as nullable. The
 logical type however defines a Value object that contains an enumeration value indicating which field was set and allows
 getting just that field:&lt;/p>
 &lt;div class='language-java snippet'>
@@ -7188,12 +7309,27 @@ getting just that field:&lt;/p>
 &lt;span class="o">}&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
 &lt;/div>
 &lt;/div>
-&lt;p>In the above example we used the field names in the switch statement for clarity, however the enum integer values could
+&lt;p class="language-java">In the above example we used the field names in the switch statement for clarity, however the enum integer values could
 also be used.&lt;/p>
 &lt;h3 id="creating-schemas">6.5. Creating Schemas&lt;/h3>
-&lt;p>In order to take advantage of schemas, your &lt;code>PCollection&lt;/code>s must have a schema attached to it. Often, the source itself will attach a schema to the PCollection. For example, when using &lt;code>AvroIO&lt;/code> to read Avro files, the source can automatically infer a Beam schema from the Avro schema and attach that to the Beam &lt;code>PCollection&lt;/code>. However not all sources produce schemas. In addition, often Beam pipelines have intermediate stages and types [...]
+&lt;p>In order to take advantage of schemas, your &lt;code>PCollection&lt;/code>s must have a schema attached to it.
+Often, the source itself will attach a schema to the PCollection.
+For example, when using &lt;code>AvroIO&lt;/code> to read Avro files, the source can automatically infer a Beam schema from the Avro schema and attach that to the Beam &lt;code>PCollection&lt;/code>.
+However not all sources produce schemas.
+In addition, often Beam pipelines have intermediate stages and types, and those also can benefit from the expressiveness of schemas.&lt;/p>
 &lt;h4 id="inferring-schemas">6.5.1. Inferring schemas&lt;/h4>
-&lt;p class="language-java">Beam is able to infer schemas from a variety of common Java types. The &lt;code>@DefaultSchema&lt;/code> annotation can be used to tell Beam to infer schemas from a specific type. The annotation takes a &lt;code>SchemaProvider&lt;/code> as an argument, and &lt;code>SchemaProvider&lt;/code> classes are already built in for common Java types. The &lt;code>SchemaRegistry&lt;/code> can also be invoked programmatically for cases where it is not practical to annotat [...]
+&lt;nav class="language-switcher">
+&lt;strong>Adapt for:&lt;/strong>
+&lt;ul>
+&lt;li data-type="language-java" class="active">Java SDK&lt;/li>
+&lt;li data-type="language-py">Python SDK&lt;/li>
+&lt;li data-type="language-go">Go SDK&lt;/li>
+&lt;/ul>
+&lt;/nav>
+&lt;p class="language-java">Beam is able to infer schemas from a variety of common Java types.
+The &lt;code>@DefaultSchema&lt;/code> annotation can be used to tell Beam to infer schemas from a specific type.
+The annotation takes a &lt;code>SchemaProvider&lt;/code> as an argument, and &lt;code>SchemaProvider&lt;/code> classes are already built in for common Java types.
+The &lt;code>SchemaRegistry&lt;/code> can also be invoked programmatically for cases where it is not practical to annotate the Java type itself.&lt;/p>
 &lt;p class="language-java">&lt;strong>Java POJOs&lt;/strong>&lt;/p>
 &lt;p class="language-java">A POJO (Plain Old Java Object) is a Java object that is not bound by any restriction other than the Java Language
 Specification. A POJO can contain member variables that are primitives, that are other POJOs, or are collections maps or
@@ -7359,10 +7495,48 @@ correctly infers types with &lt;code>beam.Row&lt;/code> or with &lt;code>Select&
 &lt;span class="n">purchase_amount&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">float&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">item&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;purchase_amount&amp;#34;&lt;/span>&lt;span class="p">])))&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
 &lt;/div>
 &lt;/div>
+&lt;p class="language-go">Beam currently only infers schemas for exported fields in Go structs.&lt;/p>
+&lt;p class="language-go">&lt;strong>Structs&lt;/strong>&lt;/p>
+&lt;p class="language-go">Beam will automatically infer schemas for all Go structs used
+as PCollection elements, and default to encoding them using
+schema encoding.&lt;/p>
+&lt;div class='language-go snippet'>
+&lt;div class="notebook-skip code-snippet">
+&lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
+&lt;img src="/images/copy-icon.svg"/>
+&lt;/a>
+&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="kd">type&lt;/span> &lt;span class="nx">Transaction&lt;/span> &lt;span class="kd">struct&lt;/span>&lt;span class="p">{&lt;/span>
+&lt;span class="nx">Bank&lt;/span> &lt;span class="kt">string&lt;/span>
+&lt;span class="nx">PurchaseAmount&lt;/span> &lt;span class="kt">float64&lt;/span>
+&lt;span class="nx">checksum&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="kt">byte&lt;/span> &lt;span class="c1">// ignored
+&lt;/span>&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
+&lt;/div>
+&lt;/div>
+&lt;p class="language-go">Unexported fields are ignored, and cannot be automatically infered as part of the schema.
+Fields of type func, channel, unsafe.Pointer, or uintptr will be ignored by inference.
+Fields of interface types are ignored, unless a schema provider
+is registered for them.&lt;/p>
+&lt;p class="language-go">By default, schema field names will match the exported struct field names.
+In the above example, &amp;ldquo;Bank&amp;rdquo; and &amp;ldquo;PurchaseAmount&amp;rdquo; are the schema field names.
+A schema field name can be overridden with a struct tag for the field.&lt;/p>
+&lt;div class='language-go snippet'>
+&lt;div class="notebook-skip code-snippet">
+&lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
+&lt;img src="/images/copy-icon.svg"/>
+&lt;/a>
+&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="kd">type&lt;/span> &lt;span class="nx">Transaction&lt;/span> &lt;span class="kd">struct&lt;/span>&lt;span class="p">{&lt;/span>
+&lt;span class="nx">Bank&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`beam:&amp;#34;bank&amp;#34;`&lt;/span>
+&lt;span class="nx">PurchaseAmount&lt;/span> &lt;span class="kt">float64&lt;/span> &lt;span class="s">`beam:&amp;#34;purchase_amount&amp;#34;`&lt;/span>
+&lt;span class="p">}&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
+&lt;/div>
+&lt;/div>
+&lt;p class="language-go">Overriding schema field names is useful for compatibility cross language transforms,
+as schema fields may have different requirements or restrictions from Go exported fields.&lt;/p>
 &lt;h3 id="using-schemas">6.6. Using Schema Transforms&lt;/h3>
 &lt;p>A schema on a &lt;code>PCollection&lt;/code> enables a rich variety of relational transforms. The fact that each record is composed of
 named fields allows for simple and readable aggregations that reference fields by name, similar to the aggregations in
 a SQL expression.&lt;/p>
+&lt;p class="language-go">Beam does not yet support Schema transforms natively in Go. However, it will be implemented with the following behavior.&lt;/p>
 &lt;h4 id="661-field-selection-syntax">6.6.1. Field selection syntax&lt;/h4>
 &lt;p>The advantage of schemas is that they allow referencing of element fields by name. Beam provides a selection syntax for
 referencing fields, including nested and repeated fields. This syntax is used by all of the schema transforms when
@@ -7892,6 +8066,7 @@ pipeline will fail to launch.&lt;/p>
 &lt;p>A &lt;code>PCollection&lt;/code> with a schema can apply a &lt;code>ParDo&lt;/code>, just like any other &lt;code>PCollection&lt;/code>. However the Beam runner is aware
 of schemas when applying a &lt;code>ParDo&lt;/code>, which enables additional functionality.&lt;/p>
 &lt;h5 id="input-conversion">&lt;strong>Input conversion&lt;/strong>&lt;/h5>
+&lt;p class="language-go">Beam does not yet support input conversion in Go.&lt;/p>
 &lt;p>Since Beam knows the schema of the source &lt;code>PCollection&lt;/code>, it can automatically convert the elements to any Java type for
 which a matching schema is known. For example, using the above-mentioned Transaction schema, say we have the following
 &lt;code>PCollection&lt;/code>:&lt;/p>
@@ -7967,6 +8142,14 @@ using the above-described selection expressions, as follows:&lt;/p>
 &lt;p>For more information, see the section on field-selection expressions. When selecting subschemas, Beam will
 automatically convert to any matching schema type, just like when reading the entire row.&lt;/p>
 &lt;h2 id="data-encoding-and-type-safety">7. Data encoding and type safety&lt;/h2>
+&lt;nav class="language-switcher">
+&lt;strong>Adapt for:&lt;/strong>
+&lt;ul>
+&lt;li data-type="language-java" class="active">Java SDK&lt;/li>
+&lt;li data-type="language-py">Python SDK&lt;/li>
+&lt;li data-type="language-go">Go SDK&lt;/li>
+&lt;/ul>
+&lt;/nav>
 &lt;p>When Beam runners execute your pipeline, they often need to materialize the
 intermediate data in your &lt;code>PCollection&lt;/code>s, which requires converting elements to
 and from byte strings. The Beam SDKs use objects called &lt;code>Coder&lt;/code>s to describe how
@@ -7989,6 +8172,12 @@ types, Tuple, Iterable, StringUtf8 and more. You can find all of the available
 Coder subclasses in the
 &lt;a href="https://github.com/apache/beam/tree/master/sdks/python/apache_beam/coders">apache_beam.coders&lt;/a>
 package.&lt;/p>
+&lt;p class="language-go">Standard Go types like &lt;code>int&lt;/code>, &lt;code>int64&lt;/code> &lt;code>float64&lt;/code>, &lt;code>[]byte&lt;/code>, and &lt;code>string&lt;/code> and more are coded using builtin coders.
+Structs and pointers to structs default using Beam Schema Row encoding.
+However, users can build and register custom coders with &lt;code>beam.RegisterCoder&lt;/code>.
+You can find available Coder functions in the
+&lt;a href="https://pkg.go.dev/github.com/apache/beam/sdks/v2/go/pkg/beam/core/graph/coders">coder&lt;/a>
+package.&lt;/p>
 &lt;blockquote>
 &lt;p>Note that coders do not necessarily have a 1:1 relationship with types. For
 example, the Integer type can have multiple valid coders, and input and output
@@ -8016,6 +8205,8 @@ mapping of Java types to the default coders that the pipeline should use for
 &lt;p class="language-py">The Beam SDK for Python has a &lt;code>CoderRegistry&lt;/code> that represents a mapping of
 Python types to the default coder that should be used for &lt;code>PCollection&lt;/code>s of each
 type.&lt;/p>
+&lt;p class="language-go">The Beam SDK for Go allows users to register default coder
+implementations with &lt;code>beam.RegisterCoder&lt;/code>.&lt;/p>
 &lt;p class="language-java">By default, the Beam SDK for Java automatically infers the &lt;code>Coder&lt;/code> for the
 elements of a &lt;code>PCollection&lt;/code> produced by a &lt;code>PTransform&lt;/code> using the type parameter
 from the transform&amp;rsquo;s function object, such as &lt;code>DoFn&lt;/code>. In the case of &lt;code>ParDo&lt;/code>,
@@ -8032,13 +8223,20 @@ with the typehints &lt;code>@beam.typehints.with_input_types(int)&lt;/code> and
 and produces an output element of type str. In such a case, the Beam SDK for
 Python will automatically infer the default &lt;code>Coder&lt;/code> for the output &lt;code>PCollection&lt;/code>
 (in the default pipeline &lt;code>CoderRegistry&lt;/code>, this is &lt;code>BytesCoder&lt;/code>).&lt;/p>
+&lt;p class="language-go">By default, the Beam SDK for Go automatically infers the &lt;code>Coder&lt;/code> for the elements of an output &lt;code>PCollection&lt;/code> by the output of the transform&amp;rsquo;s function object, such as a &lt;code>DoFn&lt;/code>.
+In the case of &lt;code>ParDo&lt;/code>, for example a &lt;code>DoFn&lt;/code>
+with the parameters of &lt;code>v int, emit func(string)&lt;/code> accepts an input element of type &lt;code>int&lt;/code>
+and produces an output element of type &lt;code>string&lt;/code>.
+In such a case, the Beam SDK for Go will automatically infer the default &lt;code>Coder&lt;/code> for the output &lt;code>PCollection&lt;/code> to be the &lt;code>string_utf8&lt;/code> coder.&lt;/p>
+&lt;span class="language-java">
 &lt;blockquote>
-&lt;p>NOTE: If you create your &lt;code>PCollection&lt;/code> from in-memory data by using the
+&lt;p>&lt;strong>Note:&lt;/strong> If you create your &lt;code>PCollection&lt;/code> from in-memory data by using the
 &lt;code>Create&lt;/code> transform, you cannot rely on coder inference and default coders.
 &lt;code>Create&lt;/code> does not have access to any typing information for its arguments, and
 may not be able to infer a coder if the argument list contains a value whose
 exact run-time class doesn&amp;rsquo;t have a default coder registered.&lt;/p>
 &lt;/blockquote>
+&lt;/span>
 &lt;p class="language-java">When using &lt;code>Create&lt;/code>, the simplest way to ensure that you have the correct coder
 is by invoking &lt;code>withCoder&lt;/code> when you apply the &lt;code>Create&lt;/code> transform.&lt;/p>
 &lt;h3 id="default-coders-and-the-coderregistry">7.2. Default coders and the CoderRegistry&lt;/h3>
@@ -8153,8 +8351,9 @@ this pipeline, verify that Integer values are encoded using
 &lt;p class="language-py">You can use the method &lt;code>CoderRegistry.get_coder&lt;/code> to determine the default Coder
 for a Python type. You can use &lt;code>coders.registry&lt;/code> to access the &lt;code>CoderRegistry&lt;/code>.
 This allows you to determine (or set) the default Coder for a Python type.&lt;/p>
+&lt;p class="language-go">You can use the &lt;code>beam.NewCoder&lt;/code> function to determine the default Coder for a Go type.&lt;/p>
 &lt;h4 id="setting-default-coder">7.2.2. Setting the default coder for a type&lt;/h4>
-&lt;p>To set the default Coder for a
+&lt;p class="language-java language-py">To set the default Coder for a
 &lt;span class="language-java">Java&lt;/span>&lt;span class="language-py">Python&lt;/span>
 type for a particular pipeline, you obtain and modify the pipeline&amp;rsquo;s
 &lt;code>CoderRegistry&lt;/code>. You use the method
@@ -8164,10 +8363,13 @@ to get the &lt;code>CoderRegistry&lt;/code> object, and then use the method
 &lt;span class="language-java">&lt;code>CoderRegistry.registerCoder&lt;/code>&lt;/span>
 &lt;span class="language-py">&lt;code>CoderRegistry.register_coder&lt;/code>&lt;/span>
 to register a new &lt;code>Coder&lt;/code> for the target type.&lt;/p>
-&lt;p>The following example code demonstrates how to set a default Coder, in this case
+&lt;p class="language-go">To set the default Coder for a Go type you use the function &lt;code>beam.RegisterCoder&lt;/code> to register a encoder and decoder functions for the target type.
+However, built in types like &lt;code>int&lt;/code>, &lt;code>string&lt;/code>, &lt;code>float64&lt;/code>, etc cannot have their coders overridde.&lt;/p>
+&lt;p class="language-java language-py">The following example code demonstrates how to set a default Coder, in this case
 &lt;code>BigEndianIntegerCoder&lt;/code>, for
 &lt;span class="language-java">Integer&lt;/span>&lt;span class="language-py">int&lt;/span>
 values for a pipeline.&lt;/p>
+&lt;p class="language-go">The following example code demonstrates how to set a custom Coder for &lt;code>MyCustomType&lt;/code> elements.&lt;/p>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
 &lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
@@ -8187,8 +8389,26 @@ values for a pipeline.&lt;/p>
 &lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-py" data-lang="py">&lt;span class="n">apache_beam&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">coders&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">registry&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">register_coder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">BigEndianIntegerCoder&lt;/span>&lt;span c [...]
 &lt;/div>
 &lt;/div>
+&lt;div class='language-go snippet'>
+&lt;div class="notebook-skip code-snippet">
+&lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
+&lt;img src="/images/copy-icon.svg"/>
+&lt;/a>
+&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="kd">type&lt;/span> &lt;span class="nx">MyCustomType&lt;/span> &lt;span class="kd">struct&lt;/span>&lt;span class="p">{&lt;/span>
+&lt;span class="o">...&lt;/span>
+&lt;span class="p">}&lt;/span>
+&lt;span class="c1">// See documentation on beam.RegisterCoder for other supported coder forms.
+&lt;/span>&lt;span class="c1">&lt;/span>
+&lt;span class="kd">func&lt;/span> &lt;span class="nf">encode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">MyCustomType&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="kt">byte&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="o">...&lt;/span> &lt;span class="p">}&lt;/span>
+&lt;span class="kd">func&lt;/span> &lt;span class="nf">decode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">b&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="kt">byte&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nx">MyCustomType&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="o">...&lt;/span> &lt;span class="p">}&lt;/span>
+&lt;span class="kd">func&lt;/span> &lt;span class="nf">init&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
+&lt;span class="nx">beam&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">RegisterCoder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">TypeOf&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="nx">MyCustomType&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="kc">nil&lt;/span>&lt;span class="p">)).&lt;/span>&lt;span class="nf">Elem&lt;/span>&lt;span class="p"> [...]
+&lt;span class="p">}&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
+&lt;/div>
+&lt;/div>
 &lt;h4 id="annotating-custom-type-default-coder">7.2.3. Annotating a custom data type with a default coder&lt;/h4>
-&lt;p class="language-java">&lt;p>If your pipeline program defines a custom data type, you can use the
+&lt;span class="language-java">
+&lt;p>If your pipeline program defines a custom data type, you can use the
 &lt;code>@DefaultCoder&lt;/code> annotation to specify the coder to use with that type.
 By default, Beam will use &lt;code>SerializableCoder&lt;/code> which uses Java serialization,
 but it has drawbacks:&lt;/p>
@@ -8202,11 +8422,11 @@ See this &lt;a href="https://blog.softwaremill.com/the-best-serialization-strate
 equivalent objects.&lt;/p>
 &lt;p>For key/value pairs, the correctness of key-based operations
 (GroupByKey, Combine) and per-key State depends on having a deterministic
-coder for the key.&lt;/p>
+coder for the key&lt;/p>
 &lt;/li>
 &lt;/ol>
 &lt;p>You can use the &lt;code>@DefaultCoder&lt;/code> annotation to set a new default as follows:&lt;/p>
-&lt;/p>
+&lt;/span>
 &lt;div class='language-java snippet'>
 &lt;div class="notebook-skip code-snippet">
 &lt;a class="copy" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Copy to clipboard">
@@ -8236,8 +8456,9 @@ the &lt;code>@DefaultCoder&lt;/code> annotation, your coder class must implement
 &lt;span class="o">}&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
 &lt;/div>
 &lt;/div>
-&lt;p class="language-py">The Beam SDK for Python does not support annotating data types with a default
-coder. If you would like to set a default coder, use the method described in the
+&lt;p class="language-py language-go">The Beam SDK for &lt;span class="language-py">Python&lt;/span>&lt;span class="language-go">Go&lt;/span>
+does not support annotating data types with a default coder.
+If you would like to set a default coder, use the method described in the
 previous section, &lt;em>Setting the default coder for a type&lt;/em>.&lt;/p>
 &lt;h2 id="windowing">8. Windowing&lt;/h2>
 &lt;p>Windowing subdivides a &lt;code>PCollection&lt;/code> according to the timestamps of its
diff --git a/website/generated-content/documentation/programming-guide/index.html b/website/generated-content/documentation/programming-guide/index.html
index b31a31e..9cc9792 100644
--- a/website/generated-content/documentation/programming-guide/index.html
+++ b/website/generated-content/documentation/programming-guide/index.html
@@ -1367,7 +1367,7 @@ determined by the input data, or depend on a different branch of your pipeline.<
 	<span class=kd>var</span> <span class=nx>cutOff</span> <span class=kt>float64</span>
 	<span class=nx>ok</span> <span class=o>:=</span> <span class=nf>lengthCutOffIter</span><span class=p>(</span><span class=o>&amp;</span><span class=nx>cutOff</span><span class=p>)</span>
 	<span class=k>if</span> <span class=p>!</span><span class=nx>ok</span> <span class=p>{</span>
-		<span class=k>return</span> <span class=nx>fmt</span><span class=p>.</span><span class=nf>Errorf</span><span class=p>(</span><span class=s>&#34;No length cutoff provided.&#34;</span><span class=p>)</span>
+		<span class=k>return</span> <span class=nx>fmt</span><span class=p>.</span><span class=nf>Errorf</span><span class=p>(</span><span class=s>&#34;no length cutoff provided&#34;</span><span class=p>)</span>
 	<span class=p>}</span>
 	<span class=k>if</span> <span class=nb>float64</span><span class=p>(</span><span class=nb>len</span><span class=p>(</span><span class=nx>word</span><span class=p>))</span> <span class=p>&gt;</span> <span class=nx>cutOff</span> <span class=p>{</span>
 		<span class=nf>emitAboveCutoff</span><span class=p>(</span><span class=nx>word</span><span class=p>)</span>
@@ -1412,7 +1412,7 @@ gets called multiple times, once for each window. Each call to <code>processElem
 projects the &ldquo;current&rdquo; window for the main input element, and thus might provide
 a different view of the side input each time.</p><p>If the side input has multiple trigger firings, Beam uses the value from the
 latest trigger firing. This is particularly useful if you use a side input with
-a single global window and specify a trigger.</p><h3 id=additional-outputs>4.5. Additional outputs</h3><p class="language-java language-python">While <code>ParDo</code> always produces a main output <code>PCollection</code> (as the return value
+a single global window and specify a trigger.</p><h3 id=additional-outputs>4.5. Additional outputs</h3><p class="language-java language-py">While <code>ParDo</code> always produces a main output <code>PCollection</code> (as the return value
 from <code>apply</code>), you can also have your <code>ParDo</code> produce any number of additional
 output <code>PCollection</code>s. If you choose to have multiple outputs, your <code>ParDo</code>
 returns all of the output <code>PCollection</code>s (including the main output) bundled
@@ -1889,7 +1889,8 @@ types across different programming-language APIs.</p><p>A <code>PCollection</cod
 Schema rows; Beam uses a special coder to encode schema types.</p><h3 id=schemas-for-pl-types>6.2. Schemas for programming language types</h3><p>While schemas themselves are language independent, they are designed to embed naturally into the programming languages
 of the Beam SDK being used. This allows Beam users to continue using native types while reaping the advantage of
 having Beam understand their element schemas.</p><p class=language-java>In Java you could use the following set of classes to represent the purchase schema. Beam will automatically
-infer the correct schema based on the members of the class.</p><p class=language-py>In Python you can use the following set of classes to represent the purchase schema. Beam will automatically infer the correct schema based on the members of the class.</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre  [...]
+infer the correct schema based on the members of the class.</p><p class=language-py>In Python you can use the following set of classes to represent the purchase schema. Beam will automatically infer the correct schema based on the members of the class.</p><p class=language-go>In Go, schema encoding is used by default for struct types, with Exported fields becoming part of the schema.
+Beam will automatically infer the schema based on the fields and field tags of the struct, and their order.</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=nd>@DefaultSchema</span><span class=o>(</span><span class=n>JavaBeanSchema</spa [...]
 <span class=kd>public</span> <span class=kd>class</span> <span class=nc>Purchase</span> <span class=o>{</span>
   <span class=kd>public</span> <span class=n>String</span> <span class=nf>getUserId</span><span class=o>();</span>  <span class=c1>// Returns the id of the user who made the purchase.
 </span><span class=c1></span>  <span class=kd>public</span> <span class=kt>long</span> <span class=nf>getItemId</span><span class=o>();</span>  <span class=c1>// Returns the identifier of the item that was purchased.
@@ -1946,7 +1947,33 @@ infer the correct schema based on the members of the class.</p><p class=language
 
 <span class=k>class</span> <span class=nc>Transaction</span><span class=p>(</span><span class=n>typing</span><span class=o>.</span><span class=n>NamedTuple</span><span class=p>):</span>
   <span class=n>bank</span><span class=p>:</span> <span class=nb>str</span>
-  <span class=n>purchase_amount</span><span class=p>:</span> <span class=nb>float</span></code></pre></div></div></div><p class=language-java>Using JavaBean classes as above is one way to map a schema to Java classes. However multiple Java classes might have
+  <span class=n>purchase_amount</span><span class=p>:</span> <span class=nb>float</span></code></pre></div></div></div><div class="language-go snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-go data-lang=go><span class=kd>type</span> <span class=nx>Purchase</span> <span class=kd>struct</span> <s [...]
+	<span class=c1>// ID of the user who made the purchase.
+</span><span class=c1></span>	<span class=nx>UserID</span> <span class=kt>string</span> <span class=s>`beam:&#34;userId&#34;`</span>
+	<span class=c1>// Identifier of the item that was purchased.
+</span><span class=c1></span>	<span class=nx>ItemID</span> <span class=kt>int64</span> <span class=s>`beam:&#34;itemId&#34;`</span>
+	<span class=c1>// The shipping address, a nested type.
+</span><span class=c1></span>	<span class=nx>ShippingAddress</span> <span class=nx>ShippingAddress</span> <span class=s>`beam:&#34;shippingAddress&#34;`</span>
+	<span class=c1>// The cost of the item in cents.
+</span><span class=c1></span>	<span class=nx>Cost</span> <span class=kt>int64</span> <span class=s>`beam:&#34;cost&#34;`</span>
+	<span class=c1>// The transactions that paid for this purchase.
+</span><span class=c1></span>	<span class=c1>// A slice since the purchase might be spread out over multiple
+</span><span class=c1></span>	<span class=c1>// credit cards.
+</span><span class=c1></span>	<span class=nx>Transactions</span> <span class=p>[]</span><span class=nx>Transaction</span> <span class=s>`beam:&#34;transactions&#34;`</span>
+<span class=p>}</span>
+
+<span class=kd>type</span> <span class=nx>ShippingAddress</span> <span class=kd>struct</span> <span class=p>{</span>
+	<span class=nx>StreetAddress</span> <span class=kt>string</span>  <span class=s>`beam:&#34;streetAddress&#34;`</span>
+	<span class=nx>City</span>          <span class=kt>string</span>  <span class=s>`beam:&#34;city&#34;`</span>
+	<span class=nx>State</span>         <span class=o>*</span><span class=kt>string</span> <span class=s>`beam:&#34;state&#34;`</span>
+	<span class=nx>Country</span>       <span class=kt>string</span>  <span class=s>`beam:&#34;country&#34;`</span>
+	<span class=nx>PostCode</span>      <span class=kt>string</span>  <span class=s>`beam:&#34;postCode&#34;`</span>
+<span class=p>}</span>
+
+<span class=kd>type</span> <span class=nx>Transaction</span> <span class=kd>struct</span> <span class=p>{</span>
+	<span class=nx>Bank</span>           <span class=kt>string</span>  <span class=s>`beam:&#34;bank&#34;`</span>
+	<span class=nx>PurchaseAmount</span> <span class=kt>float64</span> <span class=s>`beam:&#34;purchaseAmount&#34;`</span>
+<span class=p>}</span></code></pre></div></div></div><p class=language-java>Using JavaBean classes as above is one way to map a schema to Java classes. However multiple Java classes might have
 the same schema, in which case the different Java types can often be used interchangeably. Beam will add implicit
 conversions between types that have matching schemas. For example, the above
 <code>Transaction</code> class has the same schema as the following class:</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=nd>@DefaultSchema</span><span class=o>(</span><span class=n>JavaFieldSchema</span><span class=o>.</span><span cl [...]
@@ -1985,7 +2012,9 @@ type to represent nanosecond timestamps is represented as a schema containing an
 alone does not say anything about how to interpret this type, however the logical type tells you that this represents
 a nanosecond timestamp, with the INT64 field representing seconds and the INT32 field representing nanoseconds.</p><p>Logical types are also specified by an argument, which allows creating a class of related types. For example, a
 limited-precision decimal type would have an integer argument indicating how many digits of precision are represented.
-The argument is represented by a schema type, so can itself be a complex type.</p><p class=language-java>In Java, a logical type is specified as a subclass of the <code>LogicalType</code> class. A custom Java class can be specified to represent the logical type and conversion functions must be supplied to convert back and forth between this Java class and the underlying Schema type representation. For example, the logical type representing nanosecond timestamp might be implemented as fol [...]
+The argument is represented by a schema type, so can itself be a complex type.</p><p class=language-java>In Java, a logical type is specified as a subclass of the <code>LogicalType</code> class. A custom Java class can be specified to represent the logical type and conversion functions must be supplied to convert back and forth between this Java class and the underlying Schema type representation. For example, the logical type representing nanosecond timestamp might be implemented as fol [...]
+For example, the logical type provider representing nanosecond timestamps
+might be implemented as follows</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=c1>// A Logical type using java.time.Instant to represent the logical type.
 </span><span class=c1></span><span class=kd>public</span> <span class=kd>class</span> <span class=nc>TimestampNanos</span> <span class=kd>implements</span> <span class=n>LogicalType</span><span class=o>&lt;</span><span class=n>Instant</span><span class=o>,</span> <span class=n>Row</span><span class=o>&gt;</span> <span class=o>{</span>
   <span class=c1>// The underlying schema used to represent rows.
 </span><span class=c1></span>  <span class=kd>private</span> <span class=kd>final</span> <span class=n>Schema</span> <span class=n>SCHEMA</span> <span class=o>=</span> <span class=n>Schema</span><span class=o>.</span><span class=na>builder</span><span class=o>().</span><span class=na>addInt64Field</span><span class=o>(</span><span class=s>&#34;seconds&#34;</span><span class=o>).</span><span class=na>addInt32Field</span><span class=o>(</span><span class=s>&#34;nanos&#34;</span><span class [...]
@@ -2003,20 +2032,101 @@ The argument is represented by a schema type, so can itself be a complex type.</
   <span class=o>}</span>
 
      <span class=o>...</span>
-<span class=o>}</span></code></pre></div></div></div><h4 id=built-in-logical-types>6.4.2. Useful logical types</h4><h5 id=enumerationtype><strong>EnumerationType</strong></h5><p>This logical type allows creating an enumeration type consisting of a set of named constants.</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div cl [...]
+<span class=o>}</span></code></pre></div></div></div><div class="language-go snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-go data-lang=go><span class=c1>// Define a logical provider like so:
+</span><span class=c1></span>
+
+<span class=c1>// TimestampNanos is a logical type using time.Time, but
+</span><span class=c1>// encodes as a schema type.
+</span><span class=c1></span><span class=kd>type</span> <span class=nx>TimestampNanos</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Time</span>
+
+<span class=kd>func</span> <span class=p>(</span><span class=nx>tn</span> <span class=nx>TimestampNanos</span><span class=p>)</span> <span class=nf>Seconds</span><span class=p>()</span> <span class=kt>int64</span> <span class=p>{</span>
+	<span class=k>return</span> <span class=nx>time</span><span class=p>.</span><span class=nf>Time</span><span class=p>(</span><span class=nx>tn</span><span class=p>).</span><span class=nf>Unix</span><span class=p>()</span>
+<span class=p>}</span>
+<span class=kd>func</span> <span class=p>(</span><span class=nx>tn</span> <span class=nx>TimestampNanos</span><span class=p>)</span> <span class=nf>Nanos</span><span class=p>()</span> <span class=kt>int32</span> <span class=p>{</span>
+	<span class=k>return</span> <span class=nb>int32</span><span class=p>(</span><span class=nx>time</span><span class=p>.</span><span class=nf>Time</span><span class=p>(</span><span class=nx>tn</span><span class=p>).</span><span class=nf>UnixNano</span><span class=p>()</span> <span class=o>%</span> <span class=mi>1000000000</span><span class=p>)</span>
+<span class=p>}</span>
+
+<span class=c1>// tnStorage is the storage schema for TimestampNanos.
+</span><span class=c1></span><span class=kd>type</span> <span class=nx>tnStorage</span> <span class=kd>struct</span> <span class=p>{</span>
+	<span class=nx>Seconds</span> <span class=kt>int64</span> <span class=s>`beam:&#34;seconds&#34;`</span>
+	<span class=nx>Nanos</span>   <span class=kt>int32</span> <span class=s>`beam:&#34;nanos&#34;`</span>
+<span class=p>}</span>
+
+<span class=kd>var</span> <span class=p>(</span>
+	<span class=c1>// reflect.Type of the Value type of TimestampNanos
+</span><span class=c1></span>	<span class=nx>tnType</span>        <span class=p>=</span> <span class=nx>reflect</span><span class=p>.</span><span class=nf>TypeOf</span><span class=p>((</span><span class=o>*</span><span class=nx>TimestampNanos</span><span class=p>)(</span><span class=kc>nil</span><span class=p>)).</span><span class=nf>Elem</span><span class=p>()</span>
+	<span class=nx>tnStorageType</span> <span class=p>=</span> <span class=nx>reflect</span><span class=p>.</span><span class=nf>TypeOf</span><span class=p>((</span><span class=o>*</span><span class=nx>tnStorage</span><span class=p>)(</span><span class=kc>nil</span><span class=p>)).</span><span class=nf>Elem</span><span class=p>()</span>
+<span class=p>)</span>
+
+<span class=c1>// TimestampNanosProvider implements the beam.SchemaProvider interface.
+</span><span class=c1></span><span class=kd>type</span> <span class=nx>TimestampNanosProvider</span> <span class=kd>struct</span><span class=p>{}</span>
+
+<span class=c1>// FromLogicalType converts checks if the given type is TimestampNanos, and if so
+</span><span class=c1>// returns the storage type.
+</span><span class=c1></span><span class=kd>func</span> <span class=p>(</span><span class=nx>p</span> <span class=o>*</span><span class=nx>TimestampNanosProvider</span><span class=p>)</span> <span class=nf>FromLogicalType</span><span class=p>(</span><span class=nx>rt</span> <span class=nx>reflect</span><span class=p>.</span><span class=nx>Type</span><span class=p>)</span> <span class=p>(</span><span class=nx>reflect</span><span class=p>.</span><span class=nx>Type</span><span class=p>,</s [...]
+	<span class=k>if</span> <span class=nx>rt</span> <span class=o>!=</span> <span class=nx>tnType</span> <span class=p>{</span>
+		<span class=k>return</span> <span class=kc>nil</span><span class=p>,</span> <span class=nx>fmt</span><span class=p>.</span><span class=nf>Errorf</span><span class=p>(</span><span class=s>&#34;unable to provide schema.LogicalType for type %v, want %v&#34;</span><span class=p>,</span> <span class=nx>rt</span><span class=p>,</span> <span class=nx>tnType</span><span class=p>)</span>
+	<span class=p>}</span>
+	<span class=k>return</span> <span class=nx>tnStorageType</span><span class=p>,</span> <span class=kc>nil</span>
+<span class=p>}</span>
+
+<span class=c1>// BuildEncoder builds a Beam schema encoder for the TimestampNanos type.
+</span><span class=c1></span><span class=kd>func</span> <span class=p>(</span><span class=nx>p</span> <span class=o>*</span><span class=nx>TimestampNanosProvider</span><span class=p>)</span> <span class=nf>BuildEncoder</span><span class=p>(</span><span class=nx>rt</span> <span class=nx>reflect</span><span class=p>.</span><span class=nx>Type</span><span class=p>)</span> <span class=p>(</span><span class=kd>func</span><span class=p>(</span><span class=kd>interface</span><span class=p>{},</ [...]
+	<span class=k>if</span> <span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>p</span><span class=p>.</span><span class=nf>FromLogicalType</span><span class=p>(</span><span class=nx>rt</span><span class=p>);</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
+		<span class=k>return</span> <span class=kc>nil</span><span class=p>,</span> <span class=nx>err</span>
+	<span class=p>}</span>
+	<span class=nx>enc</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>coder</span><span class=p>.</span><span class=nf>RowEncoderForStruct</span><span class=p>(</span><span class=nx>tnStorageType</span><span class=p>)</span>
+	<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
+		<span class=k>return</span> <span class=kc>nil</span><span class=p>,</span> <span class=nx>err</span>
+	<span class=p>}</span>
+	<span class=k>return</span> <span class=kd>func</span><span class=p>(</span><span class=nx>iface</span> <span class=kd>interface</span><span class=p>{},</span> <span class=nx>w</span> <span class=nx>io</span><span class=p>.</span><span class=nx>Writer</span><span class=p>)</span> <span class=kt>error</span> <span class=p>{</span>
+		<span class=nx>v</span> <span class=o>:=</span> <span class=nx>iface</span><span class=p>.(</span><span class=nx>TimestampNanos</span><span class=p>)</span>
+		<span class=k>return</span> <span class=nf>enc</span><span class=p>(</span><span class=nx>tnStorage</span><span class=p>{</span>
+			<span class=nx>Seconds</span><span class=p>:</span> <span class=nx>v</span><span class=p>.</span><span class=nf>Seconds</span><span class=p>(),</span>
+			<span class=nx>Nanos</span><span class=p>:</span>   <span class=nx>v</span><span class=p>.</span><span class=nf>Nanos</span><span class=p>(),</span>
+		<span class=p>},</span> <span class=nx>w</span><span class=p>)</span>
+	<span class=p>},</span> <span class=kc>nil</span>
+<span class=p>}</span>
+
+<span class=c1>// BuildDecoder builds a Beam schema decoder for the TimestampNanos type.
+</span><span class=c1></span><span class=kd>func</span> <span class=p>(</span><span class=nx>p</span> <span class=o>*</span><span class=nx>TimestampNanosProvider</span><span class=p>)</span> <span class=nf>BuildDecoder</span><span class=p>(</span><span class=nx>rt</span> <span class=nx>reflect</span><span class=p>.</span><span class=nx>Type</span><span class=p>)</span> <span class=p>(</span><span class=kd>func</span><span class=p>(</span><span class=nx>io</span><span class=p>.</span><spa [...]
+	<span class=k>if</span> <span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>p</span><span class=p>.</span><span class=nf>FromLogicalType</span><span class=p>(</span><span class=nx>rt</span><span class=p>);</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
+		<span class=k>return</span> <span class=kc>nil</span><span class=p>,</span> <span class=nx>err</span>
+	<span class=p>}</span>
+	<span class=nx>dec</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>coder</span><span class=p>.</span><span class=nf>RowDecoderForStruct</span><span class=p>(</span><span class=nx>tnStorageType</span><span class=p>)</span>
+	<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
+		<span class=k>return</span> <span class=kc>nil</span><span class=p>,</span> <span class=nx>err</span>
+	<span class=p>}</span>
+	<span class=k>return</span> <span class=kd>func</span><span class=p>(</span><span class=nx>r</span> <span class=nx>io</span><span class=p>.</span><span class=nx>Reader</span><span class=p>)</span> <span class=p>(</span><span class=kd>interface</span><span class=p>{},</span> <span class=kt>error</span><span class=p>)</span> <span class=p>{</span>
+		<span class=nx>s</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nf>dec</span><span class=p>(</span><span class=nx>r</span><span class=p>)</span>
+		<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
+			<span class=k>return</span> <span class=kc>nil</span><span class=p>,</span> <span class=nx>err</span>
+		<span class=p>}</span>
+		<span class=nx>tn</span> <span class=o>:=</span> <span class=nx>s</span><span class=p>.(</span><span class=nx>tnStorage</span><span class=p>)</span>
+		<span class=k>return</span> <span class=nf>TimestampNanos</span><span class=p>(</span><span class=nx>time</span><span class=p>.</span><span class=nf>Unix</span><span class=p>(</span><span class=nx>tn</span><span class=p>.</span><span class=nx>Seconds</span><span class=p>,</span> <span class=nb>int64</span><span class=p>(</span><span class=nx>tn</span><span class=p>.</span><span class=nx>Nanos</span><span class=p>))),</span> <span class=kc>nil</span>
+	<span class=p>},</span> <span class=kc>nil</span>
+<span class=p>}</span>
+
+
+
+<span class=c1>// Register it like so:
+</span><span class=c1></span>
+<span class=nx>beam</span><span class=p>.</span><span class=nf>RegisterSchemaProvider</span><span class=p>(</span><span class=nx>tnType</span><span class=p>,</span> <span class=o>&amp;</span><span class=nx>TimestampNanosProvider</span><span class=p>{})</span></code></pre></div></div></div><h4 id=built-in-logical-types>6.4.2. Useful logical types</h4><p class=language-py>Currently the Python SDK provides minimal convenience logical types,
+other than to handle <code>MicrosInstant</code>.</p><p class=language-go>Currently the Go SDK provides minimal convenience logical types,
+other than to handle additional integer primitives, and <code>time.Time</code>.</p><h5 id=enumerationtype><strong>EnumerationType</strong></h5><p class=language-py>This convenience builder doesn&rsquo;t yet exist for the Python SDK.</p><p class=language-go>This convenience builder doesn&rsquo;t yet exist for the Go SDK.</p><p class=language-java>This logical type allows creating an enumeration type consisting of a set of named constants.</p><div class="language-java snippet"><div class=" [...]
                <span class=err>…</span>
      <span class=o>.</span><span class=na>addLogicalTypeField</span><span class=o>(</span><span class=s>&#34;color&#34;</span><span class=o>,</span> <span class=n>EnumerationType</span><span class=o>.</span><span class=na>create</span><span class=o>(</span><span class=s>&#34;RED&#34;</span><span class=o>,</span> <span class=s>&#34;GREEN&#34;</span><span class=o>,</span> <span class=s>&#34;BLUE&#34;</span><span class=o>))</span>
-     <span class=o>.</span><span class=na>build</span><span class=o>();</span></code></pre></div></div></div><p>The value of this field is stored in the row as an INT32 type, however the logical type defines a value type that lets
+     <span class=o>.</span><span class=na>build</span><span class=o>();</span></code></pre></div></div></div><p class=language-java>The value of this field is stored in the row as an INT32 type, however the logical type defines a value type that lets
 you access the enumeration either as a string or a value. For example:</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=n>EnumerationType</span><span class=o>.</span><span class=na>Value</span> <span class=n>enumValue</span> <span class [...]
 <span class=n>enumValue</span><span class=o>.</span><span class=na>getValue</span><span class=o>();</span>  <span class=c1>// Returns 0, the integer value of the constant.
-</span><span class=c1></span><span class=n>enumValue</span><span class=o>.</span><span class=na>toString</span><span class=o>();</span>  <span class=o>//</span> <span class=n>Returns</span> <span class=s>&#34;RED&#34;</span><span class=o>,</span> <span class=n>the</span> <span class=n>string</span> <span class=n>value</span> <span class=n>of</span> <span class=n>the</span> <span class=n>constant</span></code></pre></div></div></div><p>Given a row object with an enumeration field, you can [...]
-types.</p><h5 id=oneoftype><strong>OneOfType</strong></h5><p>OneOfType allows creating a disjoint union type over a set of schema fields. For example:</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=n>Schema</span> <span class=n>schema [...]
+</span><span class=c1></span><span class=n>enumValue</span><span class=o>.</span><span class=na>toString</span><span class=o>();</span>  <span class=o>//</span> <span class=n>Returns</span> <span class=s>&#34;RED&#34;</span><span class=o>,</span> <span class=n>the</span> <span class=n>string</span> <span class=n>value</span> <span class=n>of</span> <span class=n>the</span> <span class=n>constant</span></code></pre></div></div></div><p class=language-java>Given a row object with an enumer [...]
+types.</p><h5 id=oneoftype><strong>OneOfType</strong></h5><p class=language-py>This convenience builder doesn&rsquo;t yet exist for the Python SDK.</p><p class=language-go>This convenience builder doesn&rsquo;t yet exist for the Go SDK.</p><p class=language-java>OneOfType allows creating a disjoint union type over a set of schema fields. For example:</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-plac [...]
                <span class=err>…</span>
      <span class=o>.</span><span class=na>addLogicalTypeField</span><span class=o>(</span><span class=s>&#34;oneOfField&#34;</span><span class=o>,</span>
         <span class=n>OneOfType</span><span class=o>.</span><span class=na>create</span><span class=o>(</span><span class=n>Field</span><span class=o>.</span><span class=na>of</span><span class=o>(</span><span class=s>&#34;intField&#34;</span><span class=o>,</span> <span class=n>FieldType</span><span class=o>.</span><span class=na>INT32</span><span class=o>),</span>
                          <span class=n>Field</span><span class=o>.</span><span class=na>of</span><span class=o>(</span><span class=s>&#34;stringField&#34;</span><span class=o>,</span> <span class=n>FieldType</span><span class=o>.</span><span class=na>STRING</span><span class=o>),</span>
                          <span class=n>Field</span><span class=o>.</span><span class=na>of</span><span class=o>(</span><span class=s>&#34;bytesField&#34;</span><span class=o>,</span> <span class=n>FieldType</span><span class=o>.</span><span class=na>BYTES</span><span class=o>)))</span>
-      <span class=o>.</span><span class=na>build</span><span class=o>();</span></code></pre></div></div></div><p>The value of this field is stored in the row as another Row type, where all the fields are marked as nullable. The
+      <span class=o>.</span><span class=na>build</span><span class=o>();</span></code></pre></div></div></div><p class=language-java>The value of this field is stored in the row as another Row type, where all the fields are marked as nullable. The
 logical type however defines a Value object that contains an enumeration value indicating which field was set and allows
 getting just that field:</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=c1>// Returns an enumeration indicating all possible case values for the enum.
 </span><span class=c1>// For the above example, this will be
@@ -2034,8 +2144,15 @@ getting just that field:</p><div class="language-java snippet"><div class="noteb
     <span class=k>return</span> <span class=n>processString</span><span class=o>(</span><span class=n>oneOfValue</span><span class=o>.</span><span class=na>getValue</span><span class=o>(</span><span class=n>String</span><span class=o>.</span><span class=na>class</span><span class=o>));</span>
   <span class=k>case</span> <span class=s>&#34;bytesField&#34;</span><span class=o>:</span>
     <span class=k>return</span> <span class=n>processBytes</span><span class=o>(</span><span class=n>oneOfValue</span><span class=o>.</span><span class=na>getValue</span><span class=o>(</span><span class=n>bytes</span><span class=o>[].</span><span class=na>class</span><span class=o>));</span>
-<span class=o>}</span></code></pre></div></div></div><p>In the above example we used the field names in the switch statement for clarity, however the enum integer values could
-also be used.</p><h3 id=creating-schemas>6.5. Creating Schemas</h3><p>In order to take advantage of schemas, your <code>PCollection</code>s must have a schema attached to it. Often, the source itself will attach a schema to the PCollection. For example, when using <code>AvroIO</code> to read Avro files, the source can automatically infer a Beam schema from the Avro schema and attach that to the Beam <code>PCollection</code>. However not all sources produce schemas. In addition, often Bea [...]
+<span class=o>}</span></code></pre></div></div></div><p class=language-java>In the above example we used the field names in the switch statement for clarity, however the enum integer values could
+also be used.</p><h3 id=creating-schemas>6.5. Creating Schemas</h3><p>In order to take advantage of schemas, your <code>PCollection</code>s must have a schema attached to it.
+Often, the source itself will attach a schema to the PCollection.
+For example, when using <code>AvroIO</code> to read Avro files, the source can automatically infer a Beam schema from the Avro schema and attach that to the Beam <code>PCollection</code>.
+However not all sources produce schemas.
+In addition, often Beam pipelines have intermediate stages and types, and those also can benefit from the expressiveness of schemas.</p><h4 id=inferring-schemas>6.5.1. Inferring schemas</h4><nav class=language-switcher><strong>Adapt for:</strong><ul><li data-type=language-java class=active>Java SDK</li><li data-type=language-py>Python SDK</li><li data-type=language-go>Go SDK</li></ul></nav><p class=language-java>Beam is able to infer schemas from a variety of common Java types.
+The <code>@DefaultSchema</code> annotation can be used to tell Beam to infer schemas from a specific type.
+The annotation takes a <code>SchemaProvider</code> as an argument, and <code>SchemaProvider</code> classes are already built in for common Java types.
+The <code>SchemaRegistry</code> can also be invoked programmatically for cases where it is not practical to annotate the Java type itself.</p><p class=language-java><strong>Java POJOs</strong></p><p class=language-java>A POJO (Plain Old Java Object) is a Java object that is not bound by any restriction other than the Java Language
 Specification. A POJO can contain member variables that are primitives, that are other POJOs, or are collections maps or
 arrays thereof. POJOs do not have to extend prespecified classes or extend any specific interfaces.</p><p class=language-java>If a POJO class is annotated with <code>@DefaultSchema(JavaFieldSchema.class)</code>, Beam will automatically infer a schema for
 this class. Nested classes are supported as are classes with <code>List</code>, array, and <code>Map</code> fields.</p><p class=language-java>For example, annotating the following class tells Beam to infer a schema from this POJO class and apply it to any
@@ -2106,9 +2223,25 @@ type information. If it&rsquo;s unable to it will fall back to the generic type
 <code>Any</code>. Sometimes this is not ideal, you can use casts to make sure Beam
 correctly infers types with <code>beam.Row</code> or with <code>Select</code>:</p><div class="language-py snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-py data-lang=py><span class=n>input_pc</span> <span class=o>=</span> <span class=o>...</span> <span class=c1># {&#34;bank&#34;: ..., &#34;purc [...]
 <span class=n>output_pc</span> <span class=o>=</span> <span class=n>input_pc</span> <span class=o>|</span> <span class=n>beam</span><span class=o>.</span><span class=n>Map</span><span class=p>(</span><span class=k>lambda</span> <span class=n>item</span><span class=p>:</span> <span class=n>beam</span><span class=o>.</span><span class=n>Row</span><span class=p>(</span><span class=n>bank</span><span class=o>=</span><span class=nb>str</span><span class=p>(</span><span class=n>item</span><spa [...]
-                                                      <span class=n>purchase_amount</span><span class=o>=</span><span class=nb>float</span><span class=p>(</span><span class=n>item</span><span class=p>[</span><span class=s2>&#34;purchase_amount&#34;</span><span class=p>])))</span></code></pre></div></div></div><h3 id=using-schemas>6.6. Using Schema Transforms</h3><p>A schema on a <code>PCollection</code> enables a rich variety of relational transforms. The fact that each record is composed of
+                                                      <span class=n>purchase_amount</span><span class=o>=</span><span class=nb>float</span><span class=p>(</span><span class=n>item</span><span class=p>[</span><span class=s2>&#34;purchase_amount&#34;</span><span class=p>])))</span></code></pre></div></div></div><p class=language-go>Beam currently only infers schemas for exported fields in Go structs.</p><p class=language-go><strong>Structs</strong></p><p class=language-go>Beam will automat [...]
+as PCollection elements, and default to encoding them using
+schema encoding.</p><div class="language-go snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-go data-lang=go><span class=kd>type</span> <span class=nx>Transaction</span> <span class=kd>struct</span><span class=p>{</span>
+  <span class=nx>Bank</span> <span class=kt>string</span>
+  <span class=nx>PurchaseAmount</span> <span class=kt>float64</span>
+
+  <span class=nx>checksum</span> <span class=p>[]</span><span class=kt>byte</span> <span class=c1>// ignored
+</span><span class=c1></span><span class=p>}</span></code></pre></div></div></div><p class=language-go>Unexported fields are ignored, and cannot be automatically infered as part of the schema.
+Fields of type func, channel, unsafe.Pointer, or uintptr will be ignored by inference.
+Fields of interface types are ignored, unless a schema provider
+is registered for them.</p><p class=language-go>By default, schema field names will match the exported struct field names.
+In the above example, &ldquo;Bank&rdquo; and &ldquo;PurchaseAmount&rdquo; are the schema field names.
+A schema field name can be overridden with a struct tag for the field.</p><div class="language-go snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-go data-lang=go><span class=kd>type</span> <span class=nx>Transaction</span> <span class=kd>struct</span><span class=p>{</span>
+  <span class=nx>Bank</span>           <span class=kt>string</span>  <span class=s>`beam:&#34;bank&#34;`</span>
+  <span class=nx>PurchaseAmount</span> <span class=kt>float64</span> <span class=s>`beam:&#34;purchase_amount&#34;`</span>
+<span class=p>}</span></code></pre></div></div></div><p class=language-go>Overriding schema field names is useful for compatibility cross language transforms,
+as schema fields may have different requirements or restrictions from Go exported fields.</p><h3 id=using-schemas>6.6. Using Schema Transforms</h3><p>A schema on a <code>PCollection</code> enables a rich variety of relational transforms. The fact that each record is composed of
 named fields allows for simple and readable aggregations that reference fields by name, similar to the aggregations in
-a SQL expression.</p><h4 id=661-field-selection-syntax>6.6.1. Field selection syntax</h4><p>The advantage of schemas is that they allow referencing of element fields by name. Beam provides a selection syntax for
+a SQL expression.</p><p class=language-go>Beam does not yet support Schema transforms natively in Go. However, it will be implemented with the following behavior.</p><h4 id=661-field-selection-syntax>6.6.1. Field selection syntax</h4><p>The advantage of schemas is that they allow referencing of element fields by name. Beam provides a selection syntax for
 referencing fields, including nested and repeated fields. This syntax is used by all of the schema transforms when
 referencing the fields they operate on. The syntax can also be used inside of a DoFn to specify which schema fields to
 process.</p><p>Addressing fields by name still retains type safety as Beam will check that schemas match at the time the pipeline graph
@@ -2198,7 +2331,7 @@ follows.</p><div class="language-java snippet"><div class="notebook-skip code-sn
 unboxing the row. For example, give a schema with a single INT64 field, the following will convert it to a
 <code>PCollection&lt;Long></code></p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=n>PCollection</span><span class=o>&lt;</span><span class=n>Long</span><span class=o>&gt;</span> <span class=n>longs</span> <span class=o>=</span> <span c [...]
 pipeline will fail to launch.</p><h4 id=663-schemas-in-pardo>6.6.3. Schemas in ParDo</h4><p>A <code>PCollection</code> with a schema can apply a <code>ParDo</code>, just like any other <code>PCollection</code>. However the Beam runner is aware
-of schemas when applying a <code>ParDo</code>, which enables additional functionality.</p><h5 id=input-conversion><strong>Input conversion</strong></h5><p>Since Beam knows the schema of the source <code>PCollection</code>, it can automatically convert the elements to any Java type for
+of schemas when applying a <code>ParDo</code>, which enables additional functionality.</p><h5 id=input-conversion><strong>Input conversion</strong></h5><p class=language-go>Beam does not yet support input conversion in Go.</p><p>Since Beam knows the schema of the source <code>PCollection</code>, it can automatically convert the elements to any Java type for
 which a matching schema is known. For example, using the above-mentioned Transaction schema, say we have the following
 <code>PCollection</code>:</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=n>PCollection</span><span class=o>&lt;</span><span class=n>PurchasePojo</span><span class=o>&gt;</span> <span class=n>purchases</span> <span class=o>=</span> <sp [...]
 since there is a schema, you could apply the following DoFn:</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=n>purchases</span><span class=o>.</span><span class=na>appy</span><span class=o>(</span><span class=n>ParDo</span><span class= [...]
@@ -2223,7 +2356,7 @@ using the above-described selection expressions, as follows:</p><div class="lang
       <span class=o>...</span>
   <span class=o>}</span>
 <span class=o>}));</span></code></pre></div></div></div><p>For more information, see the section on field-selection expressions. When selecting subschemas, Beam will
-automatically convert to any matching schema type, just like when reading the entire row.</p><h2 id=data-encoding-and-type-safety>7. Data encoding and type safety</h2><p>When Beam runners execute your pipeline, they often need to materialize the
+automatically convert to any matching schema type, just like when reading the entire row.</p><h2 id=data-encoding-and-type-safety>7. Data encoding and type safety</h2><nav class=language-switcher><strong>Adapt for:</strong><ul><li data-type=language-java class=active>Java SDK</li><li data-type=language-py>Python SDK</li><li data-type=language-go>Go SDK</li></ul></nav><p>When Beam runners execute your pipeline, they often need to materialize the
 intermediate data in your <code>PCollection</code>s, which requires converting elements to
 and from byte strings. The Beam SDKs use objects called <code>Coder</code>s to describe how
 the elements of a given <code>PCollection</code> may be encoded and decoded.</p><blockquote><p>Note that coders are unrelated to parsing or formatting data when interacting
@@ -2239,6 +2372,11 @@ subclasses that work with a variety of standard Python types, such as primitive
 types, Tuple, Iterable, StringUtf8 and more. You can find all of the available
 Coder subclasses in the
 <a href=https://github.com/apache/beam/tree/master/sdks/python/apache_beam/coders>apache_beam.coders</a>
+package.</p><p class=language-go>Standard Go types like <code>int</code>, <code>int64</code> <code>float64</code>, <code>[]byte</code>, and <code>string</code> and more are coded using builtin coders.
+Structs and pointers to structs default using Beam Schema Row encoding.
+However, users can build and register custom coders with <code>beam.RegisterCoder</code>.
+You can find available Coder functions in the
+<a href=https://pkg.go.dev/github.com/apache/beam/sdks/v2/go/pkg/beam/core/graph/coders>coder</a>
 package.</p><blockquote><p>Note that coders do not necessarily have a 1:1 relationship with types. For
 example, the Integer type can have multiple valid coders, and input and output
 data can use different Integer coders. A transform might have Integer-typed
@@ -2256,7 +2394,8 @@ not been set and cannot be inferred for the given <code>PCollection</code>.</p><
 mapping of Java types to the default coders that the pipeline should use for
 <code>PCollection</code>s of each type.</p><p class=language-py>The Beam SDK for Python has a <code>CoderRegistry</code> that represents a mapping of
 Python types to the default coder that should be used for <code>PCollection</code>s of each
-type.</p><p class=language-java>By default, the Beam SDK for Java automatically infers the <code>Coder</code> for the
+type.</p><p class=language-go>The Beam SDK for Go allows users to register default coder
+implementations with <code>beam.RegisterCoder</code>.</p><p class=language-java>By default, the Beam SDK for Java automatically infers the <code>Coder</code> for the
 elements of a <code>PCollection</code> produced by a <code>PTransform</code> using the type parameter
 from the transform&rsquo;s function object, such as <code>DoFn</code>. In the case of <code>ParDo</code>,
 for example, a <code>DoFn&lt;Integer, String></code> function object accepts an input element
@@ -2270,11 +2409,15 @@ with the typehints <code>@beam.typehints.with_input_types(int)</code> and
 <code>@beam.typehints.with_output_types(str)</code> accepts an input element of type int
 and produces an output element of type str. In such a case, the Beam SDK for
 Python will automatically infer the default <code>Coder</code> for the output <code>PCollection</code>
-(in the default pipeline <code>CoderRegistry</code>, this is <code>BytesCoder</code>).</p><blockquote><p>NOTE: If you create your <code>PCollection</code> from in-memory data by using the
+(in the default pipeline <code>CoderRegistry</code>, this is <code>BytesCoder</code>).</p><p class=language-go>By default, the Beam SDK for Go automatically infers the <code>Coder</code> for the elements of an output <code>PCollection</code> by the output of the transform&rsquo;s function object, such as a <code>DoFn</code>.
+In the case of <code>ParDo</code>, for example a <code>DoFn</code>
+with the parameters of <code>v int, emit func(string)</code> accepts an input element of type <code>int</code>
+and produces an output element of type <code>string</code>.
+In such a case, the Beam SDK for Go will automatically infer the default <code>Coder</code> for the output <code>PCollection</code> to be the <code>string_utf8</code> coder.</p><span class=language-java><blockquote><p><strong>Note:</strong> If you create your <code>PCollection</code> from in-memory data by using the
 <code>Create</code> transform, you cannot rely on coder inference and default coders.
 <code>Create</code> does not have access to any typing information for its arguments, and
 may not be able to infer a coder if the argument list contains a value whose
-exact run-time class doesn&rsquo;t have a default coder registered.</p></blockquote><p class=language-java>When using <code>Create</code>, the simplest way to ensure that you have the correct coder
+exact run-time class doesn&rsquo;t have a default coder registered.</p></blockquote></span><p class=language-java>When using <code>Create</code>, the simplest way to ensure that you have the correct coder
 is by invoking <code>withCoder</code> when you apply the <code>Create</code> transform.</p><h3 id=default-coders-and-the-coderregistry>7.2. Default coders and the CoderRegistry</h3><p>Each Pipeline object has a <code>CoderRegistry</code> object, which maps language types to
 the default coder the pipeline should use for those types. You can use the
 <code>CoderRegistry</code> yourself to look up the default coder for a given type, or to
@@ -2289,7 +2432,7 @@ by using the method <code>Pipeline.getCoderRegistry</code>. This allows you to d
 this pipeline, verify that Integer values are encoded using
 <code>BigEndianIntegerCoder</code>.&rdquo;</p><p class=language-py>You can use the method <code>CoderRegistry.get_coder</code> to determine the default Coder
 for a Python type. You can use <code>coders.registry</code> to access the <code>CoderRegistry</code>.
-This allows you to determine (or set) the default Coder for a Python type.</p><h4 id=setting-default-coder>7.2.2. Setting the default coder for a type</h4><p>To set the default Coder for a
+This allows you to determine (or set) the default Coder for a Python type.</p><p class=language-go>You can use the <code>beam.NewCoder</code> function to determine the default Coder for a Go type.</p><h4 id=setting-default-coder>7.2.2. Setting the default coder for a type</h4><p class="language-java language-py">To set the default Coder for a
 <span class=language-java>Java</span><span class=language-py>Python</span>
 type for a particular pipeline, you obtain and modify the pipeline&rsquo;s
 <code>CoderRegistry</code>. You use the method
@@ -2298,21 +2441,34 @@ type for a particular pipeline, you obtain and modify the pipeline&rsquo;s
 to get the <code>CoderRegistry</code> object, and then use the method
 <span class=language-java><code>CoderRegistry.registerCoder</code></span>
 <span class=language-py><code>CoderRegistry.register_coder</code></span>
-to register a new <code>Coder</code> for the target type.</p><p>The following example code demonstrates how to set a default Coder, in this case
+to register a new <code>Coder</code> for the target type.</p><p class=language-go>To set the default Coder for a Go type you use the function <code>beam.RegisterCoder</code> to register a encoder and decoder functions for the target type.
+However, built in types like <code>int</code>, <code>string</code>, <code>float64</code>, etc cannot have their coders overridde.</p><p class="language-java language-py">The following example code demonstrates how to set a default Coder, in this case
 <code>BigEndianIntegerCoder</code>, for
 <span class=language-java>Integer</span><span class=language-py>int</span>
-values for a pipeline.</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=n>PipelineOptions</span> <span class=n>options</span> <span class=o>=</span> <span class=n>PipelineOptionsFactory</span><span class=o>.</span><span class=na>create< [...]
+values for a pipeline.</p><p class=language-go>The following example code demonstrates how to set a custom Coder for <code>MyCustomType</code> elements.</p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=n>PipelineOptions</span> <span cla [...]
 <span class=n>Pipeline</span> <span class=n>p</span> <span class=o>=</span> <span class=n>Pipeline</span><span class=o>.</span><span class=na>create</span><span class=o>(</span><span class=n>options</span><span class=o>);</span>
 
 <span class=n>CoderRegistry</span> <span class=n>cr</span> <span class=o>=</span> <span class=n>p</span><span class=o>.</span><span class=na>getCoderRegistry</span><span class=o>();</span>
-<span class=n>cr</span><span class=o>.</span><span class=na>registerCoder</span><span class=o>(</span><span class=n>Integer</span><span class=o>.</span><span class=na>class</span><span class=o>,</span> <span class=n>BigEndianIntegerCoder</span><span class=o>.</span><span class=na>class</span><span class=o>);</span></code></pre></div></div></div><div class="language-py snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=botto [...]
+<span class=n>cr</span><span class=o>.</span><span class=na>registerCoder</span><span class=o>(</span><span class=n>Integer</span><span class=o>.</span><span class=na>class</span><span class=o>,</span> <span class=n>BigEndianIntegerCoder</span><span class=o>.</span><span class=na>class</span><span class=o>);</span></code></pre></div></div></div><div class="language-py snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=botto [...]
+  <span class=o>...</span>
+<span class=p>}</span>
+
+<span class=c1>// See documentation on beam.RegisterCoder for other supported coder forms.
+</span><span class=c1></span>
+<span class=kd>func</span> <span class=nf>encode</span><span class=p>(</span><span class=nx>MyCustomType</span><span class=p>)</span> <span class=p>[]</span><span class=kt>byte</span> <span class=p>{</span> <span class=o>...</span> <span class=p>}</span>
+
+<span class=kd>func</span> <span class=nf>decode</span><span class=p>(</span><span class=nx>b</span> <span class=p>[]</span><span class=kt>byte</span><span class=p>)</span> <span class=nx>MyCustomType</span> <span class=p>{</span> <span class=o>...</span> <span class=p>}</span>
+
+<span class=kd>func</span> <span class=nf>init</span><span class=p>()</span> <span class=p>{</span>
+  <span class=nx>beam</span><span class=p>.</span><span class=nf>RegisterCoder</span><span class=p>(</span><span class=nx>reflect</span><span class=p>.</span><span class=nf>TypeOf</span><span class=p>((</span><span class=o>*</span><span class=nx>MyCustomType</span><span class=p>)(</span><span class=kc>nil</span><span class=p>)).</span><span class=nf>Elem</span><span class=p>(),</span> <span class=nx>encode</span><span class=p>,</span> <span class=nx>decode</span><span class=p>)</span>
+<span class=p>}</span></code></pre></div></div></div><h4 id=annotating-custom-type-default-coder>7.2.3. Annotating a custom data type with a default coder</h4><span class=language-java><p>If your pipeline program defines a custom data type, you can use the
 <code>@DefaultCoder</code> annotation to specify the coder to use with that type.
 By default, Beam will use <code>SerializableCoder</code> which uses Java serialization,
 but it has drawbacks:</p><ol><li><p>It is inefficient in encoding size and speed.
 See this <a href=https://blog.softwaremill.com/the-best-serialization-strategy-for-event-sourcing-9321c299632b>comparison of Java serialization methods.</a></p></li><li><p>It is non-deterministic: it may produce different binary encodings for two
 equivalent objects.</p><p>For key/value pairs, the correctness of key-based operations
 (GroupByKey, Combine) and per-key State depends on having a deterministic
-coder for the key.</p></li></ol><p>You can use the <code>@DefaultCoder</code> annotation to set a new default as follows:</p></p><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=nd>@DefaultCoder</span><span class=o>(</span><span class=n>Av [...]
+coder for the key</p></li></ol><p>You can use the <code>@DefaultCoder</code> annotation to set a new default as follows:</p></span><div class="language-java snippet"><div class="notebook-skip code-snippet"><a class=copy type=button data-bs-toggle=tooltip data-bs-placement=bottom title="Copy to clipboard"><img src=/images/copy-icon.svg></a><div class=highlight><pre class=chroma><code class=language-java data-lang=java><span class=nd>@DefaultCoder</span><span class=o>(</span><span class=n> [...]
 <span class=kd>public</span> <span class=kd>class</span> <span class=nc>MyCustomDataType</span> <span class=o>{</span>
   <span class=o>...</span>
 <span class=o>}</span></code></pre></div></div></div><p class=language-java>If you&rsquo;ve created a custom coder to match your data type, and you want to use
@@ -2325,8 +2481,9 @@ the <code>@DefaultCoder</code> annotation, your coder class must implement a sta
 <span class=nd>@DefaultCoder</span><span class=o>(</span><span class=n>MyCustomCoder</span><span class=o>.</span><span class=na>class</span><span class=o>)</span>
 <span class=kd>public</span> <span class=kd>class</span> <span class=nc>MyCustomDataType</span> <span class=o>{</span>
   <span class=o>...</span>
-<span class=o>}</span></code></pre></div></div></div><p class=language-py>The Beam SDK for Python does not support annotating data types with a default
-coder. If you would like to set a default coder, use the method described in the
+<span class=o>}</span></code></pre></div></div></div><p class="language-py language-go">The Beam SDK for <span class=language-py>Python</span><span class=language-go>Go</span>
+does not support annotating data types with a default coder.
+If you would like to set a default coder, use the method described in the
 previous section, <em>Setting the default coder for a type</em>.</p><h2 id=windowing>8. Windowing</h2><p>Windowing subdivides a <code>PCollection</code> according to the timestamps of its
 individual elements. Transforms that aggregate multiple elements, such as
 <code>GroupByKey</code> and <code>Combine</code>, work implicitly on a per-window basis — they process
@@ -3974,7 +4131,7 @@ expansionAddr := &#34;localhost:8097&#34;
 outT := beam.UnnamedOutput(typex.New(reflectx.String))
 res := beam.CrossLanguage(s, urn, payload, expansionAddr, beam.UnnamedInput(inputPCol), outT)
    </code></pre></div></div></li><li><p>After the job has been submitted to the Beam runner, shutdown the expansion service by
-terminating the expansion service process.</p></li></ol><h3 id=x-lang-transform-runner-support>13.3. Runner Support</h3><p>Currently, portable runners such as Flink, Spark, and the Direct runner can be used with multi-language pipelines.</p><p>Google Cloud Dataflow supports multi-language pipelines through the Dataflow Runner v2 backend architecture.</p><div class=feedback><p class=update>Last updated on 2021/09/24</p><h3>Have you found everything you were looking for?</h3><p class=descr [...]
+terminating the expansion service process.</p></li></ol><h3 id=x-lang-transform-runner-support>13.3. Runner Support</h3><p>Currently, portable runners such as Flink, Spark, and the Direct runner can be used with multi-language pipelines.</p><p>Google Cloud Dataflow supports multi-language pipelines through the Dataflow Runner v2 backend architecture.</p><div class=feedback><p class=update>Last updated on 2021/10/01</p><h3>Have you found everything you were looking for?</h3><p class=descr [...]
 <a href=http://www.apache.org>The Apache Software Foundation</a>
 | <a href=/privacy_policy>Privacy Policy</a>
 | <a href=/feed.xml>RSS Feed</a><br><br>Apache Beam, Apache, Beam, the Beam logo, and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation. All other products or name brands are trademarks of their respective holders, including The Apache Software Foundation.</div></div></div></div></footer></body></html>
\ No newline at end of file
diff --git a/website/generated-content/sitemap.xml b/website/generated-content/sitemap.xml
index 265a3d4..980082e 100644
--- a/website/generated-content/sitemap.xml
+++ b/website/generated-content/sitemap.xml
@@ -1 +1 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"><url><loc>/blog/beam-2.32.0/</loc><lastmod>2021-09-16T12:21:14-07:00</lastmod></url><url><loc>/categories/blog/</loc><lastmod>2021-09-16T12:21:14-07:00</lastmod></url><url><loc>/blog/</loc><lastmod>2021-09-16T12:21:14-07:00</lastmod></url><url><loc>/categories/</loc><lastmod>2021-09-17T14:05:48-07:00</lastmod></url><url><loc>/blog/b [...]
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8" standalone="yes"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"><url><loc>/blog/beam-2.32.0/</loc><lastmod>2021-09-16T12:21:14-07:00</lastmod></url><url><loc>/categories/blog/</loc><lastmod>2021-09-16T12:21:14-07:00</lastmod></url><url><loc>/blog/</loc><lastmod>2021-09-16T12:21:14-07:00</lastmod></url><url><loc>/categories/</loc><lastmod>2021-09-17T14:05:48-07:00</lastmod></url><url><loc>/blog/b [...]
\ No newline at end of file