Documentation
¶
Overview ¶
Package ir defines Morphic's spec-agnostic intermediate representation: the single contract between spec compilers and generator emitters.
The shapes in this package are normatively specified in docs/ir-design.md; field names and struct layouts must match that document exactly. All named entities live in flat, ID-keyed registries on Document and reference each other by ID. The whole Document round-trips through JSON deterministically.
Besides the nodes, it owns the traversal every consumer inspecting a whole document needs: WalkValues is the one bounded, cycle-guarded, deterministically-ordered reflection walk, and DocumentRegistries derives what counts as a resolvable reference from Document's own shape. Both live here because a second copy of either is a second answer to keep in step with the first.
This package imports only the standard library. It contains no parsing, no generation, and no I/O. All types are plain data and safe for concurrent reads; nothing in this package mutates package-level state.
Index ¶
- Constants
- Variables
- func CanonicalWords(name string) string
- func CompatibleVersion(version string) bool
- func HasError(diags []Diagnostic) bool
- func IDPath(kind, id string) (string, bool)
- func IDSpace(kind, id string) (string, bool)
- func IsNilTypeDef(td TypeDef) bool
- func RefNoun(idType reflect.Type) string
- func WalkValues(root any, path string, visit func(v reflect.Value, path string) bool) bool
- func WellFormedID(kind, id string) bool
- type AdditionalMode
- type AdditionalProps
- type Any
- type AuthID
- type AuthKind
- type AuthRequirement
- type AuthScheme
- type Availability
- type BigVal
- type Callback
- type Channel
- type ChannelID
- type Constraints
- type Contact
- type Content
- type CtorValue
- type Deprecation
- type Diagnostic
- type Discriminator
- type Docs
- type Document
- type Encoding
- type Enum
- type EnumMember
- type ErrorCase
- type ErrorExample
- type EventInfo
- type Example
- type External
- type Field
- type FileInfo
- type GraphQLBinding
- type HTTPBinding
- type HTTPLocation
- type HTTPParamBinding
- type IDDeclaration
- type Idempotency
- type IdempotencyKind
- type License
- type Lifecycle
- type Link
- type List
- type Literal
- type LongRunning
- type MapT
- type Message
- type MessageBinding
- type MessageID
- type Model
- type MsgDirection
- type Naming
- type OAuthFlow
- type OTPBinding
- type OpBindings
- type OpID
- type Operation
- type OperationGroup
- type PageStrategy
- type Pagination
- type ParamPath
- type Parameter
- type PartEncoding
- type PatternProps
- type Payload
- type Position
- type PresenceKind
- type PrimKind
- type Primitive
- type PropID
- type PropPath
- type Property
- type ProtocolDecl
- type Provenance
- type RPCBinding
- type RawConfig
- type RawValue
- type Registries
- type Registry
- type Reply
- type RequestCompression
- type ResourceInfo
- type Response
- type ResponseConditions
- type Scalar
- type SchemeUse
- type Server
- type ServerVariable
- type Service
- type ServiceID
- type Severity
- type SourceInfo
- type StatusRange
- type StreamDetail
- type StreamingMode
- type TagDef
- type TemplateArg
- type TemplateInstantiation
- type Tuple
- type TypeCommon
- type TypeDef
- type TypeID
- type TypeKind
- type TypeRef
- type TypeRegistry
- type Union
- type Unmodeled
- type UnmodeledEntry
- type UnmodeledReason
- type UsageFlags
- type Value
- type ValueKind
- type ValueRef
- type Variant
- type VersionedBool
- type VersionedName
- type VersionedType
- type Visibility
- type WireIDRange
- type XMLHints
Constants ¶
const ( IDKindType = "t" IDKindOp = "op" IDKindProp = "p" IDKindAuth = "auth" IDKindService = "s" )
The kind prefix that opens every synthetic ID. An ID is <kind>/<space>[/<path>]: the kind says what sort of entity it names, the space says whose coordinates the path is in, and the path is the compiler's own derivation from the defining occurrence.
The vocabulary lives here rather than in any one compiler because every consumer of a Document reads it — a diagnostic renderer, an IR diff, the structural verifier — so a compiler with its own spelling breaks all of them. compilers/compile owns the grammar that assembles an ID from these; what an ID looks like is fixed here, which is what lets irverify hold every compiler to it rather than only the one under test (GitHub #141).
Channels and messages have no prefix yet: no compiler mints one, and inventing a spelling before a compiler needs it would fix the wrong thing.
const DocumentPath = "doc"
DocumentPath is the path a walk rooted at a whole Document starts from, and so the first segment of every location such a walk reports. It is a constant rather than each caller's own string literal for the reason the rest of the path grammar is one walk: two checkers reporting one defect can only be deduped by a caller running both if the defect reads as one location.
const IDSeparator = "/"
IDSeparator separates an ID's kind, space and path segments.
const IDSpacePrim = "prim"
IDSpacePrim is the space the primitive leaves are addressed in.
It is the one space that is not some format's own: every compiler must reach the same node for the same PrimKind, or two documents lowered from different formats disagree about the identity of the same type. A space shared by accident rather than on purpose is what naming it here makes visible.
const IRVersion = "0.6.0"
IRVersion is the semver of the IR schema itself. Compilers stamp it into Document.IRVersion; consumers compare against it to detect schema drift.
It names a schema generation, not a commit. A line of work that changes the JSON shape several times bumps it once, where it lands on main, rather than once per change: a version that moves within an unmerged branch tells a consumer nothing and rewrites every golden each time it moves. Pre-1.0 is no exemption from moving it at all — a shape change that reaches main without a bump leaves a consumer pinned to the old version accepting a document it cannot read, which is the one thing this constant exists to prevent.
0.2.0 covers three shape changes made together: Extensions became Preserved with RawConfig split out, Content.ItemEncoding became a single encoding rather than a sentinel-keyed map, and the diagnostic code pass/dangling-auth-ref became ir/dangling-auth-ref (see pass's package doc).
0.3.0 renames that field to Unmodeled on every carrier, so the JSON key "preserved" is now "unmodeled". A consumer pinned to 0.2.0 finds no key it recognizes and drops every unmodeled construct in silence.
0.4.0 covers six shape changes made together, all of them closing a gap a consumer had to read around rather than adding a capability:
- ErrorCase becomes Response's sibling: Type is REMOVED, and Name, Payload and Headers take its place. A consumer pinned to 0.3.0 finds no "type" on an error case and cannot reach its models at all; one that reads the new fields gets the status spelling, the headers and every media type, which 0.3.0 dumped into Unmodeled whatever their arity.
- Payload gains Required. Body optionality stopped being an inverted Unmodeled sentinel read by absence, so a consumer that still reads "openapi:required" now finds nothing and reads every body as required.
- Parameter gains Provenance, non-omitempty, and with it x-sunset promotion at the parameter position.
- Deprecation gains RemovalDate. x-sunset promotes into it rather than into RemovalVersion, so a consumer reading a removal date off the version field now finds it empty.
- Encoding gains Schema, giving contentSchema a home at scalar positions.
- Constraints.ExclusiveMin and ExclusiveMax change from bool to a decimal string carrying the bound itself, so the two dialects' exclusive bounds no longer lose one keyword to the other. The JSON type of both keys changed; a consumer decoding them as booleans fails rather than degrades.
0.5.0 moves the IR onto encoding/json/v2 and gives absence one spelling:
- Operation.Auth, Service.Auth and Server.Auth write nil (inherit) as an absent key rather than null. An empty list, explicitly public, is still [].
- A Value's bytes, list and object payloads, and a CtorValue's args, are omitted when empty rather than written as null.
- Strings use RFC 8785's minimal escaping, so <, > and & are written as themselves rather than as \u003c, \u003e and \u0026.
- Decoding refuses what it used to take in silence: a member the schema does not define, a duplicate name, a string that is not UTF-8, and a missing or foreign irVersion, which is read before any other member.
0.6.0 gives each kind of Provenance locator its own key. "pointer" holds only an RFC 6901 pointer; a line and column move to "position", and an IR pass's location in the document itself moves to "node". A consumer pinned to 0.5.0 knows neither new key and reads those findings as unlocated.
const MapKeySuffix = ".key"
MapKeySuffix ends the path of a value reached as a map key rather than as a field or an element, so a caller that treats the two differently can tell them apart.
const MaxWalkDepth = 4096
MaxWalkDepth bounds a WalkValues traversal (the bounded-recursion rule). Value trees — defaults, examples — nest deepest, and compilers cap their nesting far below this (the OpenAPI compiler at 128), so reaching the cap signals a pathological document rather than legitimate nesting. The walk reports truncation so a caller can say so instead of under-checking in silence.
const NoSource = -1
NoSource is the Source value for a node that addresses no input file. An IR pass reporting on the document it was handed has no source to name, and a shared primitive, reached by kind from every source, has no one source to name. Every other index — 0 included — names a file the document actually loaded, which would make a renderer fabricate a location.
It is the only out-of-table Source value the IR declares: irverify accepts it and reports every other index that addresses no declared source, so a producer that invents a second sentinel is caught rather than tolerated.
Variables ¶
var ( // ErrVersionAbsent reports a document that declares no irVersion: a // producer that never stamped it (ir-design §2.1). ErrVersionAbsent = errors.New("no irVersion") // ErrVersionIncompatible reports a document stamped with an irVersion // CompatibleVersion rejects: another generation's document. ErrVersionIncompatible = errors.New("incompatible irVersion") )
Functions ¶
func CanonicalWords ¶
CanonicalWords renders name as the neutral lower_snake word sequence ir.Naming.Canonical promises: it splits on every non-word rune and on camel-case and letter/digit boundaries, lowercases, and joins with "_". It holds no acronym opinion beyond boundary detection; casing policy is an emitter concern.
It lives beside the field it fills rather than in the compiler framework because Canonical is ABI and the field's own doc comment above already states this grammar in prose. Three copies of it disagreed about exactly that (GitHub #163), and while an architecture test now stops a fourth being written, that rule reaches only this repository's own compilers. A Document arriving any other way — decoded from JSON, produced by a compiler outside this tree, rewritten by a pass — is held by irverify alone, and irverify is Layer 0: with the grammar here it can recompute a canonical from the source beside it and see a segmentation that lowercasing had erased the evidence of.
A name written with no word rune in it at all ("***") canonicalizes to the empty string. Naming.Source keeps the spelling either way, so nothing is lost — there is simply no word sequence to report, and inventing one from the punctuation would be a naming opinion the IR does not hold.
func CompatibleVersion ¶
CompatibleVersion reports whether a document stamped version can be read by this build. It is the predicate behind the compatibility policy in ir-design §2.1, and what a consumer holding a decoded document asks before interpreting any other field in it.
The comparison is exact. Every bump this constant has taken changed the JSON shape, so there is no looser relation to admit: a differing patch, a prerelease suffix, and a value that is not a version at all are equally unreadable. Accepting a neighbouring version would mean claiming to know what changed between the two, which is the knowledge a version exists because nobody has.
An empty version is incompatible too, but a caller that can act on the difference should test for it separately: absence is a producer that never stamped the document, while an unrecognized stamp is a fault in the pairing.
func HasError ¶
func HasError(diags []Diagnostic) bool
HasError reports whether diags contains at least one error-severity diagnostic. It is FirstError's boolean-only form, for call sites — an if condition, a fuzz-target skip gate — that only need the yes/no answer and cannot consume a two-value return.
func IDPath ¶
IDPath returns the path segment of a well-formed id — everything after the kind and the space — and whether id carries one at all.
func IDSpace ¶
IDSpace returns the space segment of a well-formed id — the segment between the kind and the path — and whether id is well-formed at all. An ID that is not yields no space rather than a guess at one.
func IsNilTypeDef ¶
IsNilTypeDef reports whether td is a nil TypeDef — an untyped nil interface or a typed nil pointer.
A typed nil satisfies a type switch case and a comma-ok assertion alike, so matching a kind is no evidence the value is safe to dereference; TypeDef.Kind and TypeDef.Common both panic on one. Every walk over a type registry screens entries through this before reading them.
func RefNoun ¶
RefNoun names the reference class an ID type identifies: its type name minus the ID suffix, lowercased ("ChannelID" → "channel"). Both of Morphic's checkers spell a dangling-reference code with it, so one defect reads under one code whichever of them reports it.
func WalkValues ¶
WalkValues performs a bounded, cycle-guarded reflection traversal of root, calling visit on every value it reaches together with the path it was reached by; returning false from visit skips that value's children. It reports whether the depth cap cut the walk short. visit is required, and path is the segment every reported location is rooted at — DocumentPath for a walk over a whole document.
Deriving what a document holds from the value graph instead of naming fields is what makes a check built on it complete: a field added to the IR is covered the moment it exists, which a hand-written enumeration cannot promise. Map keys are reached as well as values, because some are references in their own right — Service.Renames is map[TypeID]Naming, where the key is the reference and the value is not.
Paths spell fields joined by ".", slice indices and map keys in brackets, and an embedded field contributes no segment of its own: JSON inlines it and Go promotes its fields, so "….TypeCommon.Examples[0]" names a step neither encoding has — the example is reached as "….Examples[0]" in both.
A value reached through an unexported field is read-only, and Interface() panics on one where FieldByName does not, so a visitor reads the fields it needs rather than converting the value back to its Go type. That is what lets a caller be an oracle that never crashes on a malformed document.
Map entries are visited in rendered-key order rather than Go's randomized map order. A pointer reachable from two entries is descended into at whichever the walk reaches first, so a random order yields a different path for it — and so a different result set, not merely a different order — on each run, which no later sort can repair (invariant 7).
Byte sequences are skipped. Unmodeled and RawConfig payloads are jsontext.Value and are the largest values a document holds, while a uint8 element is none of the things a visitor looks for — no typed ID, no Unmodeled map, no Provenance, no index carrier. Descending one costs a reflect.Value and a formatted path per byte for nothing: verifying a document holding one 256 KB payload measured 88ms without this skip against 22µs with it, for the same result. Since the result is the same either way, a test asserting the result cannot notice the skip going missing — one that counts what the walk reaches is what holds it.
func WellFormedID ¶
WellFormedID reports whether id has the shape kind requires: the kind prefix, a non-empty space, and an optional path, with no empty segment before the path. A space with no path is an ID in its own right — the space names one node — which is why the path is optional.
Shape alone cannot catch every malformed ID. One that lost the separator between its space and its path ("t/anonaddr") reads as a space named "anonaddr" and is indistinguishable from a legitimate one here; what catches that is the path agreeing with the provenance pointer it was derived from, which irverify checks alongside this.
Types ¶
type AdditionalMode ¶
type AdditionalMode string
AdditionalMode describes the openness of a model's property set beyond its declared properties and AdditionalProps (ir-design §4.3).
const ( // AdditionalUnspecified leaves openness unspecified (open by JSON Schema default). AdditionalUnspecified AdditionalMode = "" // AdditionalClosed forbids properties beyond the declared set // (additionalProperties: false, closed-by-construction records). AdditionalClosed AdditionalMode = "closed" // AdditionalClosedAfterComposition closes the set once composition is resolved // (unevaluatedProperties: false). AdditionalClosedAfterComposition AdditionalMode = "closed_after_composition" )
Additional-property modes.
type AdditionalProps ¶
type AdditionalProps struct {
// Value is the value schema for catch-all properties.
Value TypeRef `json:"value"`
// Key is the key schema; nil = string keys.
Key *TypeRef `json:"key,omitzero"`
// Patterns are key-pattern-scoped value schemas (JSON Schema patternProperties).
Patterns []PatternProps `json:"patterns,omitempty"`
}
AdditionalProps describes a model's map-like catch-all for undeclared properties (ir-design §4.3).
type Any ¶
type Any struct {
TypeCommon
}
Any is a schemaless type (ir-design §4.6).
func (*Any) MarshalJSONTo ¶
MarshalJSONTo encodes the Any with an adjacent "kind" tag.
type AuthKind ¶
type AuthKind string
AuthKind names one authentication mechanism (ir-design §9). X509 is distinct from mutual_tls (certificate as credential vs mutual verification); compilers must not conflate them.
const ( // AuthKindAPIKey is an API key in a header, query, cookie, or transport slot. AuthKindAPIKey AuthKind = "apiKey" // AuthKindHTTPBasic is HTTP Basic authentication. AuthKindHTTPBasic AuthKind = "http_basic" // AuthKindHTTPBearer is HTTP Bearer-token authentication. AuthKindHTTPBearer AuthKind = "http_bearer" // AuthKindOAuth2 is OAuth 2.0 with one or more flows. AuthKindOAuth2 AuthKind = "oauth2" // AuthKindOpenIDConnect is OpenID Connect discovery. AuthKindOpenIDConnect AuthKind = "openid_connect" // AuthKindMutualTLS is mutual TLS verification. AuthKindMutualTLS AuthKind = "mutual_tls" // AuthKindUserPassword is a transport user/password credential. AuthKindUserPassword AuthKind = "user_password" // AuthKindX509 is an X.509 certificate used as a credential. AuthKindX509 AuthKind = "x509" // AuthKindSymmetricEncryption is symmetric-key encryption. AuthKindSymmetricEncryption AuthKind = "symmetric_encryption" // AuthKindAsymmetricEncryption is asymmetric-key encryption. AuthKindAsymmetricEncryption AuthKind = "asymmetric_encryption" // AuthKindSASLPlain is SASL PLAIN. AuthKindSASLPlain AuthKind = "sasl_plain" // AuthKindSASLSCRAMSHA256 is SASL SCRAM-SHA-256. AuthKindSASLSCRAMSHA256 AuthKind = "sasl_scram_sha256" // AuthKindSASLSCRAMSHA512 is SASL SCRAM-SHA-512. AuthKindSASLSCRAMSHA512 AuthKind = "sasl_scram_sha512" // AuthKindSASLGSSAPI is SASL GSSAPI (Kerberos). AuthKindSASLGSSAPI AuthKind = "sasl_gssapi" // AuthKindCustom is a custom/unmodeled scheme. AuthKindCustom AuthKind = "custom" )
Authentication mechanisms.
func (AuthKind) Valid ¶
Valid reports whether k is one of the mechanisms declared above. AuthKind is a bare string enum, so nothing rejects an empty, misspelled or stale value on the wire, and a scheme naming no mechanism is indistinguishable from one naming oauth2 to every structural check that reads only its key and its ID. irverify calls this so such a scheme is reported as the compiler bug it is.
type AuthRequirement ¶
type AuthRequirement struct {
// Schemes must all be satisfied together to fulfill this option.
Schemes []SchemeUse `json:"schemes,omitempty"`
}
AuthRequirement is one authentication option: all its SchemeUses must be satisfied together (ir-design §9). A slice of AuthRequirement is an OR across options in priority order; an empty option means "no auth is one acceptable choice".
type AuthScheme ¶
type AuthScheme struct {
// ID is the scheme's stable synthetic identity.
ID AuthID `json:"id,omitempty"`
// Name is the scheme's naming.
Name Naming `json:"name"`
// Kind is the authentication mechanism.
Kind AuthKind `json:"kind,omitempty"`
// Docs is the scheme's documentation.
Docs Docs `json:"docs"`
// Deprecation marks the scheme as deprecated.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// In is the apiKey location: header | query | cookie | user | password.
In string `json:"in,omitempty"`
// KeyName is the apiKey name.
KeyName string `json:"keyName,omitempty"`
// Scheme is the HTTP scheme (bearer, basic, digest…); also legal for apiKey
// (Smithy @httpApiKeyAuth scheme).
Scheme string `json:"scheme,omitempty"`
// BearerFormat is the bearer-token format hint.
BearerFormat string `json:"bearerFormat,omitempty"`
// Flows are the OAuth2 flows; device flow's deviceAuthorizationUrl rides
// OAuthFlow.AuthorizationURL.
Flows []OAuthFlow `json:"flows,omitempty"`
// OAuth2MetadataURL is the RFC 8414 authorization-server metadata URL
// (OpenAPI 3.2).
OAuth2MetadataURL string `json:"oauth2MetadataURL,omitempty"`
// OpenIDConnectURL is the OpenID Connect discovery URL.
OpenIDConnectURL string `json:"openIDConnectURL,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the scheme came from.
Provenance Provenance `json:"provenance"`
}
AuthScheme is a named authentication scheme in Document.Auth (ir-design §9).
type Availability ¶
type Availability struct {
// Added lists the version labels at which the entity was added, ordered;
// multiple entries with Removed support add/remove/re-add cycles.
Added []string `json:"added,omitempty"`
// Removed lists the version labels at which the entity was removed.
Removed []string `json:"removed,omitempty"`
// Deprecated is the version at which the entity was deprecated.
Deprecated string `json:"deprecated,omitempty"`
// RenamedFrom records prior names by version.
RenamedFrom []VersionedName `json:"renamedFrom,omitempty"`
// TypeChangedFrom records prior property/return types by version (TypeSpec
// @typeChangedFrom).
TypeChangedFrom []VersionedType `json:"typeChangedFrom,omitempty"`
// RequiredChanged records optionality flips by version (TypeSpec
// @madeOptional/@madeRequired); the slice pass reconstructs Required for older
// snapshots from it.
RequiredChanged []VersionedBool `json:"requiredChanged,omitempty"`
}
Availability stores the versioning timeline of an entity (ir-design §11), following the TypeSpec model; the version-slice pass produces a concrete snapshot document per version. Formats without versioning leave this nil.
type BigVal ¶
type BigVal string
BigVal is an arbitrary-precision numeric value carried as its decimal string form. The IR never stores float64 (the TypeSpec Numeric lesson); helpers may convert through math/big at the boundary.
A BigVal is always a JSON-valid numeric literal: NewBigVal canonicalizes non-JSON but numerically valid spellings (a leading dot as in ".5", a trailing dot as in "5.", a leading "+", a redundant leading zero as in "09") into JSON form, leaving every significant digit, the exponent, and its case untouched — so a stored value round-trips through JSON unchanged.
func NewBigVal ¶
NewBigVal validates s as a decimal or scientific-notation numeric literal and returns it in canonical JSON form. It rejects the empty string, hex, a binary (p/P) exponent, NaN, and infinities. It never rounds or reformats the significant digits: an out-of-float64-range magnitude, a high-precision decimal, and an exponential literal are all preserved verbatim (only JSON-invalid affixes are normalized).
type Callback ¶
type Callback struct {
// Expression is the runtime expression that resolves the callback URL.
Expression string `json:"expression,omitempty"`
// Operations are the callback operations keyed by that expression; no entry
// is empty.
Operations []OpID `json:"operations,omitempty"`
}
Callback is an out-of-band operation set keyed by a runtime expression (ir-design §8.1).
type Channel ¶
type Channel struct {
// ID is the channel's stable synthetic identity.
ID ChannelID `json:"id,omitempty"`
// Name is the channel's naming.
Name Naming `json:"name"`
// Address is the topic/routing key/path, may contain {params}; nil =
// unknown/runtime-assigned address (reply channels and dynamic topics; SDKs
// expose a runtime address arg).
Address *string `json:"address,omitzero"`
// Docs is the channel's documentation.
Docs Docs `json:"docs"`
// Tags are the channel's tag memberships.
Tags []string `json:"tags,omitempty"`
// Params are the channel's address parameters.
Params []Parameter `json:"params,omitempty"`
// Messages is the channel's message set; messages live in Document.Messages.
// No entry is empty.
Messages []MessageID `json:"messages,omitempty"`
// Servers indexes into Document.Servers scoped to this channel.
Servers []int `json:"servers,omitempty"`
// Bindings holds protocol-specific config ("kafka", "amqp", "ws", "mqtt")
// kept as namespaced raw config.
Bindings map[string]RawConfig `json:"bindings,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the channel came from.
Provenance Provenance `json:"provenance"`
}
Channel is an event/messaging endpoint: an AsyncAPI channel, a webhook, a subscription, or an OTP process (ir-design §8.3). Its messages live in Document.Messages and are referenced here by identity.
type Constraints ¶
type Constraints struct {
// Min is the inclusive lower numeric bound (JSON Schema minimum): an
// admissible value is >= it. nil = this position declared none.
Min *BigVal `json:"min,omitzero"`
// Max is the inclusive upper numeric bound (JSON Schema maximum): an
// admissible value is <= it. nil = this position declared none.
Max *BigVal `json:"max,omitzero"`
// ExclusiveMin is the exclusive lower numeric bound (JSON Schema
// exclusiveMinimum): an admissible value is > it. nil = this position
// declared none.
//
// It is a bound of its own rather than a flag on Min, because the two
// keywords are independent and conjunctive: a schema may declare both, both
// then apply, and the effective floor is whichever admits fewer values. One
// slot per side would have to keep that one and lower the other some other
// way, which is a change to the weaker keyword that a consumer diffing two
// revisions of a spec could not see at all (GitHub #425).
ExclusiveMin *BigVal `json:"exclusiveMin,omitzero"`
// ExclusiveMax is the exclusive upper numeric bound (JSON Schema
// exclusiveMaximum): an admissible value is < it. nil = this position
// declared none. It is independent of Max exactly as ExclusiveMin is of Min.
ExclusiveMax *BigVal `json:"exclusiveMax,omitzero"`
// MultipleOf constrains the value to a multiple of this number.
MultipleOf *BigVal `json:"multipleOf,omitzero"`
// Precision bounds the total decimal digits (Avro decimal, XSD totalDigits,
// OData Edm.Decimal).
Precision *int64 `json:"precision,omitzero"`
// Scale bounds the fractional decimal digits (XSD fractionDigits).
Scale *int64 `json:"scale,omitzero"`
// MinLength is the minimum string/bytes length.
MinLength *int64 `json:"minLength,omitzero"`
// MaxLength is the maximum string/bytes length.
MaxLength *int64 `json:"maxLength,omitzero"`
// Pattern is an ECMA-262 regex as written; emitters translate or drop it with
// a diagnostic.
Pattern string `json:"pattern,omitempty"`
// PatternMessage is a human-readable validation message (TypeSpec @pattern's
// second argument).
PatternMessage string `json:"patternMessage,omitempty"`
// MinItems is the minimum collection length.
MinItems *int64 `json:"minItems,omitzero"`
// MaxItems is the maximum collection length.
MaxItems *int64 `json:"maxItems,omitzero"`
// UniqueItems requires distinct collection elements.
UniqueItems bool `json:"uniqueItems"`
// MinProps is the minimum number of properties.
MinProps *int64 `json:"minProps,omitzero"`
// MaxProps is the maximum number of properties.
MaxProps *int64 `json:"maxProps,omitzero"`
}
Constraints restricts the admissible values of a scalar, list, string, or numeric type (ir-design §5.3). Numeric bounds are arbitrary-precision decimal strings, never float64.
Every Constraints is position-scoped: it holds what the position carrying it declared, and nothing is ever copied across a TypeRef. Bounds conjoin rather than override, so the effective restriction on a value is this struct together with the Constraints of every node reached from the position's TypeRef, and an absent Constraints means that position declared no bound — never that the value is unbounded (ir-design §12.2). Documentation, deprecation and Default are the other way round: a compiler merges them from a $ref's target onto the referencing carrier with use-site precedence, so a use site already carries those and resolves nothing to read them.
type Contact ¶
type Contact struct {
// Name is the contact name.
Name string `json:"name,omitempty"`
// URL is the contact URL.
URL string `json:"url,omitempty"`
// Email is the contact email address.
Email string `json:"email,omitempty"`
}
Contact is the API contact information (OpenAPI/AsyncAPI info.contact).
type Content ¶
type Content struct {
// MediaType is "application/json", "multipart/form-data", or "" for non-HTTP.
MediaType string `json:"mediaType,omitempty"`
// SchemaFormat is the schema language the type graph was lowered from, in
// media-type form (AsyncAPI multiFormatSchema: Avro/Protobuf/RAML/…);
// "" = source-native. The verbatim source schema is kept in Unmodeled.
SchemaFormat string `json:"schemaFormat,omitempty"`
// Type is the content's type.
Type TypeRef `json:"type"`
// Item is the element shape of a sequential stream declared per media type
// (OpenAPI 3.2 itemSchema for SSE/JSONL/json-seq); nil = not sequential.
Item *TypeRef `json:"item,omitzero"`
// ItemEncoding is the wire encoding of a sequential stream's item
// (3.2 itemEncoding); nil = none declared. It is singular like Item because
// it governs every item alike; positional per-item encoding has no form here
// and stays in Unmodeled.
ItemEncoding *PartEncoding `json:"itemEncoding,omitzero"`
// Encoding holds multipart/form per-property (part) wire config, keyed by the
// part property's PropID; no key is empty.
Encoding map[PropID]PartEncoding `json:"encoding,omitempty"`
// File marks the body as a file upload/download (TypeSpec file bodies, binary
// payloads).
File *FileInfo `json:"file,omitzero"`
// Examples are content-level example values.
Examples []Example `json:"examples,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
Content is one media-type view of a Payload (ir-design §7.2).
type CtorValue ¶
type CtorValue struct {
// Scalar identifies the scalar whose constructor is invoked; never empty.
Scalar TypeID `json:"scalar,omitempty"`
// Name is the constructor name ("fromISO", "now", custom inits).
Name string `json:"name,omitempty"`
// Args are the constructor arguments in source order. No arguments and a
// nil list are the same call, so an empty list is omitted.
Args []Value `json:"args,omitempty"`
}
CtorValue captures a value built by a named scalar constructor, such as utcDateTime.now() or plainDate.fromISO("2024-05-06"). Such values are inherently non-literal, so compilers must not fold them (ir-design §6).
type Deprecation ¶
type Deprecation struct {
// Message explains the deprecation and any migration path.
Message string `json:"message,omitempty"`
// Since is the version in which the entity was deprecated.
Since string `json:"since,omitempty"`
// RemovalVersion is the version in which the entity is scheduled for
// removal. A removal the source states as a date belongs in RemovalDate.
RemovalVersion string `json:"removalVersion,omitempty"`
// RemovalDate is the date on which the entity is scheduled for removal —
// the fact an RFC 8594 Sunset carries, and what the OpenAPI x-sunset
// convention echoing it holds.
//
// It is the source's own text, neither parsed nor normalized: the IR
// records which fact the document stated and leaves the calendar to the
// consumer, since no source format defines the field and so none defines
// its format either.
RemovalDate string `json:"removalDate,omitempty"`
}
Deprecation marks an entity as deprecated with optional migration guidance.
A scheduled removal has two fields because a version and a date are two facts, not two spellings of one: a document may state either or both ("gone in 3.0.0", "gone on 2026-08-01"), and neither is derivable from the other without a release calendar the IR does not have. Keeping them apart is what lets a consumer compare a scheduled removal against a release date without re-parsing the string to work out which kind it was handed.
type Diagnostic ¶
type Diagnostic struct {
Severity Severity `json:"severity"`
Code string `json:"code"`
Message string `json:"message"`
Provenance Provenance `json:"provenance"`
}
Diagnostic is a typed report from a compiler or pass. Codes are stable strings ("openapi/unresolved-ref", "ir/dangling-type-ref") so CI can allowlist them.
func FirstError ¶
func FirstError(diags []Diagnostic) (Diagnostic, bool)
FirstError returns the first error-severity diagnostic in diags and true, or the zero Diagnostic and false if none exists — a two-value return so a zero-value error diagnostic can't be mistaken for "no error found".
Compilers and the harness use it to tell a refusal (a real spec problem) from advisory warnings that must be carried forward, and to report the offending diagnostic once a refusal is confirmed.
func NewDiagnostic ¶
func NewDiagnostic(sev Severity, code, message string, prov Provenance) Diagnostic
NewDiagnostic builds a Diagnostic, coercing message to well-formed UTF-8 so the enclosing Document can be written at all: a third-party validator can emit a truncated multibyte rune in its error text, and a Document refuses to encode a string that is not UTF-8 rather than rewrite it to U+FFFD. irverify's ir/invalid-utf8 check flags any message that still reaches a Document ill-formed; strings.ToValidUTF8 doesn't allocate when message is already valid, so the common path costs one scan.
type Discriminator ¶
type Discriminator struct {
// Property is the property carrying the tag in model hierarchies; empty when
// PropertyName or Index locates the tag instead.
Property PropID `json:"property,omitempty"`
// PropertyName is the wire name of the tag property in unions, where the
// property exists on no single model (TypeSpec @discriminated
// discriminatorPropertyName, OpenAPI discriminator on oneOf).
PropertyName string `json:"propertyName,omitempty"`
// Index is the 0-based tuple element carrying the tag Literal (Erlang tagged
// tuples, JSON arrays with a const head via prefixItems).
Index *int `json:"index,omitzero"`
// Mapping maps wire value to subtype; nil = infer by type name; no value is
// empty.
Mapping map[string]TypeID `json:"mapping,omitempty"`
// Default is the variant to use when the tag is absent/unrecognized (OpenAPI
// 3.2 defaultMapping); zero = none.
Default TypeID `json:"default,omitempty"`
// Envelope is "" for an inline tag or "object" for a {kind, value} wrapper
// (TypeSpec @discriminated envelope).
Envelope string `json:"envelope,omitempty"`
// EnvelopeValueName is the wire name of the envelope's value property (default
// "value"); meaningful only when Envelope == "object".
EnvelopeValueName string `json:"envelopeValueName,omitempty"`
// Inferred marks a discriminator discovered heuristically, not declared.
Inferred bool `json:"inferred"`
}
Discriminator locates and maps the tag that selects a variant in a polymorphic model hierarchy or union (ir-design §4.3). Exactly one of Property, PropertyName, or Index locates the tag.
type Docs ¶
type Docs struct {
// Summary is a short single-line description.
Summary string `json:"summary,omitempty"`
// Description is CommonMark; it may contain {t:TypeID} cross-reference
// tokens that emitters resolve to language-appropriate links.
Description string `json:"description,omitempty"`
// ExternalDocs links to supplementary documentation.
ExternalDocs []Link `json:"externalDocs,omitempty"`
}
Docs is the human-readable documentation attached to a named entity (ir-design §12).
type Document ¶
type Document struct {
// IRVersion is the version of the IR schema itself (semver).
IRVersion string `json:"irVersion,omitempty"`
// Name is the API title.
Name string `json:"name,omitempty"`
// Version is the source-declared API version string.
Version string `json:"version,omitempty"`
// Docs is the document-level documentation.
Docs Docs `json:"docs"`
// Contact is the API contact (OpenAPI/AsyncAPI info.contact).
Contact *Contact `json:"contact,omitzero"`
// License is the API license (OpenAPI/AsyncAPI info.license).
License *License `json:"license,omitzero"`
// TermsOfService is the terms-of-service URL or text.
TermsOfService string `json:"termsOfService,omitempty"`
// Services holds one or more services; multi-service documents are normal
// (TypeSpec, stitching).
Services []Service `json:"services,omitempty"`
// Types is the type registry — the only owner of TypeDefs.
Types TypeRegistry `json:"types,omitempty"`
// Channels is the event/messaging layer (AsyncAPI, webhooks, subscriptions,
// OTP processes).
Channels map[ChannelID]Channel `json:"channels,omitempty"`
// Messages is the message registry; messages are reused across channels and
// referenced by identity from operations and replies (AsyncAPI 3).
Messages map[MessageID]Message `json:"messages,omitempty"`
// Auth is the auth scheme registry.
Auth map[AuthID]AuthScheme `json:"auth,omitempty"`
// Servers holds the endpoint templates.
Servers []Server `json:"servers,omitempty"`
// TagDefs is the tag metadata registry; tag membership stays []string on the
// tagged nodes.
TagDefs []TagDef `json:"tagDefs,omitempty"`
// Versions holds the ordered version labels when availability metadata is used.
Versions []string `json:"versions,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Diagnostics is accumulated by the compiler and passes; not part of API
// meaning.
Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
// Sources describes the input files: format, path, content hash.
Sources []SourceInfo `json:"sources,omitempty"`
}
Document is the root of a Morphic IR document (ir-design §2). It is self-contained: no node references anything outside it.
func (*Document) MarshalJSONTo ¶
MarshalJSONTo encodes the Document under canonicalOptions, whatever options the caller passed. Only whitespace, such as indentation, stays the caller's. The Document is the unit this holds for (invariant 7): a sub-structure encoded on its own takes the caller's options, so sorting its maps takes json.Deterministic(true).
func (*Document) UnmarshalJSONFrom ¶
UnmarshalJSONFrom decodes a Document this build can read and refuses any other before interpreting a member of it (ir-design §2.1): a missing or foreign irVersion, a member the schema does not define, a duplicate name, or a string that is not UTF-8. The refusals do not depend on the caller's options, because the document is decoded again here under the IR's own.
type Encoding ¶
type Encoding struct {
// Name is the encoding scheme ("rfc3339", "base64", "zigzag", "packed",
// "delimited", format strings, ...).
Name string `json:"name,omitempty"`
// WireType is the on-wire primitive when it differs from the logical type
// (utcDateTime encoded as int32; bytes as base64 string).
WireType *TypeRef `json:"wireType,omitzero"`
// MediaType is the content media type of the value itself (Smithy @mediaType,
// JSON Schema contentMediaType); "" = none.
MediaType string `json:"mediaType,omitempty"`
// Schema is the shape the encoded value has once decoded — what a base64 blob
// or an application/json-typed string holds (JSON Schema contentSchema); nil =
// unstated. It is a reference into the type registry like any other schema,
// never the encoded value's own type.
Schema *TypeRef `json:"schema,omitzero"`
}
Encoding is the logical-type / encoding-name / wire-type triple that reifies TypeSpec @encode and absorbs OpenAPI format and Protobuf wire variants, plus the media type and decoded shape of an encoded payload (ir-design §5.3). Property encoding overrides scalar encoding.
type Enum ¶
type Enum struct {
TypeCommon
// ValueType is the primitive type of the members' values.
ValueType PrimKind `json:"valueType"`
// Members are the enum's members, in source order.
Members []EnumMember `json:"members,omitempty"`
// Closed is false for open/extensible enums: unknown values must be
// representable.
Closed bool `json:"closed"`
// Flags marks bitfield semantics.
Flags bool `json:"flags"`
// FallbackMember is the wire name of the member to substitute for an unknown
// value (Avro enum default symbol); "" = none.
FallbackMember string `json:"fallbackMember,omitempty"`
}
Enum is a closed or open set of named values (ir-design §4.5).
func (*Enum) MarshalJSONTo ¶
MarshalJSONTo encodes the Enum with an adjacent "kind" tag.
type EnumMember ¶
type EnumMember struct {
// Name is the member's naming.
Name Naming `json:"name"`
// Value is the member's typed value, matching Enum.ValueType.
Value Value `json:"value"`
// WireName is the serialized form when it differs from Value (rare).
WireName string `json:"wireName,omitempty"`
// Docs is the member's documentation.
Docs Docs `json:"docs"`
// Deprecation marks the member as deprecated.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// Availability records the member's versioning timeline (TypeSpec @added on
// EnumMember).
Availability *Availability `json:"availability,omitzero"`
// Examples are typed example values for the member.
Examples []Example `json:"examples,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
EnumMember is one member of an Enum (ir-design §4.5).
type ErrorCase ¶
type ErrorCase struct {
// Name is the error naming for formats with named errors; Hint elsewhere —
// for OpenAPI, the responses-map key as declared and then neutralized ("404",
// "5_xx", "default"). Only a key that neutralizes to itself round-trips.
Name Naming `json:"name"`
// Conditions are the status codes/ranges this error maps to.
Conditions ResponseConditions `json:"conditions"`
// Payload is the error body, one Content per media type; nil = no body. The
// error-flagged models an error case references are its contents' types.
Payload *Payload `json:"payload,omitzero"`
// Headers are the error response's metadata fields — Retry-After and the
// rate-limit family live here.
Headers []Property `json:"headers,omitempty"`
// Fault is "" | "client" | "server" — protocol-neutral fault classification
// (Smithy @error; OpenAPI 4XX/5XX is its HTTP lowering). Drives exception
// hierarchies and default status synthesis.
Fault string `json:"fault,omitempty"`
// Retryable reports whether the error is retryable (Smithy @retryable);
// nil = unknown.
Retryable *bool `json:"retryable,omitzero"`
// Throttling reports that the error is retryable specifically due to
// throttling — a distinct backoff class (Smithy @retryable(throttling: true));
// nil = unknown.
Throttling *bool `json:"throttling,omitzero"`
// Docs is the error case's documentation.
Docs Docs `json:"docs"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
ErrorCase is a declared failure shape of an Operation (ir-design §7.2).
An error case is a response, so the four fields it shares with Response — Name, Conditions, Payload, Headers — are spelled and lowered identically, and the failure classification below them is what separates the two nodes.
The sharing is those four fields, not everything Response holds: StatusCodeProp stays success-only, because the formats that populate an output member from the status line (Smithy @httpResponseCode, TypeSpec's non-literal @statusCode) classify errors by @httpError instead, so an error case has no runtime status to bind a member to.
type ErrorExample ¶
type ErrorExample struct {
// Type is the error type produced by the scenario.
Type TypeRef `json:"type"`
// Content is the error value.
Content Value `json:"content"`
}
ErrorExample is the error arm of an operation-scenario Example.
type EventInfo ¶
type EventInfo struct {
// ContentType is the per-event content type (TypeSpec @Events.contentType).
ContentType string `json:"contentType,omitempty"`
// Terminal reports that receiving this event ends the stream (TypeSpec
// @SSE.terminalEvent).
Terminal bool `json:"terminal"`
}
EventInfo carries per-event metadata when a union is an event stream's event set (ir-design §4.4).
type Example ¶
type Example struct {
// Name identifies the example.
Name string `json:"name,omitempty"`
// Summary is a short description of the example.
Summary string `json:"summary,omitempty"`
// Description is a long-form description of the example.
Description string `json:"description,omitempty"`
// Value is a single-value example (schemas, properties, parameters); for
// message examples it is the payload.
Value *Value `json:"value,omitzero"`
// Headers holds the correlated header values for message examples (AsyncAPI
// message examples are header+payload pairs — never split them).
Headers *Value `json:"headers,omitzero"`
// Input is the operation-scenario input, paired with Output or Error.
Input *Value `json:"input,omitzero"`
// Output is the operation-scenario success result paired with Input.
Output *Value `json:"output,omitzero"`
// Error ends the scenario in this error instead of Output.
Error *ErrorExample `json:"error,omitzero"`
// ExternalURL points to an externally hosted example.
ExternalURL string `json:"externalURL,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
Example is a documentation example. Field legality is contextual: Value/Headers apply to types, properties, parameters, contents, and messages; Input/Output/Error apply to operations. An Example is not meant to mix the two arms, though no pass currently checks that.
type External ¶
type External struct {
TypeCommon
// Identity is the external type's stable identity (e.g. "erlang:pid").
Identity string `json:"identity"`
// Package is the providing package.
Package string `json:"package,omitempty"`
// MinVersion is the minimum package version.
MinVersion string `json:"minVersion,omitempty"`
}
External is a well-known library type that no target can structurally model, resolved to a runtime handle by the emitter (TCGC external) (ir-design §4.6).
func (*External) MarshalJSONTo ¶
MarshalJSONTo encodes the External with an adjacent "kind" tag.
type Field ¶
type Field struct {
// Name is the member name.
Name string `json:"name,omitempty"`
// Value is the member value.
Value Value `json:"value"`
}
Field is one named member of a ValueObject, in source order.
type FileInfo ¶
type FileInfo struct {
// IsText reports textual vs binary contents.
IsText bool `json:"isText"`
// Contents is the declared contents scalar chain (string/bytes extensions);
// nil = bytes.
Contents *TypeRef `json:"contents,omitzero"`
// ContentTypes is the declared allowed content-type set (TypeSpec
// File<"image/png" | "image/jpeg">); runtime Content-Type comes from the file
// value.
ContentTypes []string `json:"contentTypes,omitempty"`
// ContentTypeDefault is the default used when the file value carries none.
ContentTypeDefault string `json:"contentTypeDefault,omitempty"`
// FilenameLocation is "content-disposition" (default) | "path" | "header".
FilenameLocation string `json:"filenameLocation,omitempty"`
// FilenameWireName is the wire name when FilenameLocation is path/header.
FilenameWireName string `json:"filenameWireName,omitempty"`
}
FileInfo describes a file-upload/download body (ir-design §7.2).
type GraphQLBinding ¶
type GraphQLBinding struct {
// Kind is "query" | "mutation" | "subscription".
Kind string `json:"kind,omitempty"`
// FieldPath is the entry-point field (nesting for namespaced schemas).
FieldPath []string `json:"fieldPath,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
GraphQLBinding maps an Operation onto a GraphQL entry point (ir-design §8.4).
type HTTPBinding ¶
type HTTPBinding struct {
// Method is the method as sent on the wire (OpenAPI 3.2 additionalOperations
// keys carry exact capitalization; QUERY and custom methods are legal).
Method string `json:"method,omitempty"`
// URITemplate is the RFC 6570 path template — the one true path
// representation.
URITemplate string `json:"uriTemplate,omitempty"`
// HostPrefix is the endpoint host prefix, may contain {param} labels
// (Smithy @endpoint).
HostPrefix string `json:"hostPrefix,omitempty"`
// disambiguated by request content (TypeSpec @sharedRoute); validate must not
// reject the duplicate, and single-route emitters must merge.
SharedRoute bool `json:"sharedRoute"`
// ParamBindings assigns each logical parameter its HTTP location.
ParamBindings []HTTPParamBinding `json:"paramBindings,omitempty"`
// RequestContentTypes are the priority-ordered request media types.
RequestContentTypes []string `json:"requestContentTypes,omitempty"`
// ResponseBodyPath sets the HTTP response body to this sub-field of the
// response type (gRPC transcoding response_body); nil = the whole payload.
ResponseBodyPath *PropPath `json:"responseBodyPath,omitzero"`
// SuccessStatus maps response index to primary status (denormalized
// convenience; conditions are the truth).
SuccessStatus map[int]int `json:"successStatus,omitempty"`
// Compression requires the client to compress the request body
// (Smithy @requestCompression).
Compression *RequestCompression `json:"compression,omitzero"`
// ChecksumRequired requires the client to send a payload checksum
// (Smithy @httpChecksumRequired).
ChecksumRequired bool `json:"checksumRequired"`
// PatchImplicitOptionality controls PATCH implicit optionality: nil = protocol
// default (PATCH projections make properties optional); false = disabled
// (TypeSpec @patch implicitOptionality).
PatchImplicitOptionality *bool `json:"patchImplicitOptionality,omitzero"`
// IsWebhook marks an inbound webhook operation (OpenAPI 3.1 webhooks).
IsWebhook bool `json:"isWebhook"`
// Callbacks are out-of-band operations keyed by runtime expressions.
Callbacks []Callback `json:"callbacks,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
HTTPBinding maps an Operation onto one HTTP method+path (ir-design §8.1).
type HTTPLocation ¶
type HTTPLocation string
HTTPLocation is where an HTTP parameter binds on the wire (ir-design §8.1).
const ( // HTTPLocationPath binds to a path template segment. HTTPLocationPath HTTPLocation = "path" // HTTPLocationQuery binds to a single query parameter. HTTPLocationQuery HTTPLocation = "query" // HTTPLocationQuerystring binds the whole query string serialized from one // schema (OpenAPI 3.2 in: querystring, combined with ContentType). HTTPLocationQuerystring HTTPLocation = "querystring" // HTTPLocationHeader binds to a request header. HTTPLocationHeader HTTPLocation = "header" // HTTPLocationCookie binds to a cookie. HTTPLocationCookie HTTPLocation = "cookie" // HTTPLocationBody binds the whole request body. HTTPLocationBody HTTPLocation = "body" // HTTPLocationBodyProperty binds to a property within the body model. HTTPLocationBodyProperty HTTPLocation = "body_property" // HTTPLocationHost binds to a host-prefix label (Smithy @hostLabel). HTTPLocationHost HTTPLocation = "host" )
HTTP parameter locations.
type HTTPParamBinding ¶
type HTTPParamBinding struct {
// Param is the Operation.Params name it binds.
Param string `json:"param,omitempty"`
// ParamPath is the nested source field within the logical param, when the
// binding targets a sub-field of a message-typed param (gRPC transcoding
// {book.name}, dotted query params); empty = the whole param. No entry is
// empty.
ParamPath []PropID `json:"paramPath,omitempty"`
// Location is where the parameter binds on the wire. host = the param fills a
// HostPrefix label (Smithy @hostLabel); querystring = the whole query string
// serialized from one schema (OpenAPI 3.2 in: querystring, with ContentType).
Location HTTPLocation `json:"location,omitempty"`
// WireName is the serialized parameter name.
WireName string `json:"wireName,omitempty"`
// Style is the serialization style: simple | form | label | matrix |
// deepObject | pipe/space-delimited.
Style string `json:"style,omitempty"`
// Explode overrides the default explode behavior; nil = default.
Explode *bool `json:"explode,omitzero"`
// AllowReserved permits reserved characters unescaped in the value.
AllowReserved bool `json:"allowReserved"`
// PathPattern is a multi-segment path pattern constraint for this param
// (gRPC transcoding {name=shelves/*/books/*}); "" = single segment. The URI
// template uses reserved expansion; emitters that cannot validate the pattern
// drop it with a diagnostic.
PathPattern string `json:"pathPattern,omitempty"`
// Prefix spreads a map-typed param as prefixed wire entries: prefixed headers
// (Smithy @httpPrefixHeaders) or catch-all query maps (@httpQueryParams with
// Prefix "").
Prefix string `json:"prefix,omitempty"`
// ContentType serializes the param as a media type (OpenAPI content-style
// params).
ContentType string `json:"contentType,omitempty"`
// BodyPath is, for body_property, where in the body model it lands
// (TypeSpec HttpProperty); no entry is empty.
BodyPath []PropID `json:"bodyPath,omitempty"`
}
HTTPParamBinding assigns one logical parameter its HTTP wire location (ir-design §8.1).
type IDDeclaration ¶
type IDDeclaration struct {
// Class is the Go type of the ID, which names the reference class the
// declaration settles.
Class reflect.Type
// ID is the declared identity.
ID string
// Path locates the declaring node, as [WalkValues] spells it.
Path string
}
IDDeclaration is one node's declaration of its own identity: the class of ID, the ID itself, and the path of the node that declares it.
func DeclaredIDs ¶
func DeclaredIDs(doc *Document) ([]IDDeclaration, bool)
DeclaredIDs returns every identity the nodes of doc declare — the ID a node carries for itself — in walk order, and reports whether the bounded walk was cut short.
A node's own ID is what a reference to it resolves against, and reading those declarations off the value graph rather than a list of carriers covers a new ID-bearing node the moment it exists. It answers the two questions DocumentRegistries cannot: which IDs a class declares when Document holds no map for it, and whether one ID is declared twice — which no map key can express, since a map has one entry per key however many nodes claim it.
Only a struct declaring the field itself counts. Every type node embeds TypeCommon and so promotes its ID, and counting promoted fields would reach each of them twice: a document with nothing wrong with it would read as one where every type ID is declared twice.
An empty ID declares no identity and is skipped: nothing can reference one, and treating several nodes that carry one as duplicates of each other would name the wrong defect.
Whether the empty ID is itself reported is a separate claim, and one this derivation does not make. A class Document keys a map by is covered by the key — an empty or disagreeing one is what irverify.checkRegistryKeys reads — and a class with no key, an Operation, a Service or a Property, is covered by irverify.checkDeclaredIDs walking for what this drops.
type Idempotency ¶
type Idempotency struct {
// Kind is the idempotency class.
Kind IdempotencyKind `json:"kind,omitempty"`
// TokenParam names the idempotency-token parameter; set only when Kind is
// IdempotencyToken.
TokenParam string `json:"tokenParam,omitempty"`
}
Idempotency is the resolved idempotency classification of an Operation. It reifies the spec's shorthand states unknown | safe | idempotent | idempotency_token(param); TokenParam is set only for the token kind (ir-design §7.2).
type IdempotencyKind ¶
type IdempotencyKind string
IdempotencyKind names the idempotency class of an Operation (ir-design §7.2).
const ( // IdempotencyUnknown means idempotency is undeclared. IdempotencyUnknown IdempotencyKind = "" // IdempotencySafe means the operation has no side effects (Smithy @readonly, // HTTP GET semantics). IdempotencySafe IdempotencyKind = "safe" // IdempotencyIdempotent means repeating the call has the same effect as one // call. IdempotencyIdempotent IdempotencyKind = "idempotent" // IdempotencyToken means idempotency is achieved via a client-supplied token // parameter named by Idempotency.TokenParam. IdempotencyToken IdempotencyKind = "idempotency_token" )
Idempotency kinds.
type License ¶
type License struct {
// Name is the license name.
Name string `json:"name,omitempty"`
// Identifier is the SPDX license identifier.
Identifier string `json:"identifier,omitempty"`
// URL is the license URL.
URL string `json:"url,omitempty"`
}
License is the API license information (OpenAPI/AsyncAPI info.license).
type Lifecycle ¶
type Lifecycle = string
Lifecycle names a visibility lifecycle class. It is an OPEN set; canonical values are "create", "read", "update", "delete", and "query". TypeSpec custom visibility classes lower as "<class>:<member>" strings so nothing is dropped (ir-design §5.2).
const ( // LifecycleCreate is the create lifecycle. LifecycleCreate Lifecycle = "create" // LifecycleRead is the read lifecycle. LifecycleRead Lifecycle = "read" // LifecycleUpdate is the update lifecycle. LifecycleUpdate Lifecycle = "update" // LifecycleDelete is the delete lifecycle. LifecycleDelete Lifecycle = "delete" // LifecycleQuery is the query lifecycle. LifecycleQuery Lifecycle = "query" )
Canonical lifecycle values.
type Link ¶
type Link struct {
// URL is the link target.
URL string `json:"url,omitempty"`
// Description labels the link.
Description string `json:"description,omitempty"`
}
Link is an external documentation reference.
type List ¶
type List struct {
TypeCommon
// Elem is the element type.
Elem TypeRef `json:"elem"`
// Constraints restricts minItems/maxItems/uniqueItems.
Constraints *Constraints `json:"constraints,omitzero"`
// Encoding is the container-level wire encoding (protobuf packed vs expanded
// repeated fields); it stacks with the element's own encoding.
Encoding *Encoding `json:"encoding,omitzero"`
}
List is an ordered collection (ir-design §4.6).
func (*List) MarshalJSONTo ¶
MarshalJSONTo encodes the List with an adjacent "kind" tag.
type Literal ¶
type Literal struct {
TypeCommon
// Value is the constant value.
Value Value `json:"value"`
}
Literal is a single constant value used as a type (const, single-value enum, discriminator pin) (ir-design §4.6).
func (*Literal) MarshalJSONTo ¶
MarshalJSONTo encodes the Literal with an adjacent "kind" tag.
type LongRunning ¶
type LongRunning struct {
// FinalStateVia is "operation-location" | "status-monitor" | "original-uri" |
// … — how the final state is located.
FinalStateVia string `json:"finalStateVia,omitempty"`
// PollingOperation is the declared poll op (Azure.Core @pollingOperation — a
// library convention, not core TypeSpec); when set, never empty.
PollingOperation *OpID `json:"pollingOperation,omitzero"`
// FinalOperation is the declared final-result op (Azure.Core @finalOperation);
// when set, never empty.
FinalOperation *OpID `json:"finalOperation,omitzero"`
// PollingType is the status-monitor type.
PollingType *TypeRef `json:"pollingType,omitzero"`
// FinalType is the final-result type.
FinalType *TypeRef `json:"finalType,omitzero"`
// ResultPath locates the final result within the polling response.
ResultPath *PropPath `json:"resultPath,omitzero"`
}
LongRunning describes long-running-operation semantics (ir-design §7.3).
type MapT ¶
type MapT struct {
TypeCommon
// Key is the key type.
Key TypeRef `json:"key"`
// Value is the value type.
Value TypeRef `json:"value"`
}
MapT is a keyed collection (Record/additionalProperties-only/proto map) (ir-design §4.6).
func (*MapT) MarshalJSONTo ¶
MarshalJSONTo encodes the MapT with an adjacent "kind" tag.
type Message ¶
type Message struct {
// ID is the message's stable synthetic identity.
ID MessageID `json:"id,omitempty"`
// Name is the message's naming.
Name Naming `json:"name"`
// Payload is the message payload.
Payload Payload `json:"payload"`
// Headers is the header schema — an object-constrained model hoisted into the
// type registry like any anonymous type (headers can be named, composed, even
// Avro-defined; and $message.header#/… paths need a type to resolve against).
// Emitters compute flat lists per §4.3.
Headers *TypeRef `json:"headers,omitzero"`
// CorrelationID locates the correlation value: In: "header" | "" (payload).
CorrelationID *PropPath `json:"correlationID,omitzero"`
// ContentType is the message content type.
ContentType string `json:"contentType,omitempty"`
// Tags are the message's tag memberships.
Tags []string `json:"tags,omitempty"`
// Docs is the message's documentation.
Docs Docs `json:"docs"`
// Deprecation marks the message as deprecated.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// Examples are correlated header+payload example pairs (Example.Headers +
// .Value).
Examples []Example `json:"examples,omitempty"`
// Bindings holds message-level protocol bindings (kafka message key, …).
Bindings map[string]RawConfig `json:"bindings,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the message came from.
Provenance Provenance `json:"provenance"`
}
Message is a reusable message shape referenced by channels, operations, and replies by identity (ir-design §8.3, AsyncAPI 3).
type MessageBinding ¶
type MessageBinding struct {
// Channel is the channel the operation acts on; never empty.
Channel ChannelID `json:"channel,omitempty"`
// Direction is send | receive (application perspective).
Direction MsgDirection `json:"direction,omitempty"`
// Messages are which of the channel's messages this operation uses; it must be
// a subset of the channel's own Messages, which pass.Validate checks. No entry
// is empty.
Messages []MessageID `json:"messages,omitempty"`
// Reply carries request-reply semantics; nil = none. A send-op with no Reply
// and no Responses is one-way (set Operation.OneWay).
Reply *Reply `json:"reply,omitzero"`
// Bindings holds operation-level protocol bindings kept raw (kafka
// groupId/clientId — constrain SDK client config).
Bindings map[string]RawConfig `json:"bindings,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
MessageBinding maps an Operation onto a messaging channel (ir-design §8.3).
type Model ¶
type Model struct {
TypeCommon
// Properties are the model's own properties, in source order.
Properties []Property `json:"properties,omitempty"`
// Base is the declared single inheritance parent (TypeSpec extends,
// allOf-as-inheritance).
Base *TypeRef `json:"base,omitzero"`
// Implements is N-ary interface conformance (GraphQL implements A & B);
// targets are Abstract models.
Implements []TypeRef `json:"implements,omitempty"`
// Mixins is composition without subtyping (Smithy mixins, TypeSpec spread,
// extra allOf entries).
Mixins []TypeRef `json:"mixins,omitempty"`
// AdditionalProps is a map-like catch-all alongside declared properties.
AdditionalProps *AdditionalProps `json:"additionalProps,omitzero"`
// Additional is the openness of the property set.
Additional AdditionalMode `json:"additional,omitempty"`
// Constraints bounds the property set's cardinality (JSON Schema
// minProperties/maxProperties on an object). Openness is Additional's
// concern; this is how many properties an instance may carry.
Constraints *Constraints `json:"constraints,omitzero"`
// Abstract marks a model that cannot be instantiated directly (GraphQL
// interface types).
Abstract bool `json:"abstract"`
// Positional serializes properties positionally as a tuple ordered by WireID
// (Erlang records).
Positional bool `json:"positional"`
// ExtensionRanges are wire-ID ranges reserved for third-party extension fields
// (protobuf extensions 100 to 199).
ExtensionRanges []WireIDRange `json:"extensionRanges,omitempty"`
// Discriminator is set on the polymorphic base.
Discriminator *Discriminator `json:"discriminator,omitzero"`
// DiscriminatorValue is set on each subtype: its wire tag value.
DiscriminatorValue string `json:"discriminatorValue,omitempty"`
// InputOnly marks GraphQL input types, which have distinct identity from
// output types.
InputOnly bool `json:"inputOnly"`
}
Model is a struct, object, or message shape (ir-design §4.3). Properties holds only the model's own properties; consumers walk Base, Implements, and Mixins for the full shape.
func (*Model) MarshalJSONTo ¶
MarshalJSONTo encodes the Model with an adjacent "kind" tag.
type MsgDirection ¶
type MsgDirection string
MsgDirection is the application-perspective direction of a MessageBinding (ir-design §8.3, AsyncAPI 3 semantics).
const ( // MsgDirectionSend means the application sends the message. MsgDirectionSend MsgDirection = "send" // MsgDirectionReceive means the application receives the message. MsgDirectionReceive MsgDirection = "receive" )
Message directions.
type Naming ¶
type Naming struct {
// Source is the name exactly as written in the spec ("user_id", a $ref
// name, a GraphQL field).
Source string `json:"source,omitempty"`
// Canonical is the IR-normalized identifier in neutral form: lower_snake
// words with no casing opinions. A word is letters and digits (plus the
// combining marks belonging to them); every other character in the source
// name separates two words rather than surviving into the sequence.
Canonical string `json:"canonical,omitempty"`
// Hint is a context-derived suggestion for an entity with no source name to
// render: a hoisted anonymous type (e.g. "connection_domain"), or one the
// source named with the empty string. It is in the same neutral form as
// Canonical and for the same reason — it is the only name such an entity
// has, so it is what an emitter renders its identifier from — however the
// position it was derived from was spelled.
Hint string `json:"hint,omitempty"`
// Aliases are alternate names for schema-resolution matching (Avro
// aliases). Versionless — rename history tied to version labels lives in
// Availability.RenamedFrom.
//
// An alias is a verbatim channel like Source, not a neutral one like
// Canonical: it is matched against a name another schema wrote, so the
// casing and punctuation are the value. An Avro alias is a full name
// ("com.example.User"), and neutralizing it to words would lose the
// separators and the case the match depends on. So no neutrality rule
// applies to an entry, and irverify holds only what is decidable without
// one:
//
// - every entry names something, since one with nothing visible in it
// matches nothing;
// - every entry decodes, since a document holding ill-formed UTF-8
// cannot be encoded at all;
// - no entry repeats another, or the entity's own Source, since either
// admits no name that was not already admitted — so a producer that
// wrote one built the list wrong.
//
// That such an entry is inert is also why a source declaring one is
// recorded once, with a Diagnostic naming it, rather than carried through:
// dropping it is not the lossy flattening invariant #2 forbids, because the
// same set of names resolves to this entity either way.
Aliases []string `json:"aliases,omitempty"`
}
Naming carries the identity of a named entity as words, never as a cased identifier: emitters apply casing, acronym policy, and reserved-word escaping (ir-design §3.2). Anonymous (hoisted) types have an empty Source and a Hint.
At least one of Source, Canonical and Hint is set. A Naming with all three empty names the entity to nobody, and every neutrality rule is vacuously true of it, so irverify reports it as ir/naming-absent.
type OAuthFlow ¶
type OAuthFlow struct {
// Kind is authorization_code | client_credentials | implicit | password |
// device.
Kind string `json:"kind,omitempty"`
// AuthorizationURL is the authorization endpoint; also carries device flow's
// deviceAuthorizationUrl.
AuthorizationURL string `json:"authorizationURL,omitempty"`
// TokenURL is the token endpoint.
TokenURL string `json:"tokenURL,omitempty"`
// RefreshURL is the token-refresh endpoint.
RefreshURL string `json:"refreshURL,omitempty"`
// Scopes maps scope names to their descriptions.
Scopes map[string]string `json:"scopes,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
OAuthFlow is one OAuth 2.0 flow of an AuthScheme (ir-design §9).
type OTPBinding ¶
type OTPBinding struct {
// Behaviour is "gen_server" | "gen_statem" | "gen_event".
Behaviour string `json:"behaviour,omitempty"`
// Kind is "call" (synchronous request→reply) | "cast" (fire-and-forget; the
// operation also sets OneWay) | "info" (raw message send).
Kind string `json:"kind,omitempty"`
// Process is the channel modeling the target process: Address = registered
// name (nil Address = unregistered/runtime pid); registration kind
// (local/global/via) in Channel.Bindings["otp"]. Never empty: an
// unregistered process is still a channel, with a nil Address.
Process ChannelID `json:"process,omitempty"`
// RequestTag is the tag of the request tuple (a symbol Value, e.g. 'get');
// nil = the whole term is the request.
RequestTag *Value `json:"requestTag,omitzero"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
OTPBinding maps an Operation onto an Erlang/OTP behaviour callback (ir-design §8.5).
type OpBindings ¶
type OpBindings struct {
// HTTP holds the HTTP mappings (OpenAPI/Swagger ops, TypeSpec @route, Smithy
// http traits). A slice: one operation may carry several HTTP mappings — gRPC
// transcoding additional_bindings — with the primary first.
HTTP []HTTPBinding `json:"http,omitempty"`
// RPC is the Protobuf/gRPC, Smithy RPC, or JSON-RPC binding.
RPC *RPCBinding `json:"rpc,omitzero"`
// Message is the AsyncAPI operation / webhook binding.
Message *MessageBinding `json:"message,omitzero"`
// GraphQL is the query/mutation/subscription field binding. GraphQL
// subscriptions bind here plus streaming fields on the core — not via
// MessageBinding.
GraphQL *GraphQLBinding `json:"graphql,omitzero"`
// OTP is the Erlang/OTP behaviour-operation binding (§8.5).
OTP *OTPBinding `json:"otp,omitzero"`
}
OpBindings holds the concrete-protocol mappings of an Operation's neutral core (ir-design §8). An operation has at least one binding; more than one is legal (a Smithy service exposed over both HTTP and RPC; gRPC with HTTP transcoding).
type Operation ¶
type Operation struct {
// ID is the operation's stable synthetic identity.
ID OpID `json:"id,omitempty"`
// Name is the operation's naming.
Name Naming `json:"name"`
// Docs is the operation's documentation.
Docs Docs `json:"docs"`
// Deprecation marks the operation as deprecated.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// Availability records the operation's versioning timeline.
Availability *Availability `json:"availability,omitzero"`
// Params are all logical inputs, protocol-unbound.
Params []Parameter `json:"params,omitempty"`
// Request is the body/message content; nil = none.
Request *Payload `json:"request,omitzero"`
// Responses are the ordered success and alternative-success responses.
Responses []Response `json:"responses,omitempty"`
// Errors are the declared failure shapes.
Errors []ErrorCase `json:"errors,omitempty"`
// OneWay marks fire-and-forget operations for which no response ever exists
// (OTP cast, AsyncAPI send-without-reply, Thrift oneway, JSON-RPC
// notifications). Distinct from a response with no body (an ack still
// exists); validate rejects OneWay with a non-empty Responses.
OneWay bool `json:"oneWay"`
// Streaming is the derived streaming summary: none | client | server | bidi.
Streaming StreamingMode `json:"streaming,omitempty"`
// RequestStream carries client-to-server streaming semantics, when present.
RequestStream *StreamDetail `json:"requestStream,omitzero"`
// ResponseStream carries server-to-client streaming semantics, when present.
ResponseStream *StreamDetail `json:"responseStream,omitzero"`
// Pagination describes the operation's pagination, when present.
Pagination *Pagination `json:"pagination,omitzero"`
// LongRunning describes long-running-operation semantics, when present.
LongRunning *LongRunning `json:"longRunning,omitzero"`
// Idempotency is the operation's idempotency classification: unknown | safe |
// idempotent | idempotency_token(param). safe = no side effects
// (Smithy @readonly, HTTP GET semantics).
Idempotency Idempotency `json:"idempotency"`
// Auth overrides the service default; an empty slice differs from nil (empty
// = explicitly public). omitzero keeps the two apart on the wire: nil is an
// absent key and inherits, an empty slice is written as [].
Auth []AuthRequirement `json:"auth,omitzero"`
// Tags are the operation's tag memberships.
Tags []string `json:"tags,omitempty"`
// ParameterVisibility overrides the visibility filter for the request view
// (TypeSpec @parameterVisibility); nil = protocol default.
ParameterVisibility []Lifecycle `json:"parameterVisibility,omitempty"`
// ReturnTypeVisibility overrides the visibility filter for the response view;
// nil = protocol default.
ReturnTypeVisibility []Lifecycle `json:"returnTypeVisibility,omitempty"`
// OverloadOf points at the operation this one overloads (TypeSpec @overload);
// when set, never empty.
OverloadOf *OpID `json:"overloadOf,omitzero"`
// Bindings describes how the neutral core maps onto concrete protocols (§8).
Bindings OpBindings `json:"bindings"`
// Examples are operation-scenario examples.
Examples []Example `json:"examples,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the operation came from.
Provenance Provenance `json:"provenance"`
}
Operation is the protocol-neutral core of a callable API operation (ir-design §7.2). Parameters carry no protocol location; each binding in Bindings maps the core onto a concrete protocol.
type OperationGroup ¶
type OperationGroup struct {
// Name is the group's naming.
Name Naming `json:"name"`
// Docs is the group's documentation.
Docs Docs `json:"docs"`
// Groups holds nested groups: Smithy resources, sub-clients.
Groups []OperationGroup `json:"groups,omitempty"`
// Operations holds the group's operations.
Operations []Operation `json:"operations,omitempty"`
// Resource carries Smithy resource semantics when declared.
Resource *ResourceInfo `json:"resource,omitzero"`
// Availability records the group's versioning timeline (TypeSpec interfaces
// are versionable).
Availability *Availability `json:"availability,omitzero"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
OperationGroup is a hierarchical grouping of operations: a TypeSpec interface, Smithy resource, or tag (ir-design §7.1).
type PageStrategy ¶
type PageStrategy string
PageStrategy names the pagination mechanism of an Operation (ir-design §7.3).
const ( // PageStrategyCursor is opaque-cursor pagination. PageStrategyCursor PageStrategy = "cursor" // PageStrategyOffset is numeric-offset pagination. PageStrategyOffset PageStrategy = "offset" // PageStrategyPage is page-number pagination. PageStrategyPage PageStrategy = "page" // PageStrategyLinkHeader is RFC 5988 Link-header pagination. PageStrategyLinkHeader PageStrategy = "link_header" // PageStrategyNextLink is body next-link pagination. PageStrategyNextLink PageStrategy = "next_link" // PageStrategyToken is continuation-token pagination. PageStrategyToken PageStrategy = "token" )
Pagination strategies.
type Pagination ¶
type Pagination struct {
// Strategy is the pagination mechanism.
Strategy PageStrategy `json:"strategy,omitempty"`
// Inferred reports heuristic detection (OpenAPI name-matching policy) vs
// declared (Smithy/TypeSpec).
Inferred bool `json:"inferred"`
// InputCursor is the input that continues iteration.
InputCursor *ParamPath `json:"inputCursor,omitzero"`
// InputLimit is the page-size input.
InputLimit *ParamPath `json:"inputLimit,omitzero"`
// Items is where result items live in the response — a path, not a name.
Items *PropPath `json:"items,omitzero"`
// NextCursor is the continuation source in the response.
NextCursor *PropPath `json:"nextCursor,omitzero"`
// NextLink is the next-page link in the response.
NextLink *PropPath `json:"nextLink,omitzero"`
// PrevLink is the previous-page navigation link.
PrevLink *PropPath `json:"prevLink,omitzero"`
// FirstLink is the first-page navigation link.
FirstLink *PropPath `json:"firstLink,omitzero"`
// LastLink is the last-page navigation link.
LastLink *PropPath `json:"lastLink,omitzero"`
// TotalCount is the total-count source in the response.
TotalCount *PropPath `json:"totalCount,omitzero"`
}
Pagination describes an Operation's pagination (ir-design §7.3).
type ParamPath ¶
type ParamPath struct {
// Param is the parameter name the path roots in.
Param string `json:"param,omitempty"`
// Segments are the ordered property IDs walked from the parameter; no entry
// is empty.
Segments []PropID `json:"segments,omitempty"`
}
ParamPath addresses a member within a named parameter (ir-design §7.3).
type Parameter ¶
type Parameter struct {
// Name is the parameter's naming.
Name Naming `json:"name"`
// Type is the parameter's type.
Type TypeRef `json:"type"`
// Required reports whether the caller must supply the parameter.
Required bool `json:"required"`
// Default is the parameter's default value.
Default *Value `json:"default,omitzero"`
// Constraints restricts the parameter's admissible values, and holds only
// what the parameter's own position declared. A bound on a $ref'd schema
// stays on the node Type points at and is never copied here, unlike Docs,
// Deprecation and Default, which merge from that target with use-site
// precedence: bounds conjoin rather than override, so nil means this
// position declared none, not that the value is unbounded (ir-design §12.2).
Constraints *Constraints `json:"constraints,omitzero"`
// ValueFrom derives the parameter's value from a location in the
// outgoing/incoming message (AsyncAPI parameter location runtime
// expressions); SDKs may auto-fill it. nil = caller-supplied.
ValueFrom *PropPath `json:"valueFrom,omitzero"`
// Docs is the parameter's documentation.
Docs Docs `json:"docs"`
// Deprecation marks the parameter as deprecated.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// Availability records the parameter's versioning timeline.
Availability *Availability `json:"availability,omitzero"`
// Examples are parameter-level example values.
Examples []Example `json:"examples,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the parameter was declared. A parameter shared by
// several operations — a path-item parameter in OpenAPI, merged into every
// operation on the path — points at its own single declaration rather than
// at the operation it was merged into. For a referenced entry the
// declaration is the component it names, and the mount site is not
// recorded: whether a parameter was inherited or declared by the operation
// is therefore readable off the pointer only for an entry written inline.
Provenance Provenance `json:"provenance"`
}
Parameter is one logical input of an Operation, protocol-unbound; its wire location is HTTP-binding detail (ir-design §7.2). GraphQL field arguments (Property.Args) reuse this shape.
type PartEncoding ¶
type PartEncoding struct {
// ContentTypes are the media type(s) of this part.
ContentTypes []string `json:"contentTypes,omitempty"`
// Headers are the per-part headers.
Headers []Property `json:"headers,omitempty"`
// Multi reports that the part repeats (array member → repeated parts).
Multi bool `json:"multi"`
// Filename reports that the part carries a filename (file part).
Filename bool `json:"filename"`
// Style is the form-style serialization for non-file parts.
Style string `json:"style,omitempty"`
// Explode overrides the default explode behavior; nil = default.
Explode *bool `json:"explode,omitzero"`
}
PartEncoding is the wire configuration of one multipart part or sequential item (ir-design §7.2). TypeSpec tuple-form multipart lowers to a synthesized model whose properties are the parts.
type PatternProps ¶
type PatternProps struct {
// Pattern is the ECMA-262 key pattern.
Pattern string `json:"pattern"`
// Value is the value schema for matching keys.
Value TypeRef `json:"value"`
}
PatternProps binds a key pattern to a value schema (JSON Schema patternProperties).
type Payload ¶
type Payload struct {
// Contents holds one entry per media type / message schema — all kept.
Contents []Content `json:"contents,omitempty"`
// Required states whether the message must be sent: true = the body is
// mandatory, false = it may be omitted. nil = the source format does not
// express body optionality at all, which is why this is a pointer — for a
// format that does, an unstated body is optional, and collapsing that onto
// nil would make "the format is silent" indistinguishable from "the
// document says no". A response or message payload leaves it nil: only a
// request body can be omitted, and pass/validate reports one that is set
// anywhere else (ir/payload-required-outside-request).
Required *bool `json:"required,omitzero"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
Payload is the body/message content of a request, response, or message (ir-design §7.2). All media types are kept.
type Position ¶
Position is a 1-based line and column inside a source. The zero value is no position, and a zero Column is a line whose column the producer does not know.
type PresenceKind ¶
type PresenceKind string
PresenceKind is the wire-presence discipline of a property where the format distinguishes more than required/optional (protobuf) (ir-design §5.1).
const ( // PresenceDefault is the format default (Required/Nullable say everything in // the JSON world). PresenceDefault PresenceKind = "" // PresenceImplicit means absence equals the default value; unset is // unobservable and zero values are not serialized (proto3 no-label, editions // IMPLICIT). PresenceImplicit PresenceKind = "implicit" // PresenceExplicit means unset is distinguishable from default-valued // (hazzers/pointers; proto2 optional, proto3 optional, editions EXPLICIT). PresenceExplicit PresenceKind = "explicit" // PresenceRequired means the property must be present on the wire (proto2 // required, editions LEGACY_REQUIRED). PresenceRequired PresenceKind = "required" )
Presence disciplines.
type PrimKind ¶
type PrimKind string
PrimKind names a built-in primitive scalar (ir-design §4.1). The set is the union of TypeSpec's intrinsic scalars, JSON Schema's types, and Protobuf's needs.
const ( // PrimBool is a boolean. PrimBool PrimKind = "bool" // PrimString is a Unicode string. PrimString PrimKind = "string" // PrimBytes is a byte string. PrimBytes PrimKind = "bytes" // PrimInt8 is a signed 8-bit integer. PrimInt8 PrimKind = "int8" // PrimInt16 is a signed 16-bit integer. PrimInt16 PrimKind = "int16" // PrimInt32 is a signed 32-bit integer. PrimInt32 PrimKind = "int32" // PrimInt64 is a signed 64-bit integer. PrimInt64 PrimKind = "int64" // PrimUint8 is an unsigned 8-bit integer. PrimUint8 PrimKind = "uint8" // PrimUint16 is an unsigned 16-bit integer. PrimUint16 PrimKind = "uint16" // PrimUint32 is an unsigned 32-bit integer. PrimUint32 PrimKind = "uint32" // PrimUint64 is an unsigned 64-bit integer. PrimUint64 PrimKind = "uint64" // PrimInteger is an arbitrary-precision integer (JSON Schema/TypeSpec integer). PrimInteger PrimKind = "integer" // PrimFloat32 is a 32-bit IEEE-754 float. PrimFloat32 PrimKind = "float32" // PrimFloat64 is a 64-bit IEEE-754 float. PrimFloat64 PrimKind = "float64" // PrimFloat is an arbitrary-precision binary float (supertype of float32/64). PrimFloat PrimKind = "float" // PrimNumber is an arbitrary-precision number (JSON Schema number, TypeSpec numeric). PrimNumber PrimKind = "number" // PrimDecimal is an arbitrary-precision decimal. PrimDecimal PrimKind = "decimal" // PrimDecimal128 is a 128-bit IEEE-754 decimal. PrimDecimal128 PrimKind = "decimal128" // PrimDate is a calendar date without time. PrimDate PrimKind = "date" // PrimTime is a time of day without date. PrimTime PrimKind = "time" // PrimDatetime is a date and time without offset. PrimDatetime PrimKind = "datetime" // PrimDatetimeOffset is a date and time with UTC offset. PrimDatetimeOffset PrimKind = "datetime_offset" // PrimDuration is a time span. PrimDuration PrimKind = "duration" // PrimURL is a URL. PrimURL PrimKind = "url" // PrimUUID is a UUID. PrimUUID PrimKind = "uuid" // PrimAny is an unknown/JSON any (schemaless) primitive. PrimAny PrimKind = "any" )
Primitive kinds.
func (PrimKind) Valid ¶
Valid reports whether k is one of the kinds declared above. PrimKind is a bare string enum, so nothing rejects an invented or stale value on the wire, and PrimTypeID derives a consistent ID from any string it is handed — an invented kind agrees with its own ID and reads as sound. irverify calls this so a kind no emitter can switch on is reported as the compiler bug it is, rather than reaching a target that has no type to lower it to.
type Primitive ¶
type Primitive struct {
TypeCommon
// Prim selects the primitive kind.
Prim PrimKind `json:"prim"`
}
Primitive is a built-in scalar leaf type (ir-design §4.1).
func (*Primitive) MarshalJSONTo ¶
MarshalJSONTo encodes the Primitive with an adjacent "kind" tag.
type PropPath ¶
type PropPath struct {
// Root is the type the path roots in; nil = determined by context (the
// enclosing response body, message payload, …).
Root *TypeRef `json:"root,omitzero"`
// In is "" = body/payload | "header"; continuation tokens and reply addresses
// can live in response/message headers, not just bodies.
In string `json:"in,omitempty"`
// Segments are the ordered property IDs walked from the root; no entry is
// empty.
Segments []PropID `json:"segments,omitempty"`
}
PropPath addresses a member within a type by identity, not by name (ir-design §7.3).
type Property ¶
type Property struct {
// ID is the property's stable synthetic identity.
ID PropID `json:"id"`
// Name is the property's naming.
Name Naming `json:"name"`
// WireName is the serialized name; defaults to Name.Source.
WireName string `json:"wireName,omitempty"`
// WireNameByFormat carries per-media-type overrides (TypeSpec @encodedName
// json/xml).
WireNameByFormat map[string]string `json:"wireNameByFormat,omitempty"`
// WireID is the protobuf field number / thrift id / tuple element index
// (1-based when Model.Positional); nil = none (pointer because 0 is a legal
// ordinal).
WireID *int `json:"wireID,omitzero"`
// ExtensionOf is "" for the model's own field, else the fully-qualified
// declaring scope of a third-party extension field (protobuf extend).
ExtensionOf string `json:"extensionOf,omitempty"`
// Type is the property's type.
Type TypeRef `json:"type"`
// Required reports wire presence; orthogonal to Type.Nullable.
Required bool `json:"required"`
// Presence is the wire-presence discipline where the format distinguishes more
// than required/optional (protobuf).
Presence PresenceKind `json:"presence,omitempty"`
// ClientOptional marks a wire-required property that clients MUST treat as
// optional (Smithy @clientOptional).
ClientOptional bool `json:"clientOptional"`
// DefaultAdded marks a default added post-publication; generators may ignore
// it for backward compatibility (Smithy @addedDefault).
DefaultAdded bool `json:"defaultAdded"`
// Visibility is the lifecycle set; zero value = visible in all.
Visibility Visibility `json:"visibility"`
// Default is the property's default value.
Default *Value `json:"default,omitzero"`
// Constraints restricts the property's admissible values, and holds only
// what the property's own position declared. A bound on a $ref'd schema
// stays on the node Type points at and is never copied here, unlike Docs,
// Deprecation and Default, which merge from that target with use-site
// precedence: bounds conjoin rather than override, so nil means this
// position declared none, not that the value is unbounded (ir-design §12.2).
Constraints *Constraints `json:"constraints,omitzero"`
// Encoding overrides the property's wire encoding.
Encoding *Encoding `json:"encoding,omitzero"`
// Args are field arguments for parameterized fields: GraphQL field arguments
// on any property at any depth; empty elsewhere.
Args []Parameter `json:"args,omitempty"`
// Flatten hoists the property's fields into the parent on the wire (Smithy/TCGC
// flatten; also set on the synthetic property wrapping a hoisted protobuf
// oneof).
Flatten bool `json:"flatten"`
// EventHeader marks an event-stream member that travels in the frame header,
// not the payload (Smithy @eventHeader).
EventHeader bool `json:"eventHeader"`
// EventPayload marks the raw frame payload member (Smithy @eventPayload);
// mutually exclusive with EventHeader, at most one per model.
EventPayload bool `json:"eventPayload"`
// Secret requests redaction in logs/docs (TypeSpec @secret, format:password).
Secret bool `json:"secret"`
// XML is the XML wire shape when it diverges from the JSON-implied shape.
XML *XMLHints `json:"xml,omitzero"`
// Examples are property-level example values.
Examples []Example `json:"examples,omitempty"`
// Docs is the property's documentation.
Docs Docs `json:"docs"`
// Deprecation marks the property as deprecated.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// Availability records the property's versioning timeline.
Availability *Availability `json:"availability,omitzero"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the property came from.
Provenance Provenance `json:"provenance"`
}
Property is one member of a Model (ir-design §5.1). Required (wire presence) is orthogonal to Type.Nullable (this usage admits null).
type ProtocolDecl ¶
type ProtocolDecl struct {
// Name is the protocol name, e.g. "aws.restJson1" or "grpc".
Name string `json:"name,omitempty"`
// Options holds per-protocol options kept raw (the Channel.Bindings pattern).
Options RawConfig `json:"options,omitempty"`
}
ProtocolDecl is a declared serde/protocol convention a service speaks (ir-design §7.1).
type Provenance ¶
type Provenance struct {
// Source indexes into Document.Sources, or is NoSource for a node that
// addresses no input file. Nothing else is in range.
Source int `json:"source"`
// Pointer is the RFC 6901 pointer to the construct inside Source. Empty
// locates nothing finer than the source itself: it is the pointer to the
// whole document, so a node with no single place in any source, such as a
// shared primitive, is on NoSource rather than at the root of one.
Pointer jsontext.Pointer `json:"pointer,omitempty"`
// Position is where the construct starts inside Source, for a finding made
// before the construct has a pointer — on a raw node, or in a part of the
// source no pointer reaches.
Position Position `json:"position,omitzero"`
// Node locates a finding in the IR rather than in a source: a stable ID, or a
// path through the document's own fields, for what an IR pass reports about
// the document it was handed. Spelling is the producer's; nothing parses it.
Node string `json:"node,omitempty"`
// Inferred is "" for declared facts; otherwise it names the heuristic that
// produced this node (e.g. "pagination-name-match").
Inferred string `json:"inferred,omitempty"`
}
Provenance records where a node came from and whether it was declared or inferred (ir-design §13). Everything heuristic is auditable; everything broken is reportable with an exact source location.
Each kind of locator has a field of its own, because a consumer holding one cannot tell which kind it is from its spelling: a renderer printed a line and column as a pointer fragment (GitHub #509), and no check could hold a pointer to RFC 6901 while the same field admitted the other two (GitHub #511).
type RPCBinding ¶
type RPCBinding struct {
// System is "grpc" | "smithy-rpc" | "connect" | "jsonrpc" | ….
System string `json:"system,omitempty"`
// FullMethod is the fully-qualified method, e.g. "/pkg.Service/Method".
FullMethod string `json:"fullMethod,omitempty"`
// InputType is the request message type params fold into (nil = synthesize
// from Params).
InputType *TypeRef `json:"inputType,omitzero"`
// ParamStructure is "" | "by_name" | "by_position" | "either" — how params
// serialize (JSON-RPC positional vs named; OpenRPC paramStructure). Param
// order is already source order; this is the mode.
ParamStructure string `json:"paramStructure,omitempty"`
// IdempotencyLevel is the RPC-declared idempotency level.
IdempotencyLevel string `json:"idempotencyLevel,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
RPCBinding maps an Operation onto an RPC method (ir-design §8.2).
type RawConfig ¶
RawConfig is declared protocol configuration the IR models a field for but deliberately does not constrain the shape of: AsyncAPI protocol bindings, Smithy protocol options. It is not an escape hatch — the entries are there because the source declared them where the IR expects them, so unlike an Unmodeled entry they carry no UnmodeledReason.
type Registries ¶
Registries maps each ID type to the Registry that declares those IDs.
A value's Go type is what makes it a reference: a ChannelID-typed field is a reference into Document.Channels wherever it sits — a node's own ID included, which resolves against its own entry — so no field has to be listed here and none can be forgotten.
Type-driven coverage is not total, and what it misses is a category rather than a stray field. A reference carried as an integer index into a slice is an int like any other, and reflection has nothing to key on; PropID names a position inside a model rather than an entry in a document-level map. Both classes are resolved by hand where they are checked.
Not every ID class Document declares references to has a map on Document at all: an Operation is declared in the Service→OperationGroup tree and a Service in a slice. Registries.WithDeclarations covers those.
func DocumentRegistries ¶
func DocumentRegistries(doc *Document) Registries
DocumentRegistries derives doc's registries from Document's own shape: a field that is a map keyed by a named string type is an ID-keyed registry, and its key type names the reference class it resolves. Deriving them covers a registry added to Document the moment it exists, where a hand-written list would drift. Document.Unmodeled is the counterexample: keyed by plain string, it keys on a source construct's name rather than an identity, and is no registry.
A nil doc declares nothing, which is the answer a report-only caller wants: every reference then resolves against no registry and is reported, rather than the call panicking on the way to saying so.
func (Registries) WithDeclarations ¶
func (r Registries) WithDeclarations(decls []IDDeclaration) Registries
WithDeclarations returns r extended with a registry for every ID class Document holds no map for, filled from the nodes in decls that declare one, so a reference whose class has no map still resolves — against the nodes that declare it.
An OpID and a ServiceID reference resolved against nothing before this, in both of Morphic's checkers, because both are driven by the map fields DocumentRegistries reads and neither class has one (GitHub #50).
Which classes are answered for comes from [idClasses] — the IR's type graph — and not from decls, which is the same distinction DocumentRegistries draws between a document's shape and its contents. A class *no* node declares is exactly the case a reference to it must still be reported for: a document with no operation at all still carries OpID references, from ResourceInfo.Lifecycle and its siblings, and a class set read off the declarations would leave those resolving against nothing again.
A class r covers with a map keeps that map. The map is what a consumer looks an ID up in, and irverify holds every entry to being keyed by its own node's ID, so a second answer derived here could only disagree with the first. A declaration-derived registry r already carries is replaced rather than added to: r is another call's result, and writing into the set it handed out would make this call mutate that one.
PropID is left out. A property is a position inside its model rather than a document-level identity, and the checks that resolve one — against the properties a document declares, and against the parts of the model a content names — are tighter claims made where the root is known. Adding a document-wide answer here would report one defect twice, under two codes.
type Registry ¶
type Registry struct {
// Label is the name a report spells the registry with: the lowercased
// Document field that declares it — "types", "channels" — or "<noun>
// declarations" for a registry derived from the nodes themselves.
Label string
// contains filtered or unexported fields
}
Registry is one registry of IDs a Document declares: the entries themselves, plus the name a report about them is spelled with.
The zero value declares nothing, which is what a lookup for an ID class the document registers nothing for yields. Registry.Has reports false for it rather than indexing an invalid value, so a checker holding a site built against another document reports it as unresolved instead of crashing.
type Reply ¶
type Reply struct {
// Channel is the static reply channel; nil when the address is dynamic-only
// (an AsyncAPI reply channel's own address is null by spec); when set, never
// empty.
Channel *ChannelID `json:"channel,omitzero"`
// Address is the dynamic reply address: where in the request message the
// reply destination lives, e.g. In:"header", Segments:[replyTo] (AsyncAPI
// Operation Reply Address runtime expressions).
Address *PropPath `json:"address,omitzero"`
// Messages is the reply payload message set; when Channel is set it must be a
// subset of that channel's own Messages, which pass.Validate checks. No entry
// is empty.
Messages []MessageID `json:"messages,omitempty"`
// Docs is the reply's documentation.
Docs Docs `json:"docs"`
}
Reply describes request-reply semantics of a MessageBinding (ir-design §8.3).
type RequestCompression ¶
type RequestCompression struct {
// Encodings are the priority-ordered compression encodings ("gzip", …).
Encodings []string `json:"encodings,omitempty"`
}
RequestCompression declares required request-body compression encodings (ir-design §8.1).
type ResourceInfo ¶
type ResourceInfo struct {
// Identifiers are the resource identity fields.
Identifiers []Property `json:"identifiers,omitempty"`
// Properties are the resource state fields (Smithy 2.0 resource properties).
Properties []Property `json:"properties,omitempty"`
// Lifecycle maps lifecycle names ("create"|"put"|"read"|"update"|"delete"|
// "list") to operations; put = create-or-replace with a client-provided
// identifier. No value is empty.
Lifecycle map[string]OpID `json:"lifecycle,omitempty"`
// NoReplace reports that put may create but not replace (Smithy @noReplace).
NoReplace bool `json:"noReplace"`
// InstanceOps are declared non-lifecycle instance operations (require
// identifiers); no entry is empty.
InstanceOps []OpID `json:"instanceOps,omitempty"`
// CollectionOps are declared collection operations; the split drives
// sub-client shape and is a declared fact, not a heuristic. No entry is empty.
CollectionOps []OpID `json:"collectionOps,omitempty"`
}
ResourceInfo carries Smithy resource semantics for an OperationGroup (ir-design §7.1).
type Response ¶
type Response struct {
// Name is the response naming for formats with named outputs; Hint elsewhere.
Name Naming `json:"name"`
// Conditions are the HTTP status codes/ranges; empty for RPC single-response.
Conditions ResponseConditions `json:"conditions"`
// Payload is the response body; nil = no body.
Payload *Payload `json:"payload,omitzero"`
// Headers are the response metadata fields.
Headers []Property `json:"headers,omitempty"`
// StatusCodeProp is the output member populated from the runtime HTTP status
// line (Smithy @httpResponseCode, TypeSpec non-literal @statusCode); the
// member is suppressed from the body.
StatusCodeProp *PropPath `json:"statusCodeProp,omitzero"`
// Docs is the response's documentation.
Docs Docs `json:"docs"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
Response is one declared output of an Operation (ir-design §7.2). All responses and all content types survive; the plan layer picks a primary.
type ResponseConditions ¶
type ResponseConditions struct {
// StatusCodes are the applicable status ranges; empty = unconditional.
StatusCodes []StatusRange `json:"statusCodes,omitempty"`
}
ResponseConditions selects the status codes a Response or ErrorCase applies to (ir-design §7.2).
type Scalar ¶
type Scalar struct {
TypeCommon
// Base is what this scalar extends: a primitive or another scalar in a
// restriction chain, or — where the scalar is the alias a declaring position
// hoisted over a shared target (ir-design §14) — a node of any kind, which a
// consumer following the chain must expect and stop at. nil = opaque scalar
// with implementation-defined representation (GraphQL custom scalars).
Base *TypeRef `json:"base,omitzero"`
// Constraints restricts the scalar's admissible values.
Constraints *Constraints `json:"constraints,omitzero"`
// Encoding overrides the scalar's wire encoding.
Encoding *Encoding `json:"encoding,omitzero"`
}
Scalar is a named restricted or extended primitive (ir-design §4.2). Emitters resolve the Base chain to the nearest representable base, accumulating constraints and encoding along the way.
func (*Scalar) MarshalJSONTo ¶
MarshalJSONTo encodes the Scalar with an adjacent "kind" tag.
type SchemeUse ¶
type SchemeUse struct {
// Scheme is the referenced auth scheme; never empty.
Scheme AuthID `json:"scheme,omitempty"`
// Scopes are the scopes required of the scheme (OAuth2/OpenID).
Scopes []string `json:"scopes,omitempty"`
}
SchemeUse names one scheme and the scopes required of it within an AuthRequirement (ir-design §9).
type Server ¶
type Server struct {
// Name is the server's naming.
Name Naming `json:"name"`
// URLTemplate is the endpoint URL, may contain {variables}.
URLTemplate string `json:"urlTemplate,omitempty"`
// Description is the server's documentation.
Description Docs `json:"description"`
// Variables are the URL template variables.
Variables []ServerVariable `json:"variables,omitempty"`
// Protocol is "https" (default); "kafka", "wss", … for messaging servers.
Protocol string `json:"protocol,omitempty"`
// ProtocolVersion is the protocol version, e.g. Kafka "3.5", AMQP "0-9-1"
// (AsyncAPI).
ProtocolVersion string `json:"protocolVersion,omitempty"`
// Tags are the server's tag memberships.
Tags []string `json:"tags,omitempty"`
// Auth is server-scoped security — AsyncAPI's primary auth placement (broker
// connections authenticate per server; different servers of one service may
// require different schemes). An empty non-nil slice (explicitly public)
// differs from nil; omitzero writes nil as an absent key and the empty slice
// as [].
Auth []AuthRequirement `json:"auth,omitzero"`
// Bindings holds server-level protocol bindings kept raw.
Bindings map[string]RawConfig `json:"bindings,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
Server is a named endpoint template (ir-design §10). Servers are named entities (AsyncAPI name-keyed servers, OpenAPI 3.2 Server.name).
type ServerVariable ¶
type ServerVariable struct {
// Name is the variable name referenced in the URL template.
Name string `json:"name,omitempty"`
// Default is the default value used when the caller supplies none.
Default string `json:"default,omitempty"`
// Enum is the closed set of permitted values, when constrained.
Enum []string `json:"enum,omitempty"`
// Docs is the variable's documentation.
Docs Docs `json:"docs"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
ServerVariable is one variable of a Server's URL template (ir-design §10).
type Service ¶
type Service struct {
// ID is the service's stable synthetic identity.
ID ServiceID `json:"id,omitempty"`
// Name is the service's naming.
Name Naming `json:"name"`
// Docs is the service's documentation.
Docs Docs `json:"docs"`
// Version is the per-service version string (Smithy service version); the
// document-level Version remains the API title's version.
Version string `json:"version,omitempty"`
// Namespace is the source namespace path (TypeSpec/Smithy/proto package).
Namespace []string `json:"namespace,omitempty"`
// Extends lists client-visible service inheritance (Thrift service extends,
// WSDL 2.0 interface extension, Cap'n Proto interface inheritance); inherited
// operations are walked, never copied. No entry is empty.
Extends []ServiceID `json:"extends,omitempty"`
// Groups holds the hierarchical operation groups; a group is a TypeSpec
// interface / Smithy resource / tag.
Groups []OperationGroup `json:"groups,omitempty"`
// Auth is the service-level default requirement (OR-of-ANDs, §9). An empty
// non-nil slice (explicitly public) differs from nil (no default); omitzero
// writes nil as an absent key and the empty slice as [].
Auth []AuthRequirement `json:"auth,omitzero"`
// CommonErrors are errors every operation can return (Smithy service-level
// errors).
CommonErrors []ErrorCase `json:"commonErrors,omitempty"`
// Protocols are the declared serde/protocol conventions the service speaks
// (Smithy @protocolDefinition traits like aws.protocols#restJson1).
Protocols []ProtocolDecl `json:"protocols,omitempty"`
// Renames holds per-service shape presentation names (Smithy service rename);
// the TypeID — and Naming on the type — are unchanged. No key is empty.
Renames map[TypeID]Naming `json:"renames,omitempty"`
// Servers indexes into Document.Servers scoped to this service.
Servers []int `json:"servers,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the service came from.
Provenance Provenance `json:"provenance"`
}
Service is a client-visible service: a coherent group of operations with a shared identity, auth default, and protocol conventions (ir-design §7.1).
type Severity ¶
type Severity string
Severity classifies a Diagnostic. The engine decides what is fatal.
type SourceInfo ¶
type SourceInfo struct {
Format string `json:"format"`
Path string `json:"path"`
Hash string `json:"hash"`
}
SourceInfo describes one input file of a Document.
type StatusRange ¶
type StatusRange struct {
// From is the inclusive lower bound.
From int `json:"from"`
// To is the inclusive upper bound.
To int `json:"to"`
}
StatusRange is an inclusive HTTP status-code range: 200–200, 400–499 ("4XX"), 0–0 = default/catch-all (ir-design §7.2).
type StreamDetail ¶
type StreamDetail struct {
// Events is the stream element type when it differs from the payload content
// type — for event streams a WireTagged Union of event models; within an
// event model, Property.EventHeader marks frame-header members and
// Property.EventPayload marks a raw-payload member (Smithy @eventHeader/
// @eventPayload). Per-event content types and terminal events live on
// Variant.Event.
Events *TypeRef `json:"events,omitzero"`
// Initial is the initial-request/initial-response message preceding the
// stream (Smithy event stream initial messages); nil = none.
Initial *TypeRef `json:"initial,omitzero"`
// RequiresLength reports that the streamed content must have a known finite
// length up front (Smithy @requiresLength) — changes the generated parameter
// type.
RequiresLength bool `json:"requiresLength"`
}
StreamDetail describes one direction of a streaming Operation (ir-design §7.3).
type StreamingMode ¶
type StreamingMode string
StreamingMode is the protocol-independent streaming direction of an Operation (ir-design §7.3).
const ( // StreamingNone means the operation does not stream. StreamingNone StreamingMode = "none" // StreamingClient means the client streams to the server. StreamingClient StreamingMode = "client" // StreamingServer means the server streams to the client. StreamingServer StreamingMode = "server" // StreamingBidi means both directions stream. StreamingBidi StreamingMode = "bidi" )
Streaming modes.
type TagDef ¶
type TagDef struct {
// Name is the tag name referenced by tagged nodes.
Name string `json:"name,omitempty"`
// Docs is the tag's documentation.
Docs Docs `json:"docs"`
}
TagDef is one entry of the document's tag metadata registry. Tag membership stays []string on the tagged nodes.
type TemplateArg ¶
type TemplateArg struct {
// Type is the type argument, set when this is a type parameter.
Type *TypeRef `json:"type,omitzero"`
// Value is the value argument, set when this is a valueof parameter.
Value *Value `json:"value,omitzero"`
}
TemplateArg is one argument of a TemplateInstantiation; exactly one of Type or Value is set (TypeSpec valueof template parameters).
type TemplateInstantiation ¶
type TemplateInstantiation struct {
// Template names the source template.
Template string `json:"template,omitempty"`
// Args are the type and value arguments; instances are identified by both.
Args []TemplateArg `json:"args,omitempty"`
}
TemplateInstantiation records the template and arguments a monomorphized generic type was produced from (ir-design §4).
type Tuple ¶
type Tuple struct {
TypeCommon
// Elems are the element types in position order.
Elems []TypeRef `json:"elems,omitempty"`
}
Tuple is a positional, fixed-arity sequence (prefixItems, TypeSpec tuples, Erlang tuples) (ir-design §4.6).
func (*Tuple) MarshalJSONTo ¶
MarshalJSONTo encodes the Tuple with an adjacent "kind" tag.
type TypeCommon ¶
type TypeCommon struct {
// ID is the type's stable synthetic identity in Document.Types.
ID TypeID `json:"id"`
// Name is the source/canonical naming of the type.
Name Naming `json:"name"`
// Namespace is the type's declared logical namespace (proto package, Avro
// namespace, Thrift/XSD/Cap'n Proto scopes); independent of Service.Namespace.
Namespace []string `json:"namespace,omitempty"`
// Anonymous reports that this is a hoisted inline type.
Anonymous bool `json:"anonymous"`
// Docs is the human-readable documentation for the type.
Docs Docs `json:"docs"`
// Tags are free-form labels (Smithy @tags, OpenAPI tag membership via policy);
// tag metadata lives once in Document.TagDefs.
Tags []string `json:"tags,omitempty"`
// Sensitive requests whole-type redaction (Smithy @sensitive on shapes);
// Property.Secret is the per-use form.
Sensitive bool `json:"sensitive"`
// Access is "" for public or "internal" for a type outside the exported SDK
// surface (protobuf editions export/local, TCGC @access(internal)).
Access string `json:"access,omitempty"`
// Deprecation marks the type as deprecated with optional migration guidance.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// Availability records the type's versioning timeline.
Availability *Availability `json:"availability,omitzero"`
// Usage is the computed input/output/error/multipart usage bitset.
Usage UsageFlags `json:"usage,omitzero"`
// WireNameByFormat carries type-level serialized-name overrides per media type
// (TypeSpec @encodedName on models/enums/scalars).
WireNameByFormat map[string]string `json:"wireNameByFormat,omitempty"`
// MediaTypeHint is the declared default content type when the type is a body
// (TypeSpec @mediaTypeHint, Smithy @mediaType on string/blob shapes).
MediaTypeHint string `json:"mediaTypeHint,omitempty"`
// XML is the type-level XML wire shape: root element name/namespace.
XML *XMLHints `json:"xml,omitzero"`
// Examples are typed example values attached to the type.
Examples []Example `json:"examples,omitempty"`
// Instantiation records provenance for monomorphized generics (TypeSpec
// templates).
Instantiation *TemplateInstantiation `json:"instantiation,omitzero"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
// Provenance records where the type came from.
Provenance Provenance `json:"provenance"`
}
TypeCommon carries the identity, documentation, and cross-cutting metadata shared by every type-graph node (ir-design §4). It is embedded in each concrete kind, and its fields sit beside the kind's own in JSON.
func (*TypeCommon) Common ¶
func (c *TypeCommon) Common() *TypeCommon
Common returns c itself. TypeCommon embeds by value into every concrete TypeDef kind (Primitive, Scalar, Model, Union, Enum, List, MapT, Tuple, Literal, External, Any), so this single pointer method is promoted to each kind's own pointer type and satisfies the TypeDef.Common contract for every one of them; only the unexported typeDef() marker stays declared per kind, so embedding TypeCommon elsewhere cannot join the sealed sum.
type TypeDef ¶
type TypeDef interface {
Kind() TypeKind
Common() *TypeCommon
// contains filtered or unexported methods
}
TypeDef is the sealed sum of all type-graph nodes (ir-design §4). Concrete kinds: Primitive, Scalar, Model, Union, Enum, List, MapT, Tuple, Literal, External, Any. JSON encodes the sum with an adjacent "kind" tag.
func NewTypeDef ¶
NewTypeDef returns a new zero-valued concrete TypeDef for kind k, or false when k is not a registered kind.
type TypeID ¶
type TypeID string
TypeID identifies a TypeDef in Document.Types, e.g. "t/openapi/components/schemas/User".
func PrimTypeID ¶
PrimTypeID returns the shared TypeID of the primitive of kind k.
It is the one ID this package can derive. Every other path is the compiler's own — a JSON Pointer, a GraphQL structural path and a protobuf fully-qualified name are different things and nothing here can compute one — so compilers/compile owns those. A primitive has no source position to derive from: its identity is its kind, which is an ir type, so the derivation belongs beside it (GitHub #73).
That placement is what lets irverify hold every Document to this ID rather than only the ones this repository's compilers produce.
type TypeKind ¶
type TypeKind string
TypeKind names one variant of the sealed TypeDef sum (ir-design §4).
const ( // KindPrimitive is a built-in scalar leaf (Primitive). KindPrimitive TypeKind = "primitive" // KindScalar is a named restricted/extended primitive (Scalar). KindScalar TypeKind = "scalar" // KindModel is a struct/object/message shape (Model). KindModel TypeKind = "model" // KindUnion is a sum over variant types (Union). KindUnion TypeKind = "union" // KindEnum is a closed or open set of named values (Enum). KindEnum TypeKind = "enum" // KindList is an ordered collection (List). KindList TypeKind = "list" // KindMap is a keyed collection (MapT). KindMap TypeKind = "map" // KindTuple is a positional fixed-arity sequence (Tuple). KindTuple TypeKind = "tuple" // KindLiteral is a single constant value as a type (Literal). KindLiteral TypeKind = "literal" // KindExternal is a well-known library type resolved by the emitter (External). KindExternal TypeKind = "external" // KindAny is a schemaless type (Any). KindAny TypeKind = "any" )
Type kinds: the closed set of type-graph node variants.
type TypeRef ¶
type TypeRef struct {
// Target identifies the referenced TypeDef in Document.Types. It is never
// empty: a position that admits no type holds a nil *TypeRef, so a TypeRef
// naming nothing is one a lowering left unfilled, and irverify reports it as
// ir/type-ref-no-target.
Target TypeID `json:"target"`
// Nullable reports that this usage admits null on the wire. Compilers
// normalize every source spelling to this one bit: OAS 3.0 nullable: true,
// OAS 3.1 type: [T, "null"], TypeSpec T | null, GraphQL absence-of-!.
Nullable bool `json:"nullable"`
}
TypeRef references a TypeDef by ID and records whether this particular usage admits null on the wire (ir-design §3.3). Nullability lives on the reference, not the target type, because the same type is nullable in one position and not another; combined with Property.Required it yields the four distinct required/optional × nullable/non-null states.
A TypeRef carries no fact of the target's down with it. What a use site can read without resolving Target is only what a compiler already merged onto the carrier — a Property's or Parameter's Docs, Deprecation and Default, taken from a $ref's target with use-site precedence. Everything else the target declares, Constraints above all, is read from the target node itself (ir-design §12.2).
type TypeRegistry ¶
TypeRegistry is the flat, ID-keyed owner of every TypeDef in a Document (ir-design §2, §4); every other node references types by TypeID. JSON (un)marshaling of the sealed sum is defined with the rest of the sum-type codec.
func (*TypeRegistry) UnmarshalJSONFrom ¶
func (r *TypeRegistry) UnmarshalJSONFrom(dec *jsontext.Decoder) error
UnmarshalJSONFrom decodes a kind-tagged TypeDef per entry, dispatching through the same registry the completeness test walks. Each entry is decoded under the options of the decoder that reached it, which is what holds a TypeDef's body to the same rules as the rest of the document.
Entries are decoded in ID order, so a registry with several bad entries names the same one on every run.
A JSON null is a no-op (#46): the registry is left as it was. Where that differs from a plain map, a null decoded over a populated registry, the Unmarshaler convention time.Time follows was chosen over the map's.
type Union ¶
type Union struct {
TypeCommon
// Variants are the union's members, in source order.
Variants []Variant `json:"variants,omitempty"`
// Exclusive is true for oneOf/tagged (exactly one variant matches) and false
// for anyOf (one-or-more).
Exclusive bool `json:"exclusive"`
// WireTagged reports that the wire format itself encodes the variant (protobuf
// oneof, Smithy union, GraphQL __typename) rather than untagged JSON oneOf.
WireTagged bool `json:"wireTagged"`
// Discriminator is the internal tag property, when one exists.
Discriminator *Discriminator `json:"discriminator,omitzero"`
}
Union is a sum over variant types (ir-design §4.4). One node covers untagged anyOf/oneOf, discriminated oneOf, and natively tagged unions.
func (*Union) MarshalJSONTo ¶
MarshalJSONTo encodes the Union with an adjacent "kind" tag.
type Unmodeled ¶
type Unmodeled map[string]UnmodeledEntry
Unmodeled is the lossless escape hatch: a source construct the IR deliberately does not model survives here untouched, keys namespaced by origin so two formats never collide: "openapi:x-rate-limit", "smithy:aws.api#arn", "graphql:@key", "erlang:opaque" (ir-design §12).
The name states the one property every member shares — the IR does not model it — rather than any one format's word for the concept. OpenAPI calls these extensions, Protobuf options, GraphQL directives, Smithy traits, TypeSpec decorators, and Protobuf's own "extensions" means something else entirely (reserved field-number ranges), so a spec-agnostic IR can adopt none of those names. Being unmodeled is the reason an entry is here; surviving verbatim is what the field guarantees about it, and UnmodeledReason records which flavour of unmodeled each entry is.
type UnmodeledEntry ¶
type UnmodeledEntry struct {
// Reason says why the construct is here rather than modeled, so a consumer
// can take the subset it cares about — a validation emitter wants §4.7
// entries and not vendor noise; a linter wants the degradations.
Reason UnmodeledReason `json:"reason"`
// Value is the source construct, preserved whole rather than byte-for-byte:
// nothing here discards or reshapes it, but re-encodings sit between the
// source bytes and this field. Encoding a document reformats a RawValue with
// the rest of it, whitespace and string escapes alike, and a compiler that
// rebuilds the value from its parsed tree (the OpenAPI path does) also sorts
// object keys.
//
// A number's value survives exactly. Its spelling is canonicalized only
// where JSON and YAML disagree about how to write one — .5 becomes 0.5,
// 0o17 becomes 15 — while every significant digit stays (GitHub #32).
//
// A scalar the source format gives a type to and JSON does not is kept as
// the text the source wrote, as a JSON string: a YAML timestamp stays
// `2021-1-1` rather than becoming the RFC 3339 instant it resolves to, and
// a `!!binary` keeps its base64 spelling rather than the bytes it names
// (GitHub #242). Reading one means resolving it the way its source format
// would; what this field promises is that the text is still there to
// resolve, which the resolved form would not have been.
Value RawValue `json:"value"`
// Provenance locates the construct itself, which the owning node's own
// provenance cannot: a validation emitter reporting on a `not` must point at
// the keyword, not at the schema that carried it. It falls back to the
// declaring position only for an entry synthesized from several keywords, no
// one of which addresses the whole value.
Provenance Provenance `json:"provenance"`
}
UnmodeledEntry is one unmodeled construct, kept verbatim.
type UnmodeledReason ¶
type UnmodeledReason string
UnmodeledReason says why a construct was kept verbatim instead of modeled. It is a property of the construct itself, never of the diagnostic a compiler emitted beside it: one diagnostic code routinely spans several of these.
const ( // ReasonVendorExtension marks an annotation the source format itself assigns // no semantics to (OpenAPI x-*, and every format's equivalent). The key set // is unbounded and nothing can be inferred from the value. ReasonVendorExtension UnmodeledReason = "vendor_extension" // ReasonValidationOnly marks validation logic rather than data shape: the // IR's structural picture is complete without it, and neither a target type // system nor a sibling source format has an equivalent (ir-design §4.7). ReasonValidationOnly UnmodeledReason = "validation_only" // ReasonDegradedLowering marks a construct with no faithful target as // written — the IR has no combinator for the shape, or no target type system // holds it. It was lowered to a documented weaker shape with the original // kept beside it, so the degradation stays recoverable (ir-design §4.8). ReasonDegradedLowering UnmodeledReason = "degraded_lowering" // ReasonNoIRHome marks a construct target languages can express and the IR // draws no deliberate boundary against: the position simply has no field for // it yet. A gap expected to close, not a boundary. ReasonNoIRHome UnmodeledReason = "no_ir_home" // ReasonOutOfScope marks a construct the IR excludes on purpose — runtime // machinery or per-target SDK policy rather than API shape (ir-design §15: // Smithy waiters and @endpointRuleSet, TCGC client-shaping decorators). It // is kept so nothing is lost, but no IR node is coming; the consumer meant // to read it is an emitter policy layer, not a promotion pass. ReasonOutOfScope UnmodeledReason = "out_of_scope" )
Why a construct is unmodeled rather than lowered.
func (UnmodeledReason) Valid ¶
func (r UnmodeledReason) Valid() bool
Valid reports whether r is one of the reasons declared above. UnmodeledReason is a bare string enum, so nothing rejects a typo'd or stale value on the wire; irverify calls this so an entry no consumer's switch can route is reported as the compiler bug it is rather than silently dropped.
type UsageFlags ¶
type UsageFlags uint32
UsageFlags is a bitset recording how a type is used across the API surface. It is computed by a pass and JSON-encoded as a number.
const ( // UsageInput marks a type reachable from a request payload. UsageInput UsageFlags = 1 << iota // UsageOutput marks a type reachable from a response payload. UsageOutput // UsageError marks a type reachable from an error payload. UsageError // UsageMultipart marks a type used in a multipart body. UsageMultipart )
Usage bits.
type Value ¶
type Value struct {
// Kind selects the meaningful payload field.
Kind ValueKind `json:"kind"`
// Bool is the payload for ValueBool.
Bool bool `json:"bool,omitzero"`
// Str is the payload for ValueString and ValueSymbol.
Str string `json:"str,omitempty"`
// Num is the payload for ValueNumber, an arbitrary-precision decimal string.
Num BigVal `json:"num,omitempty"`
// Bytes is the payload for ValueBytes, base64-encoded in JSON form.
Bytes []byte `json:"bytes,omitempty"`
// List is the payload for ValueList, an ordered sequence of values.
List []Value `json:"list,omitempty"`
// Object is the payload for ValueObject, an ordered set of named values.
// Object member order carries meaning, so it is a slice, never a map.
Object []Field `json:"object,omitempty"`
// Ref is the payload for ValueRefKind, a reference to a declared constant.
Ref *ValueRef `json:"ref,omitzero"`
// Ctor is the payload for ValueCtor, a constructor-built value.
Ctor *CtorValue `json:"ctor,omitzero"`
}
Value is typed data kept separate from the type graph: defaults, constants, literal types, enum member values, and examples (ir-design §6). Kind selects which payload field is meaningful; the remaining fields hold their zero value, and every payload is omitted when empty. Kind already says which payload a value carries, so an empty list and a nil one are the same value and share one spelling: Value{Kind: ValueList} marshals to {"kind":"list"}.
irverify.Verify holds this contract rather than assuming it: a populated field the kind does not select is ir/value-stray-payload, an absent one it does select is ir/value-missing-payload (number, ref and ctor only — the other kinds' zero payload is a real value), and a kind outside this file's declared set is ir/unknown-value-kind.
type ValueKind ¶
type ValueKind string
ValueKind names the shape of a Value payload; see Value for why values are kept separate from the type graph (ir-design §6).
const ( // ValueNull is the null value. ValueNull ValueKind = "null" // ValueBool is a boolean value carried in Value.Bool. ValueBool ValueKind = "bool" // ValueString is a string value carried in Value.Str. ValueString ValueKind = "string" // ValueNumber is an arbitrary-precision numeric value carried in Value.Num. ValueNumber ValueKind = "number" // ValueBytes is a byte-string value carried in Value.Bytes. ValueBytes ValueKind = "bytes" // ValueSymbol is an interned-symbol value carried in Value.Str, distinct // from ValueString (Erlang atoms: on the native wire ok != <<"ok">>). ValueSymbol ValueKind = "symbol" // ValueList is an ordered sequence of values carried in Value.List. ValueList ValueKind = "list" // ValueObject is an ordered set of named values carried in Value.Object. ValueObject ValueKind = "object" // ValueRefKind is a reference to a declared constant carried in Value.Ref. // Its string form is "ref"; the constant is named ValueRefKind because // ValueRef is the referenced struct. ValueRefKind ValueKind = "ref" // ValueCtor is a value built by a named scalar constructor, carried in // Value.Ctor (TypeSpec scalar constructors such as plainDate.fromISO). ValueCtor ValueKind = "ctor" )
Value kinds. The Kind field of a Value selects which payload field carries meaning; all other payload fields hold their zero value.
type ValueRef ¶
type ValueRef struct {
// Type identifies the declaring type; never empty.
Type TypeID `json:"type,omitempty"`
// Member names the referenced member within Type.
Member string `json:"member,omitempty"`
}
ValueRef references a declared constant: a TypeSpec enum-member default or a reference to a named const (ir-design §6).
type Variant ¶
type Variant struct {
// Name is the variant's naming; Hint-only for bare oneOf members.
Name Naming `json:"name"`
// Type is the variant's type.
Type TypeRef `json:"type"`
// WireName is the serialized tag when it differs from Name.Source (Smithy
// @jsonName on union members, protobuf oneof json_name).
WireName string `json:"wireName,omitempty"`
// WireID is the protobuf oneof field number or Cap'n Proto/Avro ordinal; nil =
// none (pointer because 0 is a legal ordinal).
WireID *int `json:"wireID,omitzero"`
// XML is @xmlName/@xmlNamespace on union members.
XML *XMLHints `json:"xml,omitzero"`
// Event is event-stream metadata when the union is a stream's event set.
Event *EventInfo `json:"event,omitzero"`
// Docs is the variant's documentation.
Docs Docs `json:"docs"`
// Deprecation marks the variant as deprecated.
Deprecation *Deprecation `json:"deprecation,omitzero"`
// Availability records the variant's versioning timeline.
Availability *Availability `json:"availability,omitzero"`
// Examples are typed example values for the variant.
Examples []Example `json:"examples,omitempty"`
// Unmodeled holds source constructs the IR does not model, kept verbatim.
Unmodeled Unmodeled `json:"unmodeled,omitempty"`
}
Variant is one member of a Union (ir-design §4.4).
type VersionedBool ¶
type VersionedBool struct {
// Version is the version label.
Version string `json:"version,omitempty"`
// WasRequired is the Required state effective at that version.
WasRequired bool `json:"wasRequired"`
}
VersionedBool records the prior required state at a version (ir-design §11).
type VersionedName ¶
type VersionedName struct {
// Version is the version label.
Version string `json:"version,omitempty"`
// Name is the name effective at that version.
Name string `json:"name,omitempty"`
}
VersionedName is a prior name effective at a version (ir-design §11).
type VersionedType ¶
type VersionedType struct {
// Version is the version label.
Version string `json:"version,omitempty"`
// Type is the type effective at that version.
Type TypeRef `json:"type"`
}
VersionedType is a prior type effective at a version (ir-design §11).
type Visibility ¶
type Visibility struct {
// Only lists the lifecycles the property is visible in; empty = visible in
// all (unless None).
Only []Lifecycle `json:"only,omitempty"`
// None marks a property visible in NO lifecycle, excluded from every
// projection (TypeSpec @invisible); distinct from the zero value.
None bool `json:"none"`
}
Visibility is the set of lifecycles in which a property is visible (ir-design §5.2). The zero value is visible in all lifecycles.
type WireIDRange ¶
type WireIDRange struct {
// From is the first wire ID in the range.
From int `json:"from"`
// To is the last wire ID in the range.
To int `json:"to"`
}
WireIDRange is an inclusive range of wire IDs (ir-design §4.3).
type XMLHints ¶
type XMLHints struct {
// Name is the element/attribute name override.
Name string `json:"name,omitempty"`
// Namespace is the namespace URI.
Namespace string `json:"namespace,omitempty"`
// Prefix is the namespace prefix.
Prefix string `json:"prefix,omitempty"`
// NodeType is "", "element", "attribute", "text", "cdata", or "none" (OpenAPI
// 3.2 nodeType; "text" covers Smithy httpPayload text).
NodeType string `json:"nodeType,omitempty"`
// Wrapped reports that list items are wrapped in a container element.
Wrapped bool `json:"wrapped"`
}
XMLHints describes an XML wire shape that diverges from the JSON-implied one (ir-design §5.4). Hints attach at TypeCommon (root shape) and Property (per-use overrides; property wins).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package irtest provides golden-snapshot helpers for IR documents.
|
Package irtest provides golden-snapshot helpers for IR documents. |
|
Package irverify checks a compiled ir.Document against the structural invariants every compiler must uphold: stable IDs, no two nodes claiming one identity, no dangling references, neutral naming, routable Unmodeled entries, in-range provenance, a readable schema stamp, and more besides.
|
Package irverify checks a compiled ir.Document against the structural invariants every compiler must uphold: stable IDs, no two nodes claiming one identity, no dangling references, neutral naming, routable Unmodeled entries, in-range provenance, a readable schema stamp, and more besides. |