thrift_generator (thrift_generator v0.7.0)
View SourceFront end of the Thrift IDL generator: turns IDL files into tokens and
an AST of #thrift_generator_node{} records.
The pipeline is tokens/1 -> ast/1; parse_file/1 and
parse_string/1 wrap both steps. parse_file/1 appends a synthetic
__file__ marker to the source, which the grammar consumes after the
document's definitions; the AST document itself carries only headers
and definitions — module naming and include resolution work from the
paths the loader tracks.
Summary
Functions
Parses a token list into a document AST node.
CI gate: verifies the generated sources are up to date without
writing. Runs the same pipeline as generate/3 and requires every
artifact to already exist in OutDir with the exact content this
input would produce. Returns ok, or {error, {stale, Paths}} with
the drifted (missing or differing) files.
Deletes the generator's files from OutDir: every .erl and .hrl
whose second line carries the Autogenerated by Thrift Generator
banner. The banner — not the current IDL — decides, so files left
behind by drifted inputs (a removed service, a deleted IDL file) are
cleaned up too, and anything not carrying the banner is left alone.
Returns the deleted paths, or {error, {delete, Path, Reason}} after
the first failing removal.
Full pipeline: load (with includes), semantic analysis, code emission,
write to OutDir.
Reads, lexes and parses an IDL file in one step.
Lexes and parses an IDL snippet given as text, without a file marker.
Reads and lexes an IDL file, appending a __file__ marker with the
path as given.
Types
-type ast_node() :: #thrift_generator_node{line :: non_neg_integer(), col :: non_neg_integer(), doc :: doc(), annotations :: erl_annotations(), payload :: term(), type_module :: module()}.
-type base_type() :: bool | i8 | i16 | i32 | i64 | double | string | binary | uuid.
-type const_value() :: {ref, Name :: binary()} | boolean() | integer() | float() | binary() | {list, [const_value()]} | {map, [{const_value(), const_value()}]}.
-type constant() :: #thrift_generator_constant{name :: constant_name(), type :: thrift_type(), value :: const_value()}.
-nominal constant_name() :: binary().
-type cpp_include() :: #thrift_generator_cpp_include{path :: include_path()}.
-type doc() :: binary() | undefined.
-type enum_() :: #thrift_generator_enum{name :: enum_name(), values :: [enum_value()]}.
-nominal enum_name() :: binary().
-type enum_value() :: {Name :: binary(), Value :: integer() | undefined, annotations(), doc()}.
-type exception_() :: #thrift_generator_exception{name :: exception_name(), fields :: [ast_node()]}.
-nominal exception_name() :: binary().
-type field_() :: #thrift_generator_field{id :: integer() | undefined, required :: requiredness(), type :: thrift_type(), name :: field_name(), default :: const_value() | undefined}.
-nominal field_name() :: binary().
-type function_() :: #thrift_generator_function{oneway :: boolean(), return_type :: thrift_type() | void, name :: function_name(), fields :: [ast_node()], throws :: [ast_node()]}.
-nominal function_name() :: binary().
-type generate_opts() ::
#{repr => record | map | native,
union_type => record | sum,
set => list | sets | ordset,
typedef_type => alias | nominal}.
-type include_() :: #thrift_generator_include{path :: include_path()}.
-nominal include_path() :: binary().
-type loc() :: pos_integer() | {pos_integer(), pos_integer()}.
-type namespace_() :: #thrift_generator_namespace{scope :: namespace_scope(), name :: namespace_name()}.
-nominal namespace_name() :: binary().
-nominal namespace_scope() :: binary().
-type node_payload() :: document() | include_() | cpp_include() | namespace_() | constant() | typedef() | enum_() | struct_() | union_def() | exception_() | service() | function_() | field_().
-type requiredness() :: required | optional | default.
-type service() :: #thrift_generator_service{name :: service_name(), extends :: service_parent() | undefined, functions :: [ast_node()]}.
-nominal service_name() :: binary().
-nominal service_parent() :: binary().
-type struct_() :: #thrift_generator_struct{name :: struct_name(), fields :: [ast_node()]}.
-nominal struct_name() :: binary().
-type thrift_type() :: {base, base_type(), annotations()} | type_ref() | {list, Element :: thrift_type(), annotations()} | {set, Element :: thrift_type(), annotations()} | {map, Key :: thrift_type(), Value :: thrift_type(), annotations()}.
-type type_ref() :: {ref, Name :: binary(), annotations()}.
-type typedef() :: #thrift_generator_typedef{name :: typedef_name(), type :: thrift_type()}.
-nominal typedef_name() :: binary().
-type union_def() :: #thrift_generator_union{name :: union_name(), fields :: [ast_node()]}.
-nominal union_name() :: binary().
Functions
Parses a token list into a document AST node.
-spec check(file:filename_all(), file:filename_all(), generate_opts()) -> ok | {error, {stale, [file:filename_all()]}} | {error, term()}.
CI gate: verifies the generated sources are up to date without
writing. Runs the same pipeline as generate/3 and requires every
artifact to already exist in OutDir with the exact content this
input would produce. Returns ok, or {error, {stale, Paths}} with
the drifted (missing or differing) files.
-spec clean(file:filename_all()) -> {ok, [file:filename_all()]} | {error, term()}.
Deletes the generator's files from OutDir: every .erl and .hrl
whose second line carries the Autogenerated by Thrift Generator
banner. The banner — not the current IDL — decides, so files left
behind by drifted inputs (a removed service, a deleted IDL file) are
cleaned up too, and anything not carrying the banner is left alone.
Returns the deleted paths, or {error, {delete, Path, Reason}} after
the first failing removal.
-spec generate(file:filename_all(), file:filename_all(), generate_opts()) -> {ok, [#{module := module(), path := file:filename_all(), hrl => file:filename_all()}]} | {error, term()}.
Full pipeline: load (with includes), semantic analysis, code emission,
write to OutDir.
Writes one <module>.erl per generated module (types, and
client/server/handler per service) and a <mod>_types.hrl next to
every types module. Files whose on-disk content already matches are
left untouched, so regenerating an unchanged IDL does not churn mtimes
(and recompiles).
Opts carries the invocation-wide axes; each applies only to
definitions without an explicit annotation of its own: repr
(record, the default, map or native) for structures and
exceptions without erl.struct_type, union_type (record or sum)
for unions without erl.union_type, set (list, the default,
sets or ordset) for sets without erl.set, and typedef_type
(alias, the default, or nominal) for typedefs without erl.type.
A file-wide namespace default overrides the option for its file.
Returns the generated modules with their paths (and the include path when one was written).
-spec parse_file(file:filename_all()) -> {ok, ast_node()} | {error, term()}.
Reads, lexes and parses an IDL file in one step.
Lexes and parses an IDL snippet given as text, without a file marker.
-spec tokens(file:filename_all()) -> {ok, [token()], loc()} | {error, {loc(), module(), term()} | term(), loc()}.
Reads and lexes an IDL file, appending a __file__ marker with the
path as given.