thrift_generator_codec_compact (thrift_generator v0.7.0)

View Source

Specialized compact-protocol wire codecs emitted into <mod>_types.erl.

The compact sibling of thrift_generator_codec (the binary protocol): for every struct, union and exception the module gets encode_<prefix>_compact/1 and decode_<prefix>_compact/1 with the same contracts as thrift_runtime_compact:encode/2 and decode/2, plus the module-level compact_codec/1 handing the pair out by wire struct name. thrift_runtime_compact 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 byte for byte: ULEB128 varints, zigzag for i16/i32/i64 and field ids, little-endian doubles, field headers as type nibble + delta against the last WRITTEN field id, boolean values riding in the header nibble with no payload, collection sizes up to 14 in the header nibble, map pairs sorted by encoded-key term order, missing_required_fields in declaration order on encode and ascending field-id order on decode, identical error terms, and more on every truncated input. Unknown field ids are skipped by nibble through the runtime's thrift_runtime_compact:skip_nibble/2. The thrift_codec_test equivalence properties pin all of this against the generic engine.

The uuid base type has no compact encoding: encoding through a uuid field or element fails with the generic engine's {type_not_supported, {base, uuid}, compact} and no uuid field nibble ever matches on decode (a field_type_mismatch).

Nesting and naming follow the binary emitter: same-module struct references become direct calls to the sibling functions, cross-module references go through thrift_runtime_compact:encode/2 and decode/2; containers get private *_c helpers named after the rendered element type (the suffix keeps them clear of the binary codec's helpers emitted into the same module); enum members are inlined as case clauses at every use site. The varint/zigzag/header machinery is shared per module and emitted only when something actually calls it.

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

The -export/1 entries of the compact wire codecs: compact_codec/1 plus one pair per struct.

Every compact wire-codec form of the module: per-struct encode/decode functions, container and varint helpers, compact_codec/1.

Types

annotations()

-type annotations() :: #{binary() := true | binary()}.

ast_node()

-type ast_node() ::
          #thrift_generator_node{line :: non_neg_integer(),
                                 col :: non_neg_integer(),
                                 doc :: doc(),
                                 annotations :: erl_annotations(),
                                 payload :: term(),
                                 type_module :: module()}.

base_type()

-type base_type() :: bool | i8 | i16 | i32 | i64 | double | string | binary | uuid.

const_value()

-type const_value() ::
          {ref, Name :: binary()} |
          boolean() |
          integer() |
          float() |
          binary() |
          {list, [const_value()]} |
          {map, [{const_value(), const_value()}]}.

constant()

-type constant() ::
          #thrift_generator_constant{name :: constant_name(),
                                     type :: thrift_type(),
                                     value :: const_value()}.

constant_name()

-nominal constant_name() :: binary().

cpp_include()

-type cpp_include() :: #thrift_generator_cpp_include{path :: include_path()}.

doc()

-type doc() :: binary() | undefined.

document()

-type document() :: #thrift_generator_document{headers :: [ast_node()], definitions :: [ast_node()]}.

enum_()

-type enum_() :: #thrift_generator_enum{name :: enum_name(), values :: [enum_value()]}.

enum_name()

-nominal enum_name() :: binary().

enum_value()

-type enum_value() :: {Name :: binary(), Value :: integer() | undefined, annotations(), doc()}.

erl_annotations()

-type erl_annotations() :: #{atom() := true | binary()}.

exception_()

-type exception_() :: #thrift_generator_exception{name :: exception_name(), fields :: [ast_node()]}.

exception_name()

-nominal exception_name() :: binary().

field_()

-type field_() ::
          #thrift_generator_field{id :: integer() | undefined,
                                  required :: requiredness(),
                                  type :: thrift_type(),
                                  name :: field_name(),
                                  default :: const_value() | undefined}.

field_name()

-nominal field_name() :: binary().

function_()

-type function_() ::
          #thrift_generator_function{oneway :: boolean(),
                                     return_type :: thrift_type() | void,
                                     name :: function_name(),
                                     fields :: [ast_node()],
                                     throws :: [ast_node()]}.

function_name()

-nominal function_name() :: binary().

include_()

-type include_() :: #thrift_generator_include{path :: include_path()}.

include_path()

-nominal include_path() :: binary().

module_key()

-type module_key() :: binary().

namespace_()

-type namespace_() :: #thrift_generator_namespace{scope :: namespace_scope(), name :: namespace_name()}.

namespace_name()

-nominal namespace_name() :: binary().

namespace_scope()

-nominal namespace_scope() :: binary().

node_payload()

-type node_payload() ::
          document() |
          include_() |
          cpp_include() |
          namespace_() |
          constant() |
          typedef() |
          enum_() |
          struct_() |
          union_def() |
          exception_() |
          service() |
          function_() |
          field_().

requiredness()

-type requiredness() :: required | optional | default.

service()

-type service() ::
          #thrift_generator_service{name :: service_name(),
                                    extends :: service_parent() | undefined,
                                    functions :: [ast_node()]}.

service_name()

-nominal service_name() :: binary().

service_parent()

-nominal service_parent() :: binary().

struct_()

-type struct_() :: #thrift_generator_struct{name :: struct_name(), fields :: [ast_node()]}.

struct_name()

-nominal struct_name() :: binary().

thrift_type()

-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_ref()

-type type_ref() :: {ref, Name :: binary(), annotations()}.

typedef()

-type typedef() :: #thrift_generator_typedef{name :: typedef_name(), type :: thrift_type()}.

typedef_name()

-nominal typedef_name() :: binary().

union_def()

-type union_def() :: #thrift_generator_union{name :: union_name(), fields :: [ast_node()]}.

union_name()

-nominal union_name() :: binary().

Functions

export_entries(Mod, Ctx)

-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 compact wire codecs: compact_codec/1 plus one pair per struct.

module_forms(Mod, Ctx)

-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 compact wire-codec form of the module: per-struct encode/decode functions, container and varint helpers, compact_codec/1.