Skip to content

Commit f668a2e

Browse files
I thought extension of extension would be cool but it doesn't work ...
1 parent a326bf5 commit f668a2e

File tree

8 files changed

+70
-37
lines changed

8 files changed

+70
-37
lines changed

lib/elixir.pb.ex

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
1-
defmodule Brex.Elixir.FieldOptions do
2-
@moduledoc false
3-
use Protobuf, syntax: :proto2
4-
5-
@type t :: %__MODULE__{
6-
extype: String.t()
7-
}
8-
defstruct [:extype]
9-
10-
field :extype, 1, optional: true, type: :string
11-
end
12-
131
defmodule Brex.Elixir.PbExtension do
142
@moduledoc false
153
use Protobuf, syntax: :proto2
164

17-
extend Google.Protobuf.FieldOptions, :field, 65_007,
18-
optional: true,
19-
type: Brex.Elixir.FieldOptions
5+
extend Elixirpb.FieldOptions, :extype, 1000, optional: true, type: :string
206
end

lib/elixirpb.pb.ex

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,30 @@ defmodule Elixirpb.FileOptions do
33
use Protobuf, syntax: :proto2
44

55
@type t :: %__MODULE__{
6-
module_prefix: String.t()
6+
module_prefix: String.t(),
7+
__pb_extensions__: map
78
}
8-
defstruct [:module_prefix]
9+
defstruct [:module_prefix, :__pb_extensions__]
910

1011
field :module_prefix, 1, optional: true, type: :string
12+
13+
extensions [{1000, 536_870_912}]
14+
end
15+
16+
defmodule Elixirpb.FieldOptions do
17+
@moduledoc false
18+
use Protobuf, syntax: :proto2
19+
20+
@type t :: %__MODULE__{__pb_extensions__: map}
21+
defstruct [:__pb_extensions__]
22+
23+
extensions [{1000, 536_870_912}]
1124
end
1225

1326
defmodule Elixirpb.PbExtension do
1427
@moduledoc false
1528
use Protobuf, syntax: :proto2
1629

1730
extend Google.Protobuf.FileOptions, :file, 1047, optional: true, type: Elixirpb.FileOptions
31+
extend Google.Protobuf.FieldOptions, :field, 65007, optional: true, type: Elixirpb.FieldOptions
1832
end

lib/protobuf/extension.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ defmodule Protobuf.Extension do
134134
if GlobalStore.get(fnum_key, nil) do
135135
raise "Extension #{inspect(ext.extendee)}##{fnum} already exists"
136136
end
137+
IO.inspect(:stderr, {fnum_key, mod}, label: :extensions)
137138

138139
GlobalStore.put(fnum_key, mod)
139140
end)

lib/protobuf/protoc/generator/message.ex

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ defmodule Protobuf.Protoc.Generator.Message do
1111
end
1212

1313
def generate(ctx, desc) do
14+
IO.inspect(:stderr, desc, label: :desc)
15+
1416
msg_struct = parse_desc(ctx, desc)
1517
IO.inspect(:stderr, msg_struct, label: :message_struct)
1618
ctx = %{ctx | namespace: msg_struct[:new_namespace]}
@@ -293,13 +295,32 @@ defmodule Protobuf.Protoc.Generator.Message do
293295
end
294296

295297
defp merge_field_options(opts, f) do
296-
extype_options = Google.Protobuf.FieldOptions.get_extension(f.options, Brex.Elixir.PbExtension, :field)
297-
298-
IO.inspect(:stderr, {opts, f.options, extype_options}, label: :together)
298+
field_options =
299+
f.options
300+
|> Google.Protobuf.FieldOptions.get_extension(Elixirpb.PbExtension, :field)
301+
|> case do
302+
nil -> nil
303+
elixir_field_options ->
304+
elixir_field_options
305+
# strips :__struct__
306+
|> Map.from_struct()
307+
|> Enum.flat_map(&get_custom_field_options/1)
308+
|> case do
309+
[] -> nil
310+
custom_opts -> custom_opts
311+
end
312+
end
299313

300314
opts
301-
|> Map.put(:packed, f.options.packed)
302-
|> Map.put(:deprecated, f.options.deprecated)
303-
|> Map.put(:options, "#{inspect(extype_options)}")
315+
|> Map.put(:packed, f.options.packed)
316+
|> Map.put(:deprecated, f.options.deprecated)
317+
|> Map.put(:options, field_options)
318+
end
319+
320+
def get_custom_field_options({:__pb_extensions__, opts}) do
321+
# For now if you want field options to show up in DSL you havee to extend Elixirpb.FieldOptions.
322+
Enum.map(opts, fn {{_extending_message, field}, arg} -> {field, arg} end)
304323
end
324+
# Collect existing Elixirpb.FieldOptions (right now no fields though).
325+
def get_custom_field_options({k, v}), do: [{k, v}]
305326
end

lib/protobuf/protoc/generator/util.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ defmodule Protobuf.Protoc.Generator.Util do
4949
end
5050

5151
def print(v) when is_atom(v), do: inspect(v)
52+
def print(v) when is_list(v), do: inspect(v)
5253
def print(v), do: v
5354
end

src/elixir.proto

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
1+
// This is not working, remove
2+
13
syntax = "proto2";
24

35
// we should call just elixirpb and merge with Tony's
46
// https://github.com/tony612/protobuf-elixir/blob/e1d4a23baa1f51c2da58db24f58a26dc4d6511b2/src/elixirpb.proto
57
package brex.elixir;
68

7-
import "google/protobuf/descriptor.proto";
9+
import "elixirpb.proto";
810

911
// Define an extension to specify the elixir type generated for the given field.
1012

1113
// Field level options
1214
//
1315
// For example,
14-
// google.protobuf.StringValue my_string = 1 [(brex.elixirpb.field).extype="String.t"];
15-
16-
message FieldOptions {
17-
// Specify an elixir type to generate for this field. This will override usual type.
18-
optional string extype = 1;
19-
}
16+
// google.protobuf.StringValue my_string = 1 [(elixirpb.field).extype="String.t"];
2017

21-
extend google.protobuf.FieldOptions {
18+
extend elixirpb.FieldOptions {
2219
// number to change
23-
optional FieldOptions field = 65007;
20+
optional string extype = 1000;
21+
//optional boolean lowercase = 1001;
2422
}

src/elixirpb.proto

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,20 @@ message FileOptions {
2323
// will be "Hello.Request". But with module_prefix "Foo", the message will be
2424
// "Foo.Request"
2525
optional string module_prefix = 1;
26+
extensions 1000 to max;
2627
}
2728

2829
extend google.protobuf.FileOptions {
2930
optional FileOptions file = 1047;
3031
}
3132

33+
message FieldOptions {
34+
// optional string extype = 1;
35+
extensions 1000 to max;
36+
}
37+
38+
extend google.protobuf.FieldOptions {
39+
// TODO: determine appropriate number
40+
optional FieldOptions field = 65007;
41+
}
42+

test/protobuf/protoc/generator/message_test.exs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,12 @@ defmodule Protobuf.Protoc.Generator.MessageTest do
176176
test "generate/2 supports extensions on field options" do
177177
ctx = %Context{package: ""}
178178

179-
opts = Google.Protobuf.FieldOptions.new()
180-
custom_opts = Brex.Elixir.FieldOptions.new(extype: "String.t")
179+
field_opts = Google.Protobuf.FieldOptions.new()
180+
elixir_opts = Elixirpb.FieldOptions.new()
181+
custom_opts = Elixirpb.FieldOptions.put_extension(elixir_opts, Brex.Elixir.PbExtension, :extype, "String.t")
181182

182183
opts =
183-
Google.Protobuf.FieldOptions.put_extension(opts, Brex.Elixir.PbExtension, :field, custom_opts)
184+
Google.Protobuf.FieldOptions.put_extension(field_opts, Elixirpb.PbExtension, :field, custom_opts)
184185

185186
desc =
186187
Google.Protobuf.DescriptorProto.new(
@@ -190,15 +191,15 @@ defmodule Protobuf.Protoc.Generator.MessageTest do
190191
name: "my_string",
191192
number: 1,
192193
type: :TYPE_MESSAGE,
193-
# type_name: ".google.protobuf.StringValue",
194+
# type_name: ".google.protodescbuf.StringValue",
194195
label: :LABEL_OPTIONAL,
195196
options: opts
196197
)
197198
]
198199
)
199200

200201
{[], [msg]} = Generator.generate(ctx, desc)
201-
assert msg =~ "field :my_string, 1, optional: true, type: :message, options: %Brex.Elixir.FieldOptions{extype: \"String.t\"}\n"
202+
assert msg =~ "field :my_string, 1, optional: true, type: :message, options: [extype: \"String.t\"]\n"
202203
end
203204

204205
test "generate/2 supports message type field" do

0 commit comments

Comments
 (0)