THRIFT-5635 Update erlang client for Erlang 23-25
Client: erl
Patch: Sergey Yelin

This closes #2677

Summary of changes:
 - Add useful compiler options
 - Format sources using erlfmt
 - Switch to modern callbacks in thrift_* modules
 - Add static analysis (dialyzer), disabled by default
 - Add/fix types for API calls

NOTE: Enabling static analysis requires additional tweaks in multiplexer module.
diff --git a/lib/erl/src/thrift_json_parser.erl b/lib/erl/src/thrift_json_parser.erl
index 4e47f10..18e0c03 100644
--- a/lib/erl/src/thrift_json_parser.erl
+++ b/lib/erl/src/thrift_json_parser.erl
@@ -22,19 +22,15 @@
 -module(thrift_json_parser).
 -export([parser/0, handle_event/2]).
 
-
 -record(config, {strict_utf8 = false :: boolean()}).
 
-
 parser() -> fun(JSON) -> start(JSON, {?MODULE, []}, [], #config{}) end.
 
-
 handle_event(Event, {Handler, State}, _Config) -> {Handler, Handler:handle_event(Event, State)}.
 
 handle_event(end_json, State) -> lists:reverse([end_json] ++ State);
 handle_event(Event, State) -> [Event] ++ State.
 
-
 %% whitespace
 -define(space, 16#20).
 -define(tab, 16#09).
@@ -68,12 +64,11 @@
 %% comments
 -define(star, 16#2A).
 
-
 %% some useful guards
 -define(is_hex(Symbol),
     (Symbol >= $a andalso Symbol =< $f) orelse
-    (Symbol >= $A andalso Symbol =< $F) orelse
-    (Symbol >= $0 andalso Symbol =< $9)
+        (Symbol >= $A andalso Symbol =< $F) orelse
+        (Symbol >= $0 andalso Symbol =< $9)
 ).
 
 -define(is_nonzero(Symbol),
@@ -84,7 +79,6 @@
     Symbol =:= ?space; Symbol =:= ?tab; Symbol =:= ?cr; Symbol =:= ?newline
 ).
 
-
 %% lists are benchmarked to be faster (tho higher in memory usage) than binaries
 new_seq() -> [].
 new_seq(C) -> [C].
@@ -96,13 +90,11 @@
 
 end_seq(Seq, _) -> end_seq(Seq).
 
-
 start(<<16#ef, 16#bb, 16#bf, Rest/binary>>, Handler, Stack, Config) ->
     value(Rest, Handler, Stack, Config);
 start(Bin, Handler, Stack, Config) ->
     value(Bin, Handler, Stack, Config).
 
-
 value(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
     string(Rest, Handler, new_seq(), Stack, Config);
 value(<<$t, Rest/binary>>, Handler, Stack, Config) ->
@@ -118,41 +110,37 @@
 value(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_nonzero(S) ->
     integer(Rest, Handler, new_seq(S), Stack, Config);
 value(<<?start_object, Rest/binary>>, Handler, Stack, Config) ->
-    object(Rest, handle_event(start_object, Handler, Config), [key|Stack], Config);
+    object(Rest, handle_event(start_object, Handler, Config), [key | Stack], Config);
 value(<<?start_array, Rest/binary>>, Handler, Stack, Config) ->
-    array(Rest, handle_event(start_array, Handler, Config), [array|Stack], Config);
+    array(Rest, handle_event(start_array, Handler, Config), [array | Stack], Config);
 value(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     value(Rest, Handler, Stack, Config);
 value(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 object(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
     string(Rest, Handler, new_seq(), Stack, Config);
-object(<<?end_object, Rest/binary>>, Handler, [key|Stack], Config) ->
+object(<<?end_object, Rest/binary>>, Handler, [key | Stack], Config) ->
     maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config);
 object(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     object(Rest, Handler, Stack, Config);
 object(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
-array(<<?end_array, Rest/binary>>, Handler, [array|Stack], Config) ->
+array(<<?end_array, Rest/binary>>, Handler, [array | Stack], Config) ->
     maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config);
 array(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     array(Rest, Handler, Stack, Config);
 array(Bin, Handler, Stack, Config) ->
     value(Bin, Handler, Stack, Config).
 
-
-colon(<<?colon, Rest/binary>>, Handler, [key|Stack], Config) ->
-    value(Rest, Handler, [object|Stack], Config);
+colon(<<?colon, Rest/binary>>, Handler, [key | Stack], Config) ->
+    value(Rest, Handler, [object | Stack], Config);
 colon(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     colon(Rest, Handler, Stack, Config);
 colon(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 key(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
     string(Rest, Handler, new_seq(), Stack, Config);
 key(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
@@ -160,7 +148,6 @@
 key(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 %% note that if you encounter an error from string and you can't find the clause that
 %%  caused it here, it might be in unescape below
 string(<<?doublequote, Rest/binary>>, Handler, Acc, Stack, Config) ->
@@ -212,42 +199,47 @@
 string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#100000, X < 16#10fffe ->
     string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
 %% surrogates
-string(<<237, X, _, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 160 ->
+string(<<237, X, _, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 160
+->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 %% u+xfffe, u+xffff, control codes and other noncharacters
-string(<<_/utf8, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false}) ->
+string(<<_/utf8, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) ->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 %% u+fffe and u+ffff for R14BXX (subsequent runtimes will happily match the
 %%  preceding clause
-string(<<239, 191, X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X == 190; X == 191 ->
+string(
+    <<239, 191, X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}
+) when
+    X == 190; X == 191
+->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 %% overlong encodings and missing continuations of a 2 byte sequence
-string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 192, X =< 223 ->
+string(<<X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 192, X =< 223
+->
     strip_continuations(Rest, Handler, Acc, Stack, Config, 1);
 %% overlong encodings and missing continuations of a 3 byte sequence
-string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 224, X =< 239 ->
+string(<<X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 224, X =< 239
+->
     strip_continuations(Rest, Handler, Acc, Stack, Config, 2);
 %% overlong encodings and missing continuations of a 4 byte sequence
-string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 240, X =< 247 ->
+string(<<X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 240, X =< 247
+->
     strip_continuations(Rest, Handler, Acc, Stack, Config, 3);
 %% incompletes and unexpected bytes, including orphan continuations
-string(<<_, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false}) ->
+string(<<_, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) ->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 string(_Bin, _Handler, _Acc, _Stack, _Config) ->
-  erlang:error(badarg).
+    erlang:error(badarg).
 
-
-doublequote(Rest, Handler, Acc, [key|_] = Stack, Config) ->
+doublequote(Rest, Handler, Acc, [key | _] = Stack, Config) ->
     colon(Rest, handle_event({key, end_seq(Acc, Config)}, Handler, Config), Stack, Config);
 doublequote(Rest, Handler, Acc, Stack, Config) ->
     maybe_done(Rest, handle_event({string, end_seq(Acc, Config)}, Handler, Config), Stack, Config).
 
-
 %% strips continuation bytes after bad utf bytes, guards against both too short
 %%  and overlong sequences. N is the maximum number of bytes to strip
 strip_continuations(<<Rest/binary>>, Handler, Acc, Stack, Config, 0) ->
@@ -259,7 +251,6 @@
 strip_continuations(<<Rest/binary>>, Handler, Acc, Stack, Config, _) ->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config).
 
-
 %% this all gets really gross and should probably eventually be folded into
 %%  but for now it fakes being part of string on incompletes and errors
 unescape(<<$b, Rest/binary>>, Handler, Acc, Stack, Config) ->
@@ -278,22 +269,35 @@
     string(Rest, Handler, acc_seq(Acc, $\\), Stack, Config);
 unescape(<<?solidus, Rest/binary>>, Handler, Acc, Stack, Config) ->
     string(Rest, Handler, acc_seq(Acc, $/), Stack, Config);
-unescape(<<$u, $d, A, B, C, ?rsolidus, $u, $d, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config)
-        when (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
-             (X == $c orelse X == $d orelse X == $e orelse X == $f),
-             ?is_hex(B), ?is_hex(C), ?is_hex(Y), ?is_hex(Z)
-        ->
+unescape(
+    <<$u, $d, A, B, C, ?rsolidus, $u, $d, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config
+) when
+    (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
+    (X == $c orelse X == $d orelse X == $e orelse X == $f),
+    ?is_hex(B),
+    ?is_hex(C),
+    ?is_hex(Y),
+    ?is_hex(Z)
+->
     High = erlang:list_to_integer([$d, A, B, C], 16),
     Low = erlang:list_to_integer([$d, X, Y, Z], 16),
     Codepoint = (High - 16#d800) * 16#400 + (Low - 16#dc00) + 16#10000,
     string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config);
-unescape(<<$u, $d, A, B, C, ?rsolidus, $u, W, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config)
-        when (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
-             ?is_hex(B), ?is_hex(C), ?is_hex(W), ?is_hex(X), ?is_hex(Y), ?is_hex(Z)
-        ->
+unescape(
+    <<$u, $d, A, B, C, ?rsolidus, $u, W, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config
+) when
+    (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
+    ?is_hex(B),
+    ?is_hex(C),
+    ?is_hex(W),
+    ?is_hex(X),
+    ?is_hex(Y),
+    ?is_hex(Z)
+->
     string(Rest, Handler, acc_seq(Acc, [16#fffd, 16#fffd]), Stack, Config);
-unescape(<<$u, A, B, C, D, Rest/binary>>, Handler, Acc, Stack, Config)
-        when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) ->
+unescape(<<$u, A, B, C, D, Rest/binary>>, Handler, Acc, Stack, Config) when
+    ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D)
+->
     case erlang:list_to_integer([A, B, C, D], 16) of
         Codepoint when Codepoint < 16#d800; Codepoint > 16#dfff ->
             string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config);
@@ -303,7 +307,6 @@
 unescape(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 %% like in strings, there's some pseudo states in here that will never
 %%  show up in errors or incompletes. some show up in value, some show
 %%  up in integer, decimal or exp
@@ -314,7 +317,6 @@
 negative(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 zero(<<?decimalpoint, Rest/binary>>, Handler, Acc, Stack, Config) ->
     decimal(Rest, Handler, acc_seq(Acc, ?decimalpoint), Stack, Config);
 zero(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E ->
@@ -322,7 +324,6 @@
 zero(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {zero, Acc}, Stack, Config).
 
-
 integer(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     integer(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 integer(<<?decimalpoint, Rest/binary>>, Handler, Acc, Stack, Config) ->
@@ -332,13 +333,11 @@
 integer(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {integer, Acc}, Stack, Config).
 
-
 initialdecimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 initialdecimal(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 decimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 decimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E ->
@@ -346,7 +345,6 @@
 decimal(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {decimal, Acc}, Stack, Config).
 
-
 e(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 e(<<Sign, Rest/binary>>, Handler, Acc, Stack, Config) when Sign =:= ?positive; Sign =:= ?negative ->
@@ -354,66 +352,59 @@
 e(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 ex(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 ex(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 exp(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 exp(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {exp, Acc}, Stack, Config).
 
-
 finish_number(Rest, Handler, Acc, [], Config) ->
     maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), [], Config);
 finish_number(Rest, Handler, Acc, Stack, Config) ->
     maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config).
 
-
 format_number({zero, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))};
 format_number({integer, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))};
 format_number({decimal, Acc}) -> {float, list_to_float(lists:reverse(Acc))};
 format_number({exp, Acc}) -> {float, list_to_float(lists:reverse(Acc))}.
 
-
 true(<<$r, $u, $e, Rest/binary>>, Handler, Stack, Config) ->
     maybe_done(Rest, handle_event({literal, true}, Handler, Config), Stack, Config);
 true(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 false(<<$a, $l, $s, $e, Rest/binary>>, Handler, Stack, Config) ->
     maybe_done(Rest, handle_event({literal, false}, Handler, Config), Stack, Config);
 false(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 null(<<$u, $l, $l, Rest/binary>>, Handler, Stack, Config) ->
     maybe_done(Rest, handle_event({literal, null}, Handler, Config), Stack, Config);
 null(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 maybe_done(<<Rest/binary>>, Handler, [], Config) ->
     done(Rest, handle_event(end_json, Handler, Config), [], Config);
-maybe_done(<<?end_object, Rest/binary>>, Handler, [object|Stack], Config) ->
+maybe_done(<<?end_object, Rest/binary>>, Handler, [object | Stack], Config) ->
     maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config);
-maybe_done(<<?end_array, Rest/binary>>, Handler, [array|Stack], Config) ->
+maybe_done(<<?end_array, Rest/binary>>, Handler, [array | Stack], Config) ->
     maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config);
-maybe_done(<<?comma, Rest/binary>>, Handler, [object|Stack], Config) ->
-    key(Rest, Handler, [key|Stack], Config);
-maybe_done(<<?comma, Rest/binary>>, Handler, [array|_] = Stack, Config) ->
+maybe_done(<<?comma, Rest/binary>>, Handler, [object | Stack], Config) ->
+    key(Rest, Handler, [key | Stack], Config);
+maybe_done(<<?comma, Rest/binary>>, Handler, [array | _] = Stack, Config) ->
     value(Rest, Handler, Stack, Config);
 maybe_done(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     maybe_done(Rest, Handler, Stack, Config);
 maybe_done(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 done(<<S, Rest/binary>>, Handler, [], Config) when ?is_whitespace(S) ->
     done(Rest, Handler, [], Config);
-done(<<>>, {_Handler, State}, [], _Config) -> State;
-done(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg).
+done(<<>>, {_Handler, State}, [], _Config) ->
+    State;
+done(_Bin, _Handler, _Stack, _Config) ->
+    erlang:error(badarg).