aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/compiler/diameter_codegen.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/diameter/src/compiler/diameter_codegen.erl')
-rw-r--r--lib/diameter/src/compiler/diameter_codegen.erl120
1 files changed, 74 insertions, 46 deletions
diff --git a/lib/diameter/src/compiler/diameter_codegen.erl b/lib/diameter/src/compiler/diameter_codegen.erl
index cdaa9aa7f9..f56e4a5249 100644
--- a/lib/diameter/src/compiler/diameter_codegen.erl
+++ b/lib/diameter/src/compiler/diameter_codegen.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -150,20 +150,21 @@ erl_forms(Mod, ParseD) ->
{id, 0},
{vendor_id, 0},
{vendor_name, 0},
- {decode_avps, 2}, %% in diameter_gen.hrl
- {encode_avps, 2}, %%
+ {decode_avps, 3}, %% in diameter_gen.hrl
+ {encode_avps, 3}, %%
+ {grouped_avp, 4}, %%
{msg_name, 2},
{msg_header, 1},
{rec2msg, 1},
{msg2rec, 1},
{name2rec, 1},
{avp_name, 2},
+ {avp_arity, 1},
{avp_arity, 2},
{avp_header, 1},
- {avp, 3},
- {grouped_avp, 3},
+ {avp, 4},
{enumerated_avp, 3},
- {empty_value, 1},
+ {empty_value, 2},
{dict, 0}]},
%% diameter.hrl is included for #diameter_avp
{?attribute, include_lib, "diameter/include/diameter.hrl"},
@@ -178,13 +179,14 @@ erl_forms(Mod, ParseD) ->
f_msg2rec(ParseD),
f_name2rec(ParseD),
f_avp_name(ParseD),
- f_avp_arity(ParseD),
+ f_avp_arity_1(ParseD),
+ f_avp_arity_2(ParseD),
f_avp_header(ParseD),
f_avp(ParseD),
f_enumerated_avp(ParseD),
f_empty_value(ParseD),
f_dict(ParseD),
- {eof, erl_anno:new(?LINE)}]],
+ {eof, ?LINE}]],
lists:append(Forms).
@@ -418,10 +420,32 @@ vendor_id_map(ParseD) ->
get_value(grouped, ParseD)).
%%% ------------------------------------------------------------------------
+%%% # avp_arity/1
+%%% ------------------------------------------------------------------------
+
+f_avp_arity_1(ParseD) ->
+ {?function, avp_arity, 1, avp_arities(ParseD) ++ [?BADARG(1)]}.
+
+avp_arities(ParseD) ->
+ Msgs = get_value(messages, ParseD),
+ Groups = get_value(grouped, ParseD)
+ ++ lists:flatmap(fun avps/1, get_value(import_groups, ParseD)),
+ lists:map(fun c_avp_arities/1, Msgs ++ Groups).
+
+c_avp_arities({N,_,_,_,As}) ->
+ c_avp_arities(N,As);
+c_avp_arities({N,_,_,As}) ->
+ c_avp_arities(N,As).
+
+c_avp_arities(Name, Avps) ->
+ Arities = [{?A(N), A} || T <- Avps, {N,A} <- [avp_info(T)]],
+ {?clause, [?Atom(Name)], [], [?TERM(Arities)]}.
+
+%%% ------------------------------------------------------------------------
%%% # avp_arity/2
%%% ------------------------------------------------------------------------
-f_avp_arity(ParseD) ->
+f_avp_arity_2(ParseD) ->
{?function, avp_arity, 2, avp_arity(ParseD)}.
avp_arity(ParseD) ->
@@ -452,7 +476,7 @@ c_arity(Name, Avp) ->
%%% ------------------------------------------------------------------------
f_avp(ParseD) ->
- {?function, avp, 3, avp(ParseD) ++ [?BADARG(3)]}.
+ {?function, avp, 4, avp(ParseD) ++ [?BADARG(4)]}.
avp(ParseD) ->
Native = get_value(avp_types, ParseD),
@@ -491,19 +515,25 @@ avp(Native, Imported, Custom, Enums) ->
not_in(List, X) ->
not lists:member(X, List).
-c_base_avp({AvpName, T}) ->
- {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName)],
+c_base_avp({AvpName, "Enumerated"}) ->
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('_')],
[],
- [b_base_avp(AvpName, T)]}.
+ [?CALL(enumerated_avp, [?VAR('T'), ?Atom(AvpName), ?VAR('Data')])]};
-b_base_avp(AvpName, "Enumerated") ->
- ?CALL(enumerated_avp, [?VAR('T'), ?Atom(AvpName), ?VAR('Data')]);
-
-b_base_avp(AvpName, "Grouped") ->
- ?CALL(grouped_avp, [?VAR('T'), ?Atom(AvpName), ?VAR('Data')]);
+c_base_avp({AvpName, "Grouped"}) ->
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
+ [],
+ [?CALL(grouped_avp, [?VAR('T'),
+ ?Atom(AvpName),
+ ?VAR('Data'),
+ ?VAR('Opts')])]};
-b_base_avp(_, Type) ->
- ?APPLY(diameter_types, ?A(Type), [?VAR('T'), ?VAR('Data')]).
+c_base_avp({AvpName, Type}) ->
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
+ [],
+ [?APPLY(diameter_types, ?A(Type), [?VAR('T'),
+ ?VAR('Data'),
+ ?VAR('Opts')])]}.
cs_imported_avp({Mod, Avps}, Enums, CustomNames) ->
lists:map(fun(A) -> imported_avp(Mod, A, Enums) end,
@@ -525,11 +555,13 @@ imported_avp(Mod, {AvpName, _, _, _}, _) ->
c_imported_avp(Mod, AvpName).
c_imported_avp(Mod, AvpName) ->
- {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName)],
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
[],
- [?APPLY(Mod, avp, [?VAR('T'),
- ?VAR('Data'),
- ?Atom(AvpName)])]}.
+ [?CALL(avp, [?VAR('T'),
+ ?VAR('Data'),
+ ?Atom(AvpName),
+ ?VAR('Opts'),
+ ?ATOM(Mod)])]}.
cs_custom_avp({Mod, Key, Avps}, Dict) ->
lists:map(fun(N) -> c_custom_avp(Mod, Key, N, orddict:fetch(N, Dict)) end,
@@ -537,9 +569,12 @@ cs_custom_avp({Mod, Key, Avps}, Dict) ->
c_custom_avp(Mod, Key, AvpName, Type) ->
{F,A} = custom(Key, AvpName, Type),
- {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName)],
+ {?clause, [?VAR('T'), ?VAR('Data'), ?Atom(AvpName), ?VAR('Opts')],
[],
- [?APPLY(?A(Mod), ?A(F), [?VAR('T'), ?Atom(A), ?VAR('Data')])]}.
+ [?APPLY(?A(Mod), ?A(F), [?VAR('T'),
+ ?Atom(A),
+ ?VAR('Data'),
+ ?VAR('Opts')])]}.
custom(custom_types, AvpName, Type) ->
{AvpName, Type};
@@ -568,7 +603,11 @@ enumerated_avp(Mod, Es, Enums) ->
Es).
cs_enumerated_avp(true, Mod, Name) ->
- [c_imported_avp(Mod, Name)];
+ [{?clause, [?VAR('T'), ?Atom(Name), ?VAR('Data')],
+ [],
+ [?APPLY(Mod, enumerated_avp, [?VAR('T'),
+ ?Atom(Name),
+ ?VAR('Data')])]}];
cs_enumerated_avp(false, _, _) ->
[].
@@ -682,7 +721,7 @@ v(false, _, _, _) ->
%%% ------------------------------------------------------------------------
f_empty_value(ParseD) ->
- {?function, empty_value, 1, empty_value(ParseD)}.
+ {?function, empty_value, 2, empty_value(ParseD)}.
empty_value(ParseD) ->
Imported = lists:flatmap(fun avps/1, get_value(import_enums, ParseD)),
@@ -692,15 +731,17 @@ empty_value(ParseD) ->
not lists:keymember(N, 1, Imported)]
++ Imported,
lists:map(fun c_empty_value/1, Groups ++ Enums)
- ++ [{?clause, [?VAR('Name')], [], [?CALL(empty, [?VAR('Name')])]}].
+ ++ [{?clause, [?VAR('Name'), ?VAR('Opts')],
+ [],
+ [?CALL(empty, [?VAR('Name'), ?VAR('Opts')])]}].
c_empty_value({Name, _, _, _}) ->
- {?clause, [?Atom(Name)],
+ {?clause, [?Atom(Name), ?VAR('Opts')],
[],
- [?CALL(empty_group, [?Atom(Name)])]};
+ [?CALL(empty_group, [?Atom(Name), ?VAR('Opts')])]};
c_empty_value({Name, _}) ->
- {?clause, [?Atom(Name)],
+ {?clause, [?Atom(Name), ?VAR('_')],
[],
[?TERM(<<0:32>>)]}.
@@ -790,20 +831,7 @@ header() ->
("%% -------------------------------------------------------------------\n"
"%% This is a generated file.\n"
"%% -------------------------------------------------------------------\n"
- "\n"
- "%%\n"
- "%% Copyright (c) Ericsson AB. All rights reserved.\n"
- "%%\n"
- "%% The information in this document is the property of Ericsson.\n"
- "%%\n"
- "%% Except as specifically authorized in writing by Ericsson, the\n"
- "%% receiver of this document shall keep the information contained\n"
- "%% herein confidential and shall protect the same in whole or in\n"
- "%% part from disclosure and dissemination to third parties.\n"
- "%%\n"
- "%% Disclosure and disseminations to the receivers employees shall\n"
- "%% only be made on a strict need to know basis.\n"
- "%%\n\n").
+ "\n").
hrl_header(Name) ->
header() ++ "-hrl_name('" ++ ?S(Name) ++ ".hrl').\n".