thrift_runtime_protocol behaviour (thrift_runtime v0.7.0)

View Source

Wire protocol behaviour: value and message codecs as pure functions.

A protocol module encodes and decodes values described by the same type descriptors the generated introspection functions return (struct_info/1, enum_info/1, function_info/2). Decoding consumes a binary and returns the remaining bytes, so callers can stream; more marks a truncated but otherwise valid input.

thrift_runtime_binary and thrift_runtime_compact implement this behaviour. Any other module passed as a thrift_runtime:protocol() — to the facade, the client or the server — must export every callback with these exact shapes.

The module also hosts what the implementations share:

  • the descriptor type vocabulary (type_desc(), field_desc(), message_type(), ...): the behaviour owns the contract, so the callbacks are typed through it; thrift_runtime_binary re-exports the names for the existing call sites;
  • the TMessageType ids of the message envelope and the TApplicationException descriptor with its code-to-name table, plus the shared encode/decode of that exception payload;
  • cold-path helpers the three implementations would otherwise carry three copies of: enum member conversion, the encode-time union and required-field checks with the decode-time required marking, the message-type table, struct resolution through struct_info/1 with the schema cache, the specialized-codec probe of the generated per-protocol index, and the per-process memo over inline descriptors.

Hot-path pieces stay in the implementations on purpose: the per-type codecs, the skip functions, varint/zigzag and the per-field/per-scalar helpers work on wire shapes only they understand.

Summary

Callbacks

Decodes one value of Type from the front of Binary; the rest comes back, more marks a valid but truncated input.

Decodes a TApplicationException payload.

Decodes a message envelope from the front of Binary; more marks a truncated one.

Encodes Value as Type, or fails with a tagged error.

Encodes a TApplicationException payload.

Wraps an already-encoded payload into a message envelope.

Types

application_exception()

-type application_exception() :: #{message := binary(), code := non_neg_integer(), name := binary()}.

base_type()

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

decode_result(Value)

-type decode_result(Value) :: {ok, Value, binary()} | more | {error, term()}.

enum_desc()

-type enum_desc() :: [{integer(), atom()}].

field_desc()

-type field_desc() ::
          {Id :: integer(), requiredness(), type_desc(), Name :: binary(), Default :: term()}.

message_type()

-type message_type() :: call | reply | exception | oneway.

protocol()

-type protocol() :: binary | compact | json.

requiredness()

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

set_impl()

-type set_impl() :: list | sets | ordset.

struct_desc()

-type struct_desc() :: {struct | union | exception, [field_desc()]} | {ref, module(), binary()}.

struct_value()

-type struct_value() :: #{binary() := term()}.

type_desc()

-type type_desc() ::
          {base, base_type()} |
          {enum, enum_desc()} |
          {list, type_desc()} |
          {set, type_desc()} |
          {set, type_desc(), set_impl()} |
          {map, type_desc(), type_desc()} |
          {struct, struct_desc()}.

Callbacks

decode/2

-callback decode(type_desc(), binary()) -> decode_result(term()).

Decodes one value of Type from the front of Binary; the rest comes back, more marks a valid but truncated input.

decode_application_exception/1

-callback decode_application_exception(binary()) -> decode_result(application_exception()).

Decodes a TApplicationException payload.

decode_message/1

-callback decode_message(binary()) ->
                            {ok, message_type(), binary(), non_neg_integer(), binary()} |
                            more |
                            {error, term()}.

Decodes a message envelope from the front of Binary; more marks a truncated one.

encode/2

-callback encode(type_desc(), term()) -> {ok, iodata()} | {error, term()}.

Encodes Value as Type, or fails with a tagged error.

encode_application_exception(Message, Code)

-callback encode_application_exception(Message :: binary(), Code :: non_neg_integer()) ->
                                          {ok, iodata()} | {error, term()}.

Encodes a TApplicationException payload.

encode_message/4

-callback encode_message(message_type(), Name :: binary(), SeqId :: non_neg_integer(), Payload :: iodata()) ->
                            iodata().

Wraps an already-encoded payload into a message envelope.

Functions

all_present/2

-spec all_present([binary()], struct_value()) -> boolean().

application_exception_desc()

-spec application_exception_desc() -> struct_desc().

application_exception_name/1

-spec application_exception_name(non_neg_integer()) -> binary().

check_present_fields/5

-spec check_present_fields(struct | union | exception,
                           [binary()],
                           [tuple()],
                           struct_value(),
                           fun((tuple()) -> binary())) ->
                              ok | {error, term()}.

codec(Mod, Module, Name, Index)

-spec codec(module(), module(), binary(), atom()) -> {ok, fun(), fun()} | error.

decode_application_exception(Mod, Bin)

-spec decode_application_exception(module(), binary()) -> decode_result(application_exception()).

encode_application_exception(Mod, Message, Code)

-spec encode_application_exception(module(), binary(), non_neg_integer()) ->
                                      {ok, iodata()} | {error, term()}.

enum_from_int(Desc, Int)

-spec enum_from_int(enum_desc(), integer()) -> {ok, atom()} | error.

enum_to_int/2

-spec enum_to_int(enum_desc(), atom() | integer()) -> {ok, integer()} | error.

mark_present(Required, Id)

-spec mark_present(#{integer() => binary()}, integer()) -> #{integer() => binary()}.

memo_compiled(Mod, Key, Kind, Fields, Compile)

-spec memo_compiled(module(),
                    term(),
                    struct | union | exception,
                    [field_desc()],
                    fun((struct | union | exception, [field_desc()]) -> Compiled)) ->
                       Compiled.

message_type/1

-spec message_type(non_neg_integer()) -> {ok, message_type()} | error.

message_type_id/1

-spec message_type_id(message_type()) -> non_neg_integer().

resolve_struct(Mod, Module, Name, Compile)

-spec resolve_struct(module(),
                     module(),
                     binary(),
                     fun((struct | union | exception, [field_desc()]) -> Compiled)) ->
                        {ok, Compiled} | error.

struct_fields/1

-spec struct_fields(type_desc()) -> [field_desc()].