Protox

Build StatusCoverage StatusHex.pm VersionDeps StatusInline docs

Protox is an Elixir library to work with Google's Protocol Buffers. It supports both versions 2 and 3.

Usage

From files:

defmodule Foo do
use Protox, files: [
"./defs/foo.proto",
"./defs/bar.proto",
"./defs/baz/fiz.proto",
]
end

From a textual description:

defmodule Bar do
use Protox, schema: """
syntax = "proto3";
package fiz;
message Baz {
}
message Foo {
int32 a = 1;
map<int32, Baz> b = 2;
}
"""
end

The previous example will generate two modules: Fiz.Baz and Fiz.Foo.

It's possible to prepend a namespace to all generated modules:

defmodule Bar do
use Protox, schema: """
syntax = "proto3";
enum Enum {
FOO = 0;
BAR = 1;
}
""",
namespace: Namespace
end

In this case, the module Namespace.Enum will be generated.

Here's how to create a new message:

iex> %Fiz.Foo{a: 3, b: %{1 => %Fiz.Baz{}}} |> Protox.Encode.encode()
[[[], "\b", <<3>>], <<18>>, <<4>>, "\b", <<1>>, <<18>>, <<0>>]

Note that Protox.Encode.encode/1 creates an iolist, not a binary. Such iolists can be used directly with file or sockets read/write operations. However, you can use :binary.list_to_bin() to get a binary:

iex> %Fiz.Foo{a: 3, b: %{1 => %Fiz.Baz{}}} |> Protox.Encode.encode() |> :binary.list_to_bin()
<<8, 3, 18, 4, 8, 1, 18, 0>>

Finally, here's how to decode:

iex> <<8, 3, 18, 4, 8, 1, 18, 0>> |> Fiz.Foo.decode()
{:ok, %Fiz.Foo{a: 3, b: %{1 => %Fiz.Baz{}}}}

Prerequisites

Protox uses Google's protoc (>= 3.0) to parse .proto files. It must be available in $PATH. You can get it here.

Unsupported features

Furthermore, all options other than packed and default are ignored.

Implementation choices

Types mapping

ProtobufElixir
int32integer()
int64integer()
uint32integer()
uint64integer()
sint32integer()
sint64integer()
fixed32integer()
fixed64integer()
sfixed32integer()
sfixed64integer()
floatfloat()
doublefloat()
boolboolean()
stringString.t
bytesbinary()
map%{}
oneof {:field, value}
enumatom()
messagestruct()

Performance

TODO. Do some benchmarks.

Conformance

This library has been tested using the conformance checker provided by Google. Note that only the protobuf part is tested: as protox doesn't support JSON output, the corresponding tests are skipped.

Here's how to launch the conformance test:

Credits

Both gpb and exprotobuf were very useful in understanding how to implement Protocol Buffers.