Documentation
¶
Overview ¶
Package compiler wraps protocompile to provide namespace-scoped compilation of proto source files. It handles normalization, SHA-256 hashing for content-addressable storage, and builds the resolver chain that enforces namespace isolation (chroot model).
Index ¶
Constants ¶
const ( // DefaultCompileTimeout caps wall-clock time spent inside protocompile. DefaultCompileTimeout = 30 * time.Second // DefaultMaxFileSourceBytes caps the size of any individual proto // source the compiler will accept. Enforced before any AST work. DefaultMaxFileSourceBytes = 8 * 1024 * 1024 // 8 MiB // DefaultMaxFiles caps the number of files in a single Compile call. DefaultMaxFiles = 1000 )
Default resource caps. Compile is the user-facing entry point and these numbers bound worst-case CPU and memory consumption per call. The server applies tighter validation upstream; these are the library-level safety net so the compiler is also safe to embed in non-server callers.
Variables ¶
This section is empty.
Functions ¶
func ComputeFingerprint ¶
func ComputeFingerprint(files []FileResult) string
ComputeFingerprint computes a fingerprint over a sorted set of (filename, hash) pairs. Used to detect whether a new submission actually changes anything compared to the current version.
func IsWellKnownType ¶
IsWellKnownType reports whether filename matches a standard import provided by protocompile (e.g., google/protobuf/timestamp.proto).
Types ¶
type ChainTier ¶ added in v0.71.0
type ChainTier struct {
// NamespaceID of this tier, for diagnostics and downstream attribution.
NamespaceID string
// Files contributed by this namespace at the pinned/current versions.
Files []DepSource
}
ChainTier is one tier of the parent-namespace resolver chain. Each tier represents one ancestor namespace's contribution to filename resolution. Tiers are ordered nearest-first by the caller; the compiler walks them in order and the first match wins (filename-based resolution per D7).
type CompileResult ¶
type CompileResult struct {
// Snapshot is the compiled, immutable descriptor set.
Snapshot *snapshot.Snapshot
// Compiled is the serialized FileDescriptorSet for storage.
Compiled []byte
// Files is the list of normalized file hashes, for blob storage.
Files []FileResult
// Deps records which dependency versions were used during compilation.
Deps []Dep
}
CompileResult holds the output of a compilation.
type Compiler ¶
type Compiler struct {
// contains filtered or unexported fields
}
Compiler wraps protocompile for namespace-scoped compilation.
func New ¶
func New(opts ...CompilerOption) *Compiler
New creates a new Compiler with default caps. Pass options to override.
func (*Compiler) Compile ¶
func (c *Compiler) Compile( ctx context.Context, version uint64, sources map[string][]byte, deps []DepSource, parentChain []ChainTier, builtins []DepSource, ) (*CompileResult, error)
Compile compiles the given proto sources within a namespace scope.
Parameters:
- sources: filename → content for the schema being compiled (the child).
- deps: files from other schemas in the *same* namespace, available for import. Each DepSource's Namespace should equal the publishing namespace.
- parentChain: ancestor namespaces in resolution order (nearest first). Each tier's files are tried after the child's own namespace tier. Pass nil or empty for namespaces without a parent.
- builtins: files from the __builtins__ namespace, available to every namespace; resolve after the parent chain but before Google WKT.
Resolution order: child sources & same-ns deps → parent chain tiers (nearest first) → builtins → Google well-known types. First file whose path matches wins (decision D7).
Compile does not perform cross-tier FQN collision detection (D2). Callers that need it should invoke DetectFQNConflicts on the resulting snapshot against each ancestor's snapshot.
type CompilerOption ¶
type CompilerOption func(*Compiler)
CompilerOption customises a Compiler.
func WithMaxFileSourceBytes ¶
func WithMaxFileSourceBytes(n int64) CompilerOption
WithMaxFileSourceBytes sets the per-file size cap.
func WithMaxFiles ¶
func WithMaxFiles(n int) CompilerOption
WithMaxFiles sets the cap on the number of files per Compile call.
func WithTimeout ¶
func WithTimeout(d time.Duration) CompilerOption
WithTimeout sets the wall-clock cap on a single Compile call. Pass 0 to disable (not recommended in server contexts).
type Dep ¶
Dep records a dependency on another schema's file used during compilation.
DepNamespaceID identifies which namespace contributed the file. For same-namespace dependencies (cross-schema imports within the publishing namespace) this equals the publishing namespace's ID. For cross-namespace dependencies resolved via the namespace hierarchy, this is the ancestor namespace that supplied the file. See docs/design/namespace-hierarchy.md decision D3.
type DepSource ¶
type DepSource struct {
Namespace string
SchemaID string
Version uint64
Filename string
Source []byte
}
DepSource describes a file available to the compiler from another schema. Namespace identifies the contributing namespace. For same-namespace deps this equals the publishing namespace's ID; for parent-chain tiers this is the ancestor's ID.
func LoadBuiltIns ¶
LoadBuiltIns reads all .proto files from dir recursively and returns them as DepSource entries suitable for passing to Compile as builtins. The filenames are relative to dir, matching proto import paths.
type FQNConflict ¶ added in v0.71.0
type FQNConflict struct {
// FQN is the fully-qualified name that is defined in both snapshots.
FQN string
// Kind is what the FQN refers to: "message", "enum", "service",
// "extension". For collisions where the two definitions are of
// different kinds, Kind is "message" if either side is a message,
// otherwise the child's kind.
Kind string
// ChildFile is the file in the child snapshot that defines the symbol.
ChildFile string
// AncestorFile is the file in the ancestor snapshot that defines it.
AncestorFile string
}
FQNConflict describes a fully-qualified-name collision between a child and an ancestor in the namespace hierarchy. See decision D2 in docs/design/namespace-hierarchy.md.
func DetectFQNConflicts ¶ added in v0.71.0
func DetectFQNConflicts(child, ancestor *snapshot.Snapshot) []FQNConflict
DetectFQNConflicts walks every type defined in the child snapshot and returns those whose fully-qualified name is also defined in the ancestor snapshot **in a different file**. Same-file collisions are not flagged: they represent the legitimate case where the child imports a parent file, and the parent's types appear in the child's snapshot via that import — the definition is shared, not shadowed. A real D2 conflict (decision D2) is when the child redefines a parent FQN in one of its own files.
The check covers messages (including nested), enums (including nested), services, and top-level extensions. Method names within services are scoped under their service's FQN by protoreflect, so per-RPC collisions surface naturally through service-level FQN collisions.
Conflicts are returned in deterministic order (sorted by FQN) so error messages are stable across runs — important for golden tests.
type FQNConflictError ¶ added in v0.71.0
type FQNConflictError struct {
AncestorNamespaceID string
Conflicts []FQNConflict
}
FQNConflictError aggregates one or more FQN collisions between a child snapshot and an ancestor. Callers (typically Registry.Publish) wrap or propagate this to surface a clear diagnostic.
func (*FQNConflictError) Error ¶ added in v0.71.0
func (e *FQNConflictError) Error() string
type FileResult ¶
FileResult associates a filename with its content hash after normalization.
type NormalizeResult ¶
type NormalizeResult struct {
// SHA256 is the hex-encoded SHA-256 hash of the normalized content.
SHA256 string
// OriginalSource is the unmodified source as submitted.
OriginalSource []byte
}
NormalizeResult holds the output of normalizing a proto source file.
func NormalizeAndHash ¶
func NormalizeAndHash(filename string, source []byte) (*NormalizeResult, error)
NormalizeAndHash parses a proto file, produces a canonical (normalized) representation by printing the AST without comments or extraneous whitespace, and returns the SHA-256 hash of that normalized form.
The original source is returned unchanged for storage. The hash is used only for content-addressable deduplication and change detection.