README
¶
Internal Package Guide
This directory holds the implementation behind the wire CLI and library.
If you are new to the codebase, the two packages that matter most are:
internal/wire: parses injector/provider-set source and generateswire_gen.gointernal/loader: loads package graphs, supports the custom loader, and manages loader-side caches
Everything else is either small support code or repo maintenance helpers.
High-Level Flow
For wire gen, the rough flow is:
cmd/wireparses flags and callswire.Generate(...)internal/wiretries the output cache fast pathinternal/loaderloads the root graph and typed package graphinternal/wire/parse.gowalks source/type information and builds Wire's internal modelinternal/wire/wire.gogenerates formatted Go outputcmd/wirewriteswire_gen.go
If you are debugging behavior, start in:
Package Overview
internal/wire
This is the core implementation of Wire's analysis and code generation.
Important responsibilities:
- loading packages through the loader abstraction
- parsing
wire.NewSet,wire.Bind,wire.Struct,wire.FieldsOf, and injector functions - building the internal provider graph model
- validating dependency graphs
- rendering generated Go source
- managing the output cache
Important files:
wire/wire.goMain generation entry point. DefinesGenerate,GenerateResult, and the final generation loop.wire/parse.goThe biggest conceptual file in the repo. Defines the internal model (ProviderSet,Provider,Value,Field, etc.) and parses source/type information into that model.wire/analyze.goPerforms graph validation and dependency analysis once provider sets are parsed.wire/output_cache.goOutput cache read/write and key construction.wire/load_debug.goDebug/timing summaries for loaded package graphs.wire/timing.goTiming/debug plumbing for thewirepackage.wire/loader_timing_bridge.goConnects loader timing output into wire timing output.wire/errors.goError collection and formatting helpers.wire/copyast.goAST copying helpers used during generation.wire/loader_validation.goLoader-mode-related validation helpers.
Useful mental model:
parse.goturns package syntax/types into a Wire-specific graph modelanalyze.govalidates that graphwire.goemits Go code from that graph
internal/loader
This package abstracts package loading and is the main performance-sensitive layer.
Important responsibilities:
- choosing between the custom loader and
go/packagesfallback - root graph loading vs typed package loading
- discovery via
go list - discovery cache
- loader artifact cache
- touched-package validation
- loader timings and fallback reasons
Important files:
loader/loader.goPublic loader API and shared request/result structs. This is the best entry point for understanding loader responsibilities.loader/custom.goThe custom loader implementation. This is the most performance-critical file in the repo.loader/fallback.gogo/packagesfallback implementation and fallback reason handling.loader/discovery.goRunsgo list, decodes package metadata, and populates the discovery cache.loader/discovery_cache.goDiscovery cache storage and invalidation.loader/artifact_cache.goLoader artifact cache keying and read/write helpers.loader/mode.goLoader mode selection helpers.loader/timing.goTiming/debug plumbing for the loader package.
Useful mental model:
discovery.goanswers "what packages/files/imports exist?"custom.goanswers "how do we build the package graph and type info efficiently?"artifact_cache.gois the typed-package reuse layerfallback.gois the correctness backstop
internal/cachepaths
Small shared helper package for Wire-managed cache directories.
Responsibilities:
- resolve the shared cache root
- resolve specific cache directories
- support shared and specific env var overrides
Important file:
This package exists to keep cache path policy centralized instead of duplicated across loader, output cache, and the wire cache command.
Internal Data Structures
These are the main structs worth learning first.
In internal/wire
ProviderSetThe central Wire model. Represents a set built fromwire.NewSet(...)orwire.Build(...).ProviderA constructor source, either a function or a named struct provider.IfaceBindingAwire.Bind(...)relationship.ValueAwire.Value(...)source.FieldAwire.FieldsOf(...)source.InjectorArgs/InjectorArgInjector function argument modeling.
If you understand ProviderSet, most of parse.go becomes easier to follow.
In internal/loader
RootLoadRequest/RootLoadResultUsed for lightweight root graph loading, primarily for cache lookup and root discovery.PackageLoadRequest/PackageLoadResultUsed for full typed package loading.LazyLoadRequest/LazyLoadResultUsed for package-targeted typed loading.TouchedValidationRequest/TouchedValidationResultUsed to validate whether a touched local package can stay on the custom path.DiscoverySnapshotCapturesgo listmetadata so later phases can reuse discovery without rerunning it.packageMetaInternal metadata fromgo list. This is the custom loader's raw package description.customTypedGraphLoaderMain stateful custom loader for building typed package graphs.
Empty or Transitional Directories
internal/cachestoreinternal/semanticcache
These directories currently exist but do not contain active implementation files. Treat them as inactive unless they are populated later.
Repo Maintenance Files
There are also a few internal scripts/data files that support repo maintenance:
alldepsDependency allowlist/check input.runtests.shRepo test runner used in CI/dev workflows.listdeps.shDependency listing helper.check_api_change.shAPI change check helper.
Suggested Reading Order
If you are trying to understand the codebase quickly:
wire/wire.goloader/loader.goloader/custom.gowire/parse.gowire/analyze.gowire/output_cache.goloader/discovery.goloader/artifact_cache.go
Practical Notes For New Readers
- If a behavior issue involves parsing provider sets, start in
internal/wire/parse.go. - If a behavior issue involves performance, cache hits, or package loading, start in
internal/loader/custom.go. - If a behavior issue involves "why did we skip generation?" or "why did generation return instantly?", check
internal/wire/output_cache.go. - If a behavior issue only appears in one environment or workspace, inspect cache path resolution in
internal/cachepaths/cachepaths.goand discovery behavior ininternal/loader/discovery.go.
This repo has two real centers of complexity:
- the Wire semantic model in
internal/wire - the package loading/caching machinery in
internal/loader
Most other internal code exists to support those two areas.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package wire provides compile-time dependency injection logic as a Go library.
|
Package wire provides compile-time dependency injection logic as a Go library. |