bitwalker / bitwalker/exprotobuf

Using inject breaks enumerations with proto3

Open
#76 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Elixir
Stars
482
Forks
68
PR merge metrics
No merged PRs in 30d

Description

When using inject alongside enumerations, the namespace of the enumeration modules is inconsistent, causing the call to [get_default](https://github.com/bitwalker/exprotobuf/blob/fc6159d7f6a0b85930b2060d93be6fe3edf25fd9/lib/exprotobuf/decoder.ex#L47) to error with a no match, coming from [here](https://github.com/tomas-abrahamsson/gpb/blob/19f29c4f7fc50763ea51f7f48d0d3c4f3ca4c262/src/gpb.erl#L1221).

Reference protobuf
```protobuf
syntax = "proto3";

message Message {
enum Status {
STATE_1 = 0;
STATE_2 = 1;
}

required int64 id = 1;
optional Status status = 2;
}

```

## Example

### Module
```elixir
defmodule MessageTest do
use Protobuf, from: Path.expand("priv/protos/message.proto"), inject: true, only: :Message
end

```

### Defs
```elixir
iex(1)> MessageTest.defs()
[{{:enum, :"Message.Status"}, [STATE_1: 0, STATE_2: 1]},
{{:msg, :Message},
[%Protobuf.Field{fnum: 1, name: :id, occurrence: :required, opts: [], rnum: 2,
type: :int64},
%Protobuf.Field{fnum: 2, name: :status, occurrence: :optional, opts: [],
rnum: 3, type: {:enum, MessageTest.Message.Status}}]}]
```

Because of mismatch of the naming (`MessageTest.Message.Status` in the field vs `:enum, :"Message.Status"` in the key), when the field is looked up in `proto3_type_default`, `lists:keyfind/3` returns false, rather than a match.

I was able to circumvent this by adding `use_module_namespace: true`, unfortunately this has the side effect of ignoring the `inject` and `only` option, as [there is no function clause that takes it into account](https://github.com/bitwalker/exprotobuf/blob/fc6159d7f6a0b85930b2060d93be6fe3edf25fd9/lib/exprotobuf.ex#L41)

When not using inject, the field defs are generated as expected

## Example

### Module
```elixir
defmodule MessageTest do
use Protobuf, from: Path.expand("priv/protos/message.proto")
end
```

### Defs
```elixir
iex(1)> MessageTest.defs()
[{{:enum, MessageTest.Message.Status}, [STATE_1: 0, STATE_2: 1]},
{{:msg, MessageTest.Message},
[%Protobuf.Field{fnum: 1, name: :id, occurrence: :required, opts: [], rnum: 2,
type: :int64},
%Protobuf.Field{fnum: 2, name: :status, occurrence: :optional, opts: [],
rnum: 3, type: {:enum, MessageTest.Message.Status}}]}]
```

I'm happy to make a pr solving this issue, but would like to get some feedback on the direction to take with this before making a pr.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.