Skip to content

Commit 275e271

Browse files
committed
docs: add readme in internal for future travelers
1 parent 8a3ed6d commit 275e271

1 file changed

Lines changed: 213 additions & 0 deletions

File tree

internal/README.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# Internal Package Guide
2+
3+
This directory holds the implementation behind the `wire` CLI and library.
4+
If you are new to the codebase, the two packages that matter most are:
5+
6+
- `internal/wire`: parses injector/provider-set source and generates `wire_gen.go`
7+
- `internal/loader`: loads package graphs, supports the custom loader, and manages loader-side caches
8+
9+
Everything else is either small support code or repo maintenance helpers.
10+
11+
## High-Level Flow
12+
13+
For `wire gen`, the rough flow is:
14+
15+
1. `cmd/wire` parses flags and calls `wire.Generate(...)`
16+
2. `internal/wire` tries the output cache fast path
17+
3. `internal/loader` loads the root graph and typed package graph
18+
4. `internal/wire/parse.go` walks source/type information and builds Wire's internal model
19+
5. `internal/wire/wire.go` generates formatted Go output
20+
6. `cmd/wire` writes `wire_gen.go`
21+
22+
If you are debugging behavior, start in:
23+
24+
- [`wire/wire.go`](./wire/wire.go)
25+
- [`wire/parse.go`](./wire/parse.go)
26+
- [`loader/loader.go`](./loader/loader.go)
27+
- [`loader/custom.go`](./loader/custom.go)
28+
29+
## Package Overview
30+
31+
### `internal/wire`
32+
33+
This is the core implementation of Wire's analysis and code generation.
34+
35+
Important responsibilities:
36+
37+
- loading packages through the loader abstraction
38+
- parsing `wire.NewSet`, `wire.Bind`, `wire.Struct`, `wire.FieldsOf`, and injector functions
39+
- building the internal provider graph model
40+
- validating dependency graphs
41+
- rendering generated Go source
42+
- managing the output cache
43+
44+
Important files:
45+
46+
- [`wire/wire.go`](./wire/wire.go)
47+
Main generation entry point. Defines `Generate`, `GenerateResult`, and the final generation loop.
48+
- [`wire/parse.go`](./wire/parse.go)
49+
The biggest conceptual file in the repo. Defines the internal model (`ProviderSet`, `Provider`, `Value`, `Field`, etc.) and parses source/type information into that model.
50+
- [`wire/analyze.go`](./wire/analyze.go)
51+
Performs graph validation and dependency analysis once provider sets are parsed.
52+
- [`wire/output_cache.go`](./wire/output_cache.go)
53+
Output cache read/write and key construction.
54+
- [`wire/load_debug.go`](./wire/load_debug.go)
55+
Debug/timing summaries for loaded package graphs.
56+
- [`wire/timing.go`](./wire/timing.go)
57+
Timing/debug plumbing for the `wire` package.
58+
- [`wire/loader_timing_bridge.go`](./wire/loader_timing_bridge.go)
59+
Connects loader timing output into wire timing output.
60+
- [`wire/errors.go`](./wire/errors.go)
61+
Error collection and formatting helpers.
62+
- [`wire/copyast.go`](./wire/copyast.go)
63+
AST copying helpers used during generation.
64+
- [`wire/loader_validation.go`](./wire/loader_validation.go)
65+
Loader-mode-related validation helpers.
66+
67+
Useful mental model:
68+
69+
- `parse.go` turns package syntax/types into a Wire-specific graph model
70+
- `analyze.go` validates that graph
71+
- `wire.go` emits Go code from that graph
72+
73+
### `internal/loader`
74+
75+
This package abstracts package loading and is the main performance-sensitive layer.
76+
77+
Important responsibilities:
78+
79+
- choosing between the custom loader and `go/packages` fallback
80+
- root graph loading vs typed package loading
81+
- discovery via `go list`
82+
- discovery cache
83+
- loader artifact cache
84+
- touched-package validation
85+
- loader timings and fallback reasons
86+
87+
Important files:
88+
89+
- [`loader/loader.go`](./loader/loader.go)
90+
Public loader API and shared request/result structs. This is the best entry point for understanding loader responsibilities.
91+
- [`loader/custom.go`](./loader/custom.go)
92+
The custom loader implementation. This is the most performance-critical file in the repo.
93+
- [`loader/fallback.go`](./loader/fallback.go)
94+
`go/packages` fallback implementation and fallback reason handling.
95+
- [`loader/discovery.go`](./loader/discovery.go)
96+
Runs `go list`, decodes package metadata, and populates the discovery cache.
97+
- [`loader/discovery_cache.go`](./loader/discovery_cache.go)
98+
Discovery cache storage and invalidation.
99+
- [`loader/artifact_cache.go`](./loader/artifact_cache.go)
100+
Loader artifact cache keying and read/write helpers.
101+
- [`loader/mode.go`](./loader/mode.go)
102+
Loader mode selection helpers.
103+
- [`loader/timing.go`](./loader/timing.go)
104+
Timing/debug plumbing for the loader package.
105+
106+
Useful mental model:
107+
108+
- `discovery.go` answers "what packages/files/imports exist?"
109+
- `custom.go` answers "how do we build the package graph and type info efficiently?"
110+
- `artifact_cache.go` is the typed-package reuse layer
111+
- `fallback.go` is the correctness backstop
112+
113+
### `internal/cachepaths`
114+
115+
Small shared helper package for Wire-managed cache directories.
116+
117+
Responsibilities:
118+
119+
- resolve the shared cache root
120+
- resolve specific cache directories
121+
- support shared and specific env var overrides
122+
123+
Important file:
124+
125+
- [`cachepaths/cachepaths.go`](./cachepaths/cachepaths.go)
126+
127+
This package exists to keep cache path policy centralized instead of duplicated across loader, output cache, and the `wire cache` command.
128+
129+
## Internal Data Structures
130+
131+
These are the main structs worth learning first.
132+
133+
### In `internal/wire`
134+
135+
- `ProviderSet`
136+
The central Wire model. Represents a set built from `wire.NewSet(...)` or `wire.Build(...)`.
137+
- `Provider`
138+
A constructor source, either a function or a named struct provider.
139+
- `IfaceBinding`
140+
A `wire.Bind(...)` relationship.
141+
- `Value`
142+
A `wire.Value(...)` source.
143+
- `Field`
144+
A `wire.FieldsOf(...)` source.
145+
- `InjectorArgs` / `InjectorArg`
146+
Injector function argument modeling.
147+
148+
If you understand `ProviderSet`, most of `parse.go` becomes easier to follow.
149+
150+
### In `internal/loader`
151+
152+
- `RootLoadRequest` / `RootLoadResult`
153+
Used for lightweight root graph loading, primarily for cache lookup and root discovery.
154+
- `PackageLoadRequest` / `PackageLoadResult`
155+
Used for full typed package loading.
156+
- `LazyLoadRequest` / `LazyLoadResult`
157+
Used for package-targeted typed loading.
158+
- `TouchedValidationRequest` / `TouchedValidationResult`
159+
Used to validate whether a touched local package can stay on the custom path.
160+
- `DiscoverySnapshot`
161+
Captures `go list` metadata so later phases can reuse discovery without rerunning it.
162+
- `packageMeta`
163+
Internal metadata from `go list`. This is the custom loader's raw package description.
164+
- `customTypedGraphLoader`
165+
Main stateful custom loader for building typed package graphs.
166+
167+
## Empty or Transitional Directories
168+
169+
- `internal/cachestore`
170+
- `internal/semanticcache`
171+
172+
These directories currently exist but do not contain active implementation files.
173+
Treat them as inactive unless they are populated later.
174+
175+
## Repo Maintenance Files
176+
177+
There are also a few internal scripts/data files that support repo maintenance:
178+
179+
- [`alldeps`](./alldeps)
180+
Dependency allowlist/check input.
181+
- [`runtests.sh`](./runtests.sh)
182+
Repo test runner used in CI/dev workflows.
183+
- [`listdeps.sh`](./listdeps.sh)
184+
Dependency listing helper.
185+
- [`check_api_change.sh`](./check_api_change.sh)
186+
API change check helper.
187+
188+
## Suggested Reading Order
189+
190+
If you are trying to understand the codebase quickly:
191+
192+
1. [`wire/wire.go`](./wire/wire.go)
193+
2. [`loader/loader.go`](./loader/loader.go)
194+
3. [`loader/custom.go`](./loader/custom.go)
195+
4. [`wire/parse.go`](./wire/parse.go)
196+
5. [`wire/analyze.go`](./wire/analyze.go)
197+
6. [`wire/output_cache.go`](./wire/output_cache.go)
198+
7. [`loader/discovery.go`](./loader/discovery.go)
199+
8. [`loader/artifact_cache.go`](./loader/artifact_cache.go)
200+
201+
## Practical Notes For New Readers
202+
203+
- If a behavior issue involves parsing provider sets, start in `internal/wire/parse.go`.
204+
- If a behavior issue involves performance, cache hits, or package loading, start in `internal/loader/custom.go`.
205+
- If a behavior issue involves "why did we skip generation?" or "why did generation return instantly?", check `internal/wire/output_cache.go`.
206+
- If a behavior issue only appears in one environment or workspace, inspect cache path resolution in `internal/cachepaths/cachepaths.go` and discovery behavior in `internal/loader/discovery.go`.
207+
208+
This repo has two real centers of complexity:
209+
210+
- the Wire semantic model in `internal/wire`
211+
- the package loading/caching machinery in `internal/loader`
212+
213+
Most other internal code exists to support those two areas.

0 commit comments

Comments
 (0)