Files
moby/vendor/github.com/aws/smithy-go/AGENTS.md
Mend Renovate 20fba3eeb5 Update module github.com/aws/smithy-go to v1.27.5
Signed-off-by: Mend Renovate <bot@renovateapp.com>
2026-07-30 17:47:19 +00:00

6.6 KiB

AGENTS.md

Project overview

smithy-go is the Go code generator and runtime for Smithy. It has two major components:

  1. Codegen (codegen/) — A Smithy build plugin written in Java that generates Go client/server/shape code from Smithy models.
  2. Runtime (./, top-level Go module) — The Go packages that generated code depends on at runtime.

The primary downstream consumer is aws-sdk-go-v2.

Repository layout

.                               # Root Go module (github.com/aws/smithy-go)
├── auth/                       # Auth identity + scheme interfaces
│   └── bearer/                 # Bearer token auth
├── aws-http-auth/              # Separate module: AWS SigV4/SigV4A HTTP signing
├── codegen/                    # Java/Gradle: Smithy code generator
│   ├── smithy-go-codegen/      # Main codegen source (Java)
│   └── smithy-go-codegen-test/ # Codegen integration tests
├── container/                  # Generic container types
├── context/                    # Context helpers
├── document/                   # Smithy document type abstraction
│   └── json/                   # JSON document codec
├── encoding/                   # Wire format encoders/decoders
│   ├── cbor/                   # CBOR (used by rpcv2Cbor)
│   ├── httpbinding/            # HTTP binding serde helpers
│   ├── json/                   # JSON encoder/decoder
│   └── xml/                    # XML encoder/decoder
├── endpoints/                  # Endpoint resolution types
├── internal/                   # Internal utilities (singleflight, etc.)
├── io/                         # I/O helpers
├── logging/                    # Logging interfaces
├── metrics/                    # Metrics interfaces
│   └── smithyotelmetrics/      # Separate module: OpenTelemetry metrics adapter
├── middleware/                 # Middleware stack (the core of the operation pipeline)
├── ptr/                        # Pointer-to/from-value helpers
├── testing/                    # Test assertion helpers for generated protocol tests
│   └── xml/                    # XML comparison utilities
├── time/                       # Smithy timestamp format helpers
├── tracing/                    # Tracing interfaces
│   └── smithyoteltracing/      # Separate module: OpenTelemetry tracing adapter
└── transport/
    └── http/                   # HTTP request/response types and middleware

Building and testing

Runtime (Go)

# Run unit tests
make unit

Codegen (Java)

# Build and test codegen
cd codegen && ./gradlew build

# Publish to local Maven for downstream use
cd codegen && ./gradlew publishToMavenLocal

The codegen artifact version is published to Maven Central and bumped on each release. For local development against unreleased codegen changes, use publishToMavenLocal and point consumers at mavenLocal().

Runtime architecture

Middleware stack

The operation pipeline is built on a middleware stack defined in middleware/. Steps execute in order: Initialize → Serialize → Build → Finalize → Deserialize. Each step is a middleware.Step that holds an ordered list of middleware. The codegen generates middleware registrations for each operation.

Encoding packages

Each wire format has its own encoder/decoder under encoding/. These are low-level — they produce/consume raw tokens or values, not full Smithy shapes. Generated serde code calls into these packages.

Codegen: GoWriter and template system

GoWriter extends Smithy's SymbolWriter and is the primary mechanism for generating Go source. It has two distinct writing styles that must not be confused.

Style 1: Positional args (writer.write / writer.openBlock)

Inherited from SymbolWriter. Arguments are positional and referenced with $-prefixed format characters. Each $X consumes the next argument in order.

Format characters:

  • $L — Literal (toString). Strings, names, anything that should be inserted verbatim.
  • $S — String, quoted. Wraps the value in Go double-quotes.
  • $T — Type (Symbol). Inserts the symbol name and auto-adds its import.
  • $P — Pointable type (Symbol). Like $T but prepends * if the symbol is marked pointable.
  • $W — Writable. Evaluates a Writable (lambda/closure) inline.
  • $D — Dependency. Adds a GoDependency import, expands to empty string.

Numbered variants ($1L, $2T, etc.) allow reusing the same argument multiple times. The number is 1-indexed and refers to the position in the argument list:

// $1L is used twice, $2L once — only 2 args needed
writer.write("type $1L struct{}\nvar _ $2L = (*$1L)(nil)",
    DEFAULT_NAME, INTERFACE_NAME);

openBlock/closeBlock manage indentation for braced blocks. Arguments are positional:

writer.openBlock("func (c $P) $T(ctx $T) ($P, error) {", "}",
    serviceSymbol, operationSymbol, contextSymbol, outputSymbol,
    () -> {
        writer.write("return nil, nil");
    });

Style 2: Named template args (goTemplate / writeGoTemplate)

Uses $name:X syntax where name is a key in a Map<String, Object> and X is the format character. Arguments are passed as one or more maps. This is the preferred style for new code — it is more readable and less error-prone than positional args.

return goTemplate("""
    func $name:L(v $cborValue:T) ($type:T, error) {
        return $coercer:T(v)
    }
    """,
    Map.of(
        "name", getDeserializerName(shape),
        "cborValue", SmithyGoTypes.Encoding.Cbor.Value,
        "type", symbolProvider.toSymbol(shape),
        "coercer", coercer
    ));

Rules:

  • goTemplate(String, Map...) is a static method that returns a Writable (a Consumer<GoWriter> lambda). It does NOT write immediately.
  • writeGoTemplate(String, Map...) is an instance method that writes immediately to the writer.
  • Maps are merged into the writer's context scope for the duration of the template. Multiple maps can be passed and are applied in order.
  • The writer pre-populates common symbols in context: fmt.Sprintf, fmt.Errorf, errors.As, context.Context, time.Now.

Composing writables

  • ChainWritable — Collects multiple Writables and composes them with newlines between each. Use .compose() (with newlines) or .compose(false) (without).

Symbol constants

For symbols, use SmithyGoDependency.*.valueSymbol("Name") or SmithyGoDependency.*.pointableSymbol("Name").