GoMEOS code generator
July 11, 2026 · View on GitHub
codegen.py reads tools/meos-idl.json (produced by the
MEOS-API parser) and emits one
idiomatic Go wrapper per MEOS public C function into tools/_preview/.
The directory is prefixed with _ so go build ./... ignores it; the
output is a Draft artifact that lets reviewers see the shape of the
generated surface without disturbing the hand-written package.
Running
python3 tools/codegen.py
Coverage today
2369 candidate functions across the six public headers. 2199 emit
cleanly; 170 are excluded as Datum-bearing internal helpers (the
hand-written surface exposes those through typed overloads which the
codegen cannot synthesise from the IDL). Zero unresolved TODOs and
zero explicit skips remain. The skiplist primitives that take
function-pointer arguments (comp_fn, merge_fn, datum_func2) or
operate on void ** element arrays surface as unsafe.Pointer,
matching how PyMEOS-CFFI exposes them as _ffi.CData and MEOS.NET as
IntPtr — callers provide the raw pointer obtained from another
wrapped MEOS call (for example a typed comparator's address).
The covered shapes are: scalar inputs, wrapped opaque pointers
(Temporal, STBox, TBox, Span, SpanSet, Set, GSERIALIZED,
TInstant, TSequence, TSequenceSet, Npoint, Nsegment,
SkipList, RTree, Match, BOX3D, GBOX, AFFINE, PJ_CONTEXT,
gsl_rng, Interval), C and PostgreSQL text strings, output
parameters named result / value (scalar and wrapped-pointer
out-params surfaced as additional Go return values), counted-array
inputs (T ** / const T * paired with int count or size_t size)
lowered to Go slices, counted-array returns (T ** paired with
int *count or matching the input slice length) lowered to Go slices
including byte buffers and char ** / text ** string arrays,
unsafe.Pointer for void * arguments, and metadata-driven shapes
described below.
meta/meos-meta.json shape annotations
The remaining ecosystem-wide editorial decisions live in MEOS-API's
meta/meos-meta.json under each function's shape key, merged into
meos-idl.json at IDL-generation time. All bindings consume the same
catalog.
Annotation kinds:
shape.arrayReturn.lengthFrom = { kind: "accessor", func, arg, castTo? }— the function returns an array whose length is obtained by calling a sibling accessor on one of its inputs. Used by the*_valuesfamily (bigintset_values->set_num_values(s)), the*_insts_p/*_sequences_paccessors (cast toconst Temporal *), and the*_spanarr/*_spsspanset accessors.shape.arrayReturn.lengthFrom = { kind: "param", name }— the function returns an array whose length is written to an output parameter of the same call.shape.outputArrays = [{ param, ... }]— additional parallel output arrays sharing the primary length. Used by the*_splitfamily (time_bins,value_bins) including the triple-pointerGSERIALIZED ***output oftgeo_space_split/tgeo_space_time_split.shape.namedOutputs = ["subtype", "radius"]— scalar out-parameters whose name is neitherresultnorvalue.shape.arrayInputGroup = { params, count, nullable }— N parallel input arrays sharing one count (tpointseq_make_coords). Nullable members accept Gonil.shape.skip = "<reason>"— bindings omit the function entirely. Retained as an escape hatch but no entries use it today; the skiplist family now surfaces throughunsafe.Pointerinstead.
Refreshing the IDL
tools/meos-idl.json is vendored. When MEOS bumps, regenerate with
MEOS-API against the new headers and copy the output back:
cp ../MEOS-API/output/meos-idl.json tools/meos-idl.json
python3 tools/codegen.py
The vendored IDL relies on MEOS-API PR #1 (the stdbool stub) being in
place so bool returns and bool * outputs do not get demoted to
int.
The vendored IDL relies on MEOS-API PR #1 (the stdbool stub) being in
place so bool returns and bool * outputs do not get demoted to int.