genjsonschema

package
v1.18.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package genjsonschema builds a JSON Schema (Draft 2020-12) by reflecting over Go type definitions. It powers OPA's `genplanschema` and `genmanifestschema` commands: each generator wraps a Builder, plugs in a TypeResolver for its domain-specific shapes, walks a root struct, and renders the accumulated $defs.

The Builder treats struct types as named definitions referenced via `#/$defs/<TypeName>`, and reflects fields based on their `json:"..."` tags (handling `omitempty`, embedded structs, and skipping unexported fields).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MakeNullable

func MakeNullable(schema any) any

MakeNullable returns a schema equivalent to the input that also accepts the JSON null value.

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder accumulates struct definitions in $defs and offers ReflectType / AddStruct entry points used by both the caller and its TypeResolver.

func NewBuilder

func NewBuilder(resolver TypeResolver) *Builder

NewBuilder returns a Builder. resolver may be nil, in which case only the built-in cases are used.

func (*Builder) AddNamedDef

func (b *Builder) AddNamedDef(name string, schema OrderedMap) (string, error)

AddNamedDef stores schema under name and returns DefRef(name). Use when the body has no recursive references back to itself. Returns an error if name is already registered (whether via Reserve, SetDef, AddNamedDef, or AddStruct) — collisions are always a programming error in this API.

func (*Builder) AddStruct

func (b *Builder) AddStruct(t reflect.Type) (string, error)

AddStruct ensures t (a struct or pointer-to-struct) has a definition in $defs and returns its $ref. Recurses through fields, consulting the resolver for each.

func (*Builder) AllowAdditionalProperties

func (b *Builder) AllowAdditionalProperties(t reflect.Type)

AllowAdditionalProperties opts t out of the default `additionalProperties: false` constraint, so the generated schema accepts unknown keys on that struct. Use this for top-level types whose runtime decoder is lenient and where embedders are known to attach custom fields (e.g. the bundle Manifest).

func (*Builder) DefRef

func (*Builder) DefRef(name string) string

DefRef returns the JSON pointer ref ("#/$defs/Name") for name. It does not check that the def exists — useful for forward references that will be filled in later.

func (*Builder) DefsOrdered

func (b *Builder) DefsOrdered() OrderedMap

DefsOrdered returns the accumulated $defs in name-sorted order so the rendered schema is byte-stable across runs.

func (*Builder) HasDef

func (b *Builder) HasDef(name string) bool

HasDef reports whether name is currently registered (including reserved but not yet filled in).

func (*Builder) ReflectType

func (b *Builder) ReflectType(t reflect.Type) (any, error)

ReflectType returns a JSON Schema fragment describing t. Pointers are unwrapped. The resolver, if any, is consulted before built-in handling.

Built-in handling covers: bool, all integer kinds, all float kinds, string, slice/array (item type recurses), map (string-keyed only; values recurse), the bare-`any` interface (matches anything), and named structs (which recurse through AddStruct).

func (*Builder) Reserve

func (b *Builder) Reserve(name string) bool

Reserve marks name as in-flight so recursive references emitted while building its body can resolve to a $ref instead of looping. Returns true if the name was newly reserved, false if it already existed (in which case the caller should not call SetDef).

func (*Builder) SetDef

func (b *Builder) SetDef(name string, schema OrderedMap)

SetDef stores schema under name. Typically paired with Reserve.

type Entry

type Entry struct {
	Key   string
	Value any
}

Entry is a single key/value pair in an OrderedMap.

type OrderedMap

type OrderedMap []Entry

OrderedMap preserves insertion order for JSON object encoding so the generated schema is byte-stable across runs.

func Map

func Map(pairs ...any) OrderedMap

Map builds an OrderedMap from alternating key/value arguments. Keys must be strings; the function panics on an odd number of arguments or on a non-string key. Use this from outside the package to avoid the govet "composites" warning that fires on cross-package struct literals.

Map panics rather than returning an error so it can be used as a literal constructor in deeply nested expressions without breaking the call-site readability that is its whole point. The conditions it panics on are programming errors in literal arguments, not runtime data conditions a caller could usefully handle.

func (OrderedMap) MarshalJSON

func (m OrderedMap) MarshalJSON() ([]byte, error)

type TypeResolver

type TypeResolver func(b *Builder, t reflect.Type) (schema any, handled bool, err error)

TypeResolver returns a JSON Schema for t and reports handled=true to short circuit the Builder's default handling. A resolver runs first on every type the Builder visits via ReflectType (after pointer unwrapping), so it can intercept polymorphic interfaces, opaque types, and named structs whose JSON shape isn't derivable from reflection alone.

A resolver that reports handled=true must return a non-nil schema; the Builder treats a nil schema with handled=true as an error so silent JSON `null` output is impossible.

The Builder is passed in so resolvers can recurse — e.g., to translate the underlying type of a polymorphic union and accumulate further $defs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL