Skip to content

Commit 3e78a2b

Browse files
authored
add AGENTS.md (#638)
1 parent c53a167 commit 3e78a2b

1 file changed

Lines changed: 172 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# AGENTS.md
2+
3+
## Project overview
4+
5+
smithy-go is the Go code generator and runtime for [Smithy](https://smithy.io/).
6+
It has two major components:
7+
8+
1. **Codegen** (`codegen/`) — A Smithy build plugin written in Java that
9+
generates Go client/server/shape code from Smithy models.
10+
2. **Runtime** (`./`, top-level Go module) — The Go packages that generated
11+
code depends on at runtime.
12+
13+
The primary downstream consumer is
14+
[aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2).
15+
16+
## Repository layout
17+
18+
```
19+
. # Root Go module (github.com/aws/smithy-go)
20+
├── auth/ # Auth identity + scheme interfaces
21+
│ └── bearer/ # Bearer token auth
22+
├── aws-http-auth/ # Separate module: AWS SigV4/SigV4A HTTP signing
23+
├── codegen/ # Java/Gradle: Smithy code generator
24+
│ ├── smithy-go-codegen/ # Main codegen source (Java)
25+
│ └── smithy-go-codegen-test/ # Codegen integration tests
26+
├── container/ # Generic container types
27+
├── context/ # Context helpers
28+
├── document/ # Smithy document type abstraction
29+
│ └── json/ # JSON document codec
30+
├── encoding/ # Wire format encoders/decoders
31+
│ ├── cbor/ # CBOR (used by rpcv2Cbor)
32+
│ ├── httpbinding/ # HTTP binding serde helpers
33+
│ ├── json/ # JSON encoder/decoder
34+
│ └── xml/ # XML encoder/decoder
35+
├── endpoints/ # Endpoint resolution types
36+
├── internal/ # Internal utilities (singleflight, etc.)
37+
├── io/ # I/O helpers
38+
├── logging/ # Logging interfaces
39+
├── metrics/ # Metrics interfaces
40+
│ └── smithyotelmetrics/ # Separate module: OpenTelemetry metrics adapter
41+
├── middleware/ # Middleware stack (the core of the operation pipeline)
42+
├── ptr/ # Pointer-to/from-value helpers
43+
├── testing/ # Test assertion helpers for generated protocol tests
44+
│ └── xml/ # XML comparison utilities
45+
├── time/ # Smithy timestamp format helpers
46+
├── tracing/ # Tracing interfaces
47+
│ └── smithyoteltracing/ # Separate module: OpenTelemetry tracing adapter
48+
└── transport/
49+
└── http/ # HTTP request/response types and middleware
50+
```
51+
52+
## Building and testing
53+
54+
### Runtime (Go)
55+
56+
```bash
57+
# Run unit tests
58+
make unit
59+
```
60+
61+
### Codegen (Java)
62+
63+
```bash
64+
# Build and test codegen
65+
cd codegen && ./gradlew build
66+
67+
# Publish to local Maven for downstream use
68+
cd codegen && ./gradlew publishToMavenLocal
69+
```
70+
71+
The codegen artifact version is fixed at `0.1.0` and is not published to
72+
Maven Central — you **MUST** `publishToMavenLocal`.
73+
74+
## Runtime architecture
75+
76+
### Middleware stack
77+
78+
The operation pipeline is built on a middleware stack defined in `middleware/`.
79+
Steps execute in order: Initialize → Serialize → Build → Finalize →
80+
Deserialize. Each step is a `middleware.Step` that holds an ordered list of
81+
middleware. The codegen generates middleware registrations for each operation.
82+
83+
### Encoding packages
84+
85+
Each wire format has its own encoder/decoder under `encoding/`. These are
86+
low-level — they produce/consume raw tokens or values, not full Smithy shapes.
87+
Generated serde code calls into these packages.
88+
89+
## Codegen: GoWriter and template system
90+
91+
GoWriter extends Smithy's `SymbolWriter` and is the primary mechanism for
92+
generating Go source. It has **two distinct writing styles** that must not be
93+
confused.
94+
95+
### Style 1: Positional args (`writer.write` / `writer.openBlock`)
96+
97+
Inherited from `SymbolWriter`. Arguments are positional and referenced with
98+
`$`-prefixed format characters. Each `$X` consumes the next argument in order.
99+
100+
Format characters:
101+
- `$L` — Literal (toString). Strings, names, anything that should be inserted
102+
verbatim.
103+
- `$S` — String, quoted. Wraps the value in Go double-quotes.
104+
- `$T` — Type (Symbol). Inserts the symbol name and auto-adds its import.
105+
- `$P` — Pointable type (Symbol). Like `$T` but prepends `*` if the symbol is
106+
marked pointable.
107+
- `$W` — Writable. Evaluates a `Writable` (lambda/closure) inline.
108+
- `$D` — Dependency. Adds a `GoDependency` import, expands to empty string.
109+
110+
Numbered variants (`$1L`, `$2T`, etc.) allow reusing the same argument
111+
multiple times. The number is 1-indexed and refers to the position in the
112+
argument list:
113+
114+
```java
115+
// $1L is used twice, $2L once — only 2 args needed
116+
writer.write("type $1L struct{}\nvar _ $2L = (*$1L)(nil)",
117+
DEFAULT_NAME, INTERFACE_NAME);
118+
```
119+
120+
`openBlock`/`closeBlock` manage indentation for braced blocks. Arguments are
121+
positional:
122+
123+
```java
124+
writer.openBlock("func (c $P) $T(ctx $T) ($P, error) {", "}",
125+
serviceSymbol, operationSymbol, contextSymbol, outputSymbol,
126+
() -> {
127+
writer.write("return nil, nil");
128+
});
129+
```
130+
131+
### Style 2: Named template args (`goTemplate` / `writeGoTemplate`)
132+
133+
Uses `$name:X` syntax where `name` is a key in a `Map<String, Object>` and `X`
134+
is the format character. Arguments are passed as one or more maps. This is the
135+
**preferred style for new code** — it is more readable and less error-prone
136+
than positional args.
137+
138+
```java
139+
return goTemplate("""
140+
func $name:L(v $cborValue:T) ($type:T, error) {
141+
return $coercer:T(v)
142+
}
143+
""",
144+
Map.of(
145+
"name", getDeserializerName(shape),
146+
"cborValue", SmithyGoTypes.Encoding.Cbor.Value,
147+
"type", symbolProvider.toSymbol(shape),
148+
"coercer", coercer
149+
));
150+
```
151+
152+
Rules:
153+
- `goTemplate(String, Map...)` is a **static** method that returns a
154+
`Writable` (a `Consumer<GoWriter>` lambda). It does NOT write immediately.
155+
- `writeGoTemplate(String, Map...)` is an **instance** method that writes
156+
immediately to the writer.
157+
- Maps are merged into the writer's context scope for the duration of the
158+
template. Multiple maps can be passed and are applied in order.
159+
- The writer pre-populates common symbols in context: `fmt.Sprintf`,
160+
`fmt.Errorf`, `errors.As`, `context.Context`, `time.Now`.
161+
162+
### Composing writables
163+
164+
- `ChainWritable` — Collects multiple `Writable`s and composes them with
165+
newlines between each. Use `.compose()` (with newlines) or
166+
`.compose(false)` (without).
167+
168+
### Symbol constants
169+
170+
For symbols, use `SmithyGoDependency.*.valueSymbol("Name")` or
171+
`SmithyGoDependency.*.pointableSymbol("Name")`.
172+

0 commit comments

Comments
 (0)