Repository: elixir-protobuf/protobuf (elixir)

Issue:
Repeated enum fields do not generate proper typespecs
I'm not 100% sure about this sorry so this is more a question than an statement

In the case we have

```protobuf
syntax = "proto3";
package test;

message Salute {
    repeated Word words = 1;
}

enum Word {
  WORD_HI = 0;
  WORD_BYE = 1;
  WORD_MISS = 2;
  WORD_MR = 3;
}
```

The generate generates the following

```elixir
defmodule Test.Salute do
  @moduledoc false
  use Protobuf, syntax: :proto3

  @type t :: %__MODULE__{
    words: [[Test.Word.t()]],
  }

  defstruct [
    :words
  ]

  field :words, 0, repeated: true, type: Test.Word, enum: true
end

defmodule Test.Word do
  @moduledoc false
  use Protobuf, enum: true, syntax: :proto3

  @type t ::
          integer
          | :WORD_HI
          | :WORD_BYE
          | :WORD_MISS
          | :WORD_MR

  field :WORD_HI, 0
  field :WORD_BYE, 1
  field :WORD_MISS, 2
  field :WORD_MR, 3
end
```

Would you mind to confirm that is the expected typespec instead just `words: [Test.Word.t()],` so just one single `[` instead of `[[`


Pull request description:
Fix repeated enum field generate [[]] into typespec
Removing `[]` out of `Protobuf.Protoc.Generator.Message.fmt_type/1` and
add `[]` into `Protobuf.TypeUtil.enum_to_spec/3` when `TYPE_MESSAGE` is match
alongs with repeated true.

Fixes #132

Patch:
diff --git a/lib/protobuf/protoc/generator/message.ex b/lib/protobuf/protoc/generator/message.ex
index a53cb18..821bea1 100644
--- a/lib/protobuf/protoc/generator/message.ex
+++ b/lib/protobuf/protoc/generator/message.ex
@@ -115,6 +115,7 @@ defmodule Protobuf.Protoc.Generator.Message do
         {fmt_type_name(f.name, longest_width), "{atom, any}"}
       end)
 
+
     types =
       types ++
         Enum.map(fields, fn f ->
@@ -153,7 +154,7 @@ defmodule Protobuf.Protoc.Generator.Message do
   end
 
   defp fmt_type(%{label: "repeated", type_enum: type_enum, type: type}) do
-    "[#{type_to_spec(type_enum, type, true)}]"
+    type_to_spec(type_enum, type, true)
   end
 
   defp fmt_type(%{type_enum: type_enum, type: type}) do
diff --git a/lib/protobuf/type_util.ex b/lib/protobuf/type_util.ex
index d6db5f2..8057623 100644
--- a/lib/protobuf/type_util.ex
+++ b/lib/protobuf/type_util.ex
@@ -36,7 +36,7 @@ defmodule Protobuf.TypeUtil do
   def enum_to_spec(:TYPE_SINT32), do: "integer"
   def enum_to_spec(:TYPE_SINT64), do: "integer"
   def enum_to_spec(_), do: "any"
-  def enum_to_spec(:TYPE_MESSAGE, type, true = _repeated), do: "#{type}.t"
+  def enum_to_spec(:TYPE_MESSAGE, type, true = _repeated), do: "[#{type}.t]"
   def enum_to_spec(:TYPE_MESSAGE, type, false = _repeated), do: "#{type}.t | nil"
   def enum_to_spec(:TYPE_ENUM, type, true = _repeated), do: "[#{type}.t]"
   def enum_to_spec(:TYPE_ENUM, type, false = _repeated), do: "#{type}.t"


Test patch:
diff --git a/test/protobuf/protoc/generator/message_test.exs b/test/protobuf/protoc/generator/message_test.exs
index 079e0f1..c4e9e8c 100644
--- a/test/protobuf/protoc/generator/message_test.exs
+++ b/test/protobuf/protoc/generator/message_test.exs
@@ -515,4 +515,31 @@ defmodule Protobuf.Protoc.Generator.MessageTest do
       assert msg =~ "field :the_field_name, 1, required: true, type: :string\n"
     end
   end
+
+  test "generate/2 repeated enum field in typespec" do
+    ctx = %Context{
+      package: "foo_bar.ab_cd",
+      dep_type_mapping: %{
+        ".foo_bar.ab_cd.EnumFoo" => %{type_name: "FooBar.AbCd.EnumFoo"}
+      }
+    }
+
+    desc =
+      Google.Protobuf.DescriptorProto.new(
+        name: "Foo",
+        field: [
+          Google.Protobuf.FieldDescriptorProto.new(
+            name: "a",
+            json_name: "a",
+            number: 1,
+            type: :TYPE_ENUM,
+            label: :LABEL_REPEATED,
+            type_name: ".foo_bar.ab_cd.EnumFoo"
+          )
+        ]
+      )
+
+    {[], [msg]} = Generator.generate(ctx, desc)
+    assert msg =~ "a: [FooBar.AbCd.EnumFoo.t]"
+  end
 end