Current section
Files
Jump to
Current section
Files
lib/compiler.ex
defmodule ProtoDef.Compiler do
defmodule CustomType do
defstruct gen_decoder: nil, gen_encoder: nil
end
defmodule Context do
defstruct native_types: %{}, params: %{}, types: %{},
parse_name: &ProtoDef.Util.camel_string_to_snake_atom/1
@type t :: %__MODULE__{}
def native_type(ctx, type_id) when is_atom(type_id) do
ctx.native_types[type_id]
end
def native_type(ctx, type_id_str) when is_binary(type_id_str) do
case ProtoDef.Util.string_to_existing_atom(type_id_str) do
:nonexistent -> nil
{:ok, atom} ->
native_type(ctx, atom)
end
end
def native_type_add(ctx, type_id, definition = %{__struct__: _}) do
%{ ctx |
native_types: Map.put(ctx.native_types, type_id, definition)
}
end
def type(ctx, type_name) do
ctx.types[type_name]
end
def type_add(ctx, type_name, definition) do
%{ ctx |
types: Map.put(ctx.types, type_name, definition),
}
end
end
def compile_json_type(json_type, ctx) do
# Preprocess the json data structure into something easier to work with
descr = ProtoDef.Compiler.Preprocess.process_type(json_type, ctx)
# Assign identifiers to all the fields
{descr, ident, _count} = ProtoDef.Compiler.AssignIdents.assign(descr, 1, ctx)
# Resolve field references
descr = ProtoDef.Compiler.Resolve.run(descr, [], ctx)
# Generate structure
structure = ProtoDef.Compiler.Structure.gen_for_type(descr, ctx)
# Generate the Elixir AST
decoder_ast = ProtoDef.Gen.Elixir.Protocol.decoder(descr, ctx)
encoder_ast = ProtoDef.Gen.Elixir.Protocol.encoder(descr, ctx)
%{
descr: descr,
structure: structure,
decoder_ast: decoder_ast,
encoder_ast: encoder_ast,
}
end
end