Skip to content

Commit a326bf5

Browse files
wip that works, committing in case I f it up
1 parent c12e546 commit a326bf5

File tree

11 files changed

+108
-5
lines changed

11 files changed

+108
-5
lines changed

config/config.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
use Mix.Config
2+
3+
config :protobuf, extensions: :enabled
4+

lib/elixir.pb.ex

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
13+
defmodule Brex.Elixir.PbExtension do
14+
@moduledoc false
15+
use Protobuf, syntax: :proto2
16+
17+
extend Google.Protobuf.FieldOptions, :field, 65_007,
18+
optional: true,
19+
type: Brex.Elixir.FieldOptions
20+
end

lib/protobuf/extension/props.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ defmodule Protobuf.Extension.Props do
55
@moduledoc false
66
@type t :: %__MODULE__{
77
extendee: module,
8-
field_props: FieldProps.T
8+
field_props: FieldProps.t
99
}
1010
defstruct extendee: nil,
1111
field_props: nil

lib/protobuf/field_props.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ defmodule Protobuf.FieldProps do
1717
packed?: boolean,
1818
map?: boolean,
1919
deprecated?: boolean,
20-
encoded_fnum: iodata
20+
encoded_fnum: iodata,
21+
options: List.t() | nil
2122
}
2223
defstruct fnum: nil,
2324
name: nil,
@@ -34,5 +35,6 @@ defmodule Protobuf.FieldProps do
3435
packed?: nil,
3536
map?: false,
3637
deprecated?: false,
37-
encoded_fnum: nil
38+
encoded_fnum: nil,
39+
options: nil
3840
end

lib/protobuf/message_props.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ defmodule Protobuf.MessageProps do
66
@type t :: %__MODULE__{
77
ordered_tags: [integer],
88
tags_map: %{integer => integer},
9-
field_props: %{integer => FieldProps.T},
9+
field_props: %{integer => FieldProps.t},
1010
field_tags: %{atom => integer},
1111
repeated_fields: [atom],
1212
embedded_fields: [atom],

lib/protobuf/protoc/generator/message.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ defmodule Protobuf.Protoc.Generator.Message do
1212

1313
def generate(ctx, desc) do
1414
msg_struct = parse_desc(ctx, desc)
15+
IO.inspect(:stderr, msg_struct, label: :message_struct)
1516
ctx = %{ctx | namespace: msg_struct[:new_namespace]}
1617
{nested_enums, nested_msgs} = Enum.unzip(gen_nested_msgs(ctx, desc))
1718

@@ -179,8 +180,10 @@ defmodule Protobuf.Protoc.Generator.Message do
179180
end
180181

181182
def get_field(ctx, f, nested_maps, oneofs) do
183+
182184
opts = field_options(f)
183185
map = nested_maps[f.type_name]
186+
184187
opts = if map, do: Map.put(opts, :map, true), else: opts
185188

186189
opts =
@@ -290,8 +293,13 @@ defmodule Protobuf.Protoc.Generator.Message do
290293
end
291294

292295
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)
299+
293300
opts
294301
|> Map.put(:packed, f.options.packed)
295302
|> Map.put(:deprecated, f.options.deprecated)
303+
|> Map.put(:options, "#{inspect(extype_options)}")
296304
end
297305
end

src/elixir.proto

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
syntax = "proto2";
2+
3+
// we should call just elixirpb and merge with Tony's
4+
// https://github.com/tony612/protobuf-elixir/blob/e1d4a23baa1f51c2da58db24f58a26dc4d6511b2/src/elixirpb.proto
5+
package brex.elixir;
6+
7+
import "google/protobuf/descriptor.proto";
8+
9+
// Define an extension to specify the elixir type generated for the given field.
10+
11+
// Field level options
12+
//
13+
// 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+
}
20+
21+
extend google.protobuf.FieldOptions {
22+
// number to change
23+
optional FieldOptions field = 65007;
24+
}

src/elixirpb.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ message FileOptions {
2828
extend google.protobuf.FileOptions {
2929
optional FileOptions file = 1047;
3030
}
31+

test/protobuf/dsl_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,9 @@ defmodule Protobuf.DSLTest do
223223
assert msg_props.field_props[4].oneof == 1
224224
refute msg_props.field_props[5].oneof
225225
end
226+
227+
test "Extension use case" do
228+
msg_props = TestMsg.Ext.UseCase.__message_props__()
229+
assert %Protobuf.FieldProps{options: [extype: "String.t"]} = msg_props.field_props[1]
230+
end
226231
end

test/protobuf/protoc/generator/message_test.exs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,35 @@ defmodule Protobuf.Protoc.Generator.MessageTest do
173173
assert msg =~ "field :a, 1, optional: true, type: :int32, deprecated: true\n"
174174
end
175175

176-
test "generete/2 supports message type field" do
176+
test "generate/2 supports extensions on field options" do
177+
ctx = %Context{package: ""}
178+
179+
opts = Google.Protobuf.FieldOptions.new()
180+
custom_opts = Brex.Elixir.FieldOptions.new(extype: "String.t")
181+
182+
opts =
183+
Google.Protobuf.FieldOptions.put_extension(opts, Brex.Elixir.PbExtension, :field, custom_opts)
184+
185+
desc =
186+
Google.Protobuf.DescriptorProto.new(
187+
name: "Foo",
188+
field: [
189+
Google.Protobuf.FieldDescriptorProto.new(
190+
name: "my_string",
191+
number: 1,
192+
type: :TYPE_MESSAGE,
193+
# type_name: ".google.protobuf.StringValue",
194+
label: :LABEL_OPTIONAL,
195+
options: opts
196+
)
197+
]
198+
)
199+
200+
{[], [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+
end
203+
204+
test "generate/2 supports message type field" do
177205
ctx = %Context{
178206
package: "",
179207
dep_type_mapping: %{

0 commit comments

Comments
 (0)