thrift_generator_emitter (thrift_generator v0.7.0)
View SourceTurns the semantic model into Erlang modules.
Per IDL file a <mod>_types.erl is emitted: records for structs and
unions (map representation via the erl.struct_type = "map"
annotation, tagged-tuple sums via erl.union_type = "sum" on a union
or its namespace header), the introspection surface (struct_info/1,
enum_info/1, function_info/2, service_info/0) and the
record-field index (record_fields/1) that thrift_runtime_record uses
to bridge records and the wire.
Per service: <svc>_handler.erl (the -callback behaviour),
<svc>_server.erl (a thrift_runtime_service implementation plus the
server entry points) and <svc>_client.erl (typed call wrappers that
convert records at the boundary).
Forms are built with erl_syntax and rendered with erl_prettypr.
Descriptors are plain data: most function bodies are abstract/1 of
the descriptor terms, which keeps the emitter declarative.
compile_sources/1 compiles the same forms in memory for tests.
Summary
Functions
Compiles every generated module in memory (compile:forms).
The method's declared exceptions as wire descriptors.
Whether the definition declares a record (record mode, not a sum union).
The method's params struct as a wire descriptor.
The typed record declaration of a record-mode struct (remote type references under qualify).
The method's reply type as a wire descriptor, undefined for void.
The module key with dots replaced by underscores (an atom-safe module name).
The section divider label naming an IDL definition (the declared name, not the derived tag).
Renders every generated module as a source map with its hrl when present.
The struct_type axis of a definition: map, native, or record when absent or unrecognized.
Whether the union is generated as a tagged-tuple sum type.
Converts a model type into the wire descriptor vocabulary the runtime codecs consume (resolving references, expanding typedefs and inlining enum descriptors); shared with the codec emitter.
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 desc() :: term().
-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 include_() :: #thrift_generator_include{path :: include_path()}.
-nominal include_path() :: binary().
-type module_key() :: binary().
-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
-spec compile_sources(#tg_model{root :: binary(), modules :: [#tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}]}) -> [compiled()].
Compiles every generated module in memory (compile:forms).
-spec erlang_type(thrift_type(), #ectx{modules :: #{module_key() => #tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}}, type_modules :: #{module_key() => module()}, include_modules :: #{module_key() => module_key()}, current :: undefined | module_key(), qualify :: boolean()}) -> erl_syntax:syntaxTree().
-spec exceptions_desc(#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}, #ectx{modules :: #{module_key() => #tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}}, type_modules :: #{module_key() => module()}, include_modules :: #{module_key() => module_key()}, current :: undefined | module_key(), qualify :: boolean()}) -> [desc()].
The method's declared exceptions as wire descriptors.
-spec has_record(#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}) -> boolean().
Whether the definition declares a record (record mode, not a sum union).
-spec params_desc(#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}, #ectx{modules :: #{module_key() => #tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}}, type_modules :: #{module_key() => module()}, include_modules :: #{module_key() => module_key()}, current :: undefined | module_key(), qualify :: boolean()}) -> desc().
The method's params struct as a wire descriptor.
-spec record_form(#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}, binary(), #ectx{modules :: #{module_key() => #tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}}, type_modules :: #{module_key() => module()}, include_modules :: #{module_key() => module_key()}, current :: undefined | module_key(), qualify :: boolean()}) -> erl_syntax:forms().
The typed record declaration of a record-mode struct (remote type references under qualify).
-spec reply_desc(#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}, #ectx{modules :: #{module_key() => #tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}}, type_modules :: #{module_key() => module()}, include_modules :: #{module_key() => module_key()}, current :: undefined | module_key(), qualify :: boolean()}) -> desc() | undefined.
The method's reply type as a wire descriptor, undefined for void.
The module key with dots replaced by underscores (an atom-safe module name).
-spec section_label(#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()} | #tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()} | #tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}) -> string().
The section divider label naming an IDL definition (the declared name, not the derived tag).
-spec sources(#tg_model{root :: binary(), modules :: [#tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}]}) -> [source()].
Renders every generated module as a source map with its hrl when present.
-spec struct_type(#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}) -> record | map | native.
The struct_type axis of a definition: map, native, or record when absent or unrecognized.
-spec sum_mode(#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}) -> boolean().
Whether the union is generated as a tagged-tuple sum type.
-spec type_desc(thrift_type(), #ectx{modules :: #{module_key() => #tg_module{name :: binary(), prefix :: binary(), path :: binary(), includes :: [binary()], structs :: [#tg_struct{kind :: struct | union | exception, name :: binary(), fields :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], enums :: [#tg_enum{name :: binary(), values :: [{integer(), binary()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], typedefs :: [#tg_typedef{name :: binary(), type :: thrift_type(), erl :: erl_annotations(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], consts :: [#tg_const{name :: binary(), type :: thrift_type(), value :: const_value(), doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}], services :: [#tg_service{name :: binary(), extends :: binary() | undefined, functions :: [#tg_function{name :: binary(), oneway :: boolean(), return_type :: thrift_type() | void, params :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], throws :: [#tg_field{id :: integer(), required :: requiredness(), type :: thrift_type(), name :: binary(), default :: const_value() | undefined, doc :: doc()}], doc :: doc()}], doc :: doc(), line :: non_neg_integer(), col :: non_neg_integer()}]}}, type_modules :: #{module_key() => module()}, include_modules :: #{module_key() => module_key()}, current :: undefined | module_key(), qualify :: boolean()}) -> desc().
Converts a model type into the wire descriptor vocabulary the runtime codecs consume (resolving references, expanding typedefs and inlining enum descriptors); shared with the codec emitter.