thrift_generator_codec (thrift_generator v0.7.0)
View SourceSpecialized binary-protocol wire codecs emitted into <mod>_types.erl.
For every struct, union and exception the module gets
encode_<prefix>_wire/1 and decode_<prefix>_wire/1: direct
binary-pattern code over the wire representation (maps keyed by binary
field names), with the same contracts as thrift_runtime_binary:encode/2
and thrift_runtime_binary:decode/2. The module-level binary_codec/1
hands the function pair out by wire struct name; thrift_runtime_binary
probes that export whenever it meets a {struct, {ref, Module, Name}}
descriptor and dispatches to the specialized code, falling back to its
descriptor-driven engine for modules without the export (hand-written
descriptors, inline RPC param/result structs).
The generated code preserves the generic engine's observable
semantics: identical bytes for identical wire values and identical
error terms — missing_required_fields in declaration order on encode
and ascending field-id order on decode, union_empty/union_multiple,
field_type_mismatch, element_type_mismatch, map_type_mismatch,
bad_map_size, bad_sequence_size, bad_string_length, the
more-versus-error truncation distinction — and skips unknown field
ids by wire type. The thrift_codec_test equivalence properties pin all
of this against the generic engine.
Nesting: same-module struct references become direct calls to the
sibling wire functions; cross-module references go through
thrift_runtime_binary:encode/2 and decode/2, which re-enter the codec
probe. Containers get private enc_*/dec_* helpers named after the
rendered element type; enum members are inlined as case clauses at
every use site.
Forms are built as raw erl_parse trees — patterns, binary segment
options and guards have no convenient erl_syntax constructors — so
erl_pp renders them; doc and spec attributes stay syntax trees like
everywhere else in the emitter.
Summary
Functions
Shared with the compact/JSON codec emitters: every container node of a wire type, outermost first.
Shared with the compact/JSON codec emitters: the namespace prefix of the module being generated.
Shared with the compact/JSON codec emitters: the element type of a list or set container.
Shared with the compact/JSON codec emitters: numbers a module's distinct inline enum descriptors.
The -export/1 entries of the wire codecs: binary_codec/1 plus one pair per struct.
Every wire-codec form of the module: per-struct encode/decode functions, container helpers, binary_codec/1.
Shared with the compact/JSON codec emitters: renders a wire type as a helper-name fragment.
Shared with the compact/JSON codec emitters: joins the namespace prefix with a snake-case name.
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 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
Shared with the compact/JSON codec emitters: every container node of a wire type, outermost first.
-spec current_prefix(#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()}) -> binary().
Shared with the compact/JSON codec emitters: the namespace prefix of the module being generated.
Shared with the compact/JSON codec emitters: the element type of a list or set container.
-spec enum_registry([wire_type()], #{integer() => pos_integer()}) -> #{integer() => pos_integer()}.
Shared with the compact/JSON codec emitters: numbers a module's distinct inline enum descriptors.
-spec export_entries(#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()}]}, #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()}) -> [{atom(), arity()}].
The -export/1 entries of the wire codecs: binary_codec/1 plus one pair per struct.
-spec module_forms(#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()}]}, #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().
Every wire-codec form of the module: per-struct encode/decode functions, container helpers, binary_codec/1.
-spec type_name(wire_type(), #{integer() => pos_integer()}) -> binary().
Shared with the compact/JSON codec emitters: renders a wire type as a helper-name fragment.
Shared with the compact/JSON codec emitters: joins the namespace prefix with a snake-case name.