Skip to content

Commit

Permalink
wip that works, committing in case I f it up
Browse files Browse the repository at this point in the history
  • Loading branch information
lizziepaquette committed Apr 6, 2020
1 parent 242be79 commit a0ed603
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 5 deletions.
3 changes: 3 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
use Mix.Config

config :protobuf, extensions: :enabled

20 changes: 20 additions & 0 deletions lib/elixir.pb.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule Brex.Elixir.FieldOptions do
@moduledoc false
use Protobuf, syntax: :proto2

@type t :: %__MODULE__{
extype: String.t()
}
defstruct [:extype]

field :extype, 1, optional: true, type: :string
end

defmodule Brex.Elixir.PbExtension do
@moduledoc false
use Protobuf, syntax: :proto2

extend Google.Protobuf.FieldOptions, :field, 65_007,
optional: true,
type: Brex.Elixir.FieldOptions
end
2 changes: 1 addition & 1 deletion lib/protobuf/extension/props.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Protobuf.Extension.Props do
@moduledoc false
@type t :: %__MODULE__{
extendee: module,
field_props: FieldProps.T
field_props: FieldProps.t
}
defstruct extendee: nil,
field_props: nil
Expand Down
6 changes: 4 additions & 2 deletions lib/protobuf/field_props.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ defmodule Protobuf.FieldProps do
packed?: boolean,
map?: boolean,
deprecated?: boolean,
encoded_fnum: iodata
encoded_fnum: iodata,
options: List.t() | nil
}
defstruct fnum: nil,
name: nil,
Expand All @@ -34,5 +35,6 @@ defmodule Protobuf.FieldProps do
packed?: nil,
map?: false,
deprecated?: false,
encoded_fnum: nil
encoded_fnum: nil,
options: nil
end
2 changes: 1 addition & 1 deletion lib/protobuf/message_props.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Protobuf.MessageProps do
@type t :: %__MODULE__{
ordered_tags: [integer],
tags_map: %{integer => integer},
field_props: %{integer => FieldProps.T},
field_props: %{integer => FieldProps.t},
field_tags: %{atom => integer},
repeated_fields: [atom],
embedded_fields: [atom],
Expand Down
8 changes: 8 additions & 0 deletions lib/protobuf/protoc/generator/message.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule Protobuf.Protoc.Generator.Message do

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

Expand Down Expand Up @@ -177,8 +178,10 @@ defmodule Protobuf.Protoc.Generator.Message do
end

def get_field(ctx, f, nested_maps, oneofs) do

opts = field_options(f)
map = nested_maps[f.type_name]

opts = if map, do: Map.put(opts, :map, true), else: opts

opts =
Expand Down Expand Up @@ -288,8 +291,13 @@ defmodule Protobuf.Protoc.Generator.Message do
end

defp merge_field_options(opts, f) do
extype_options = Google.Protobuf.FieldOptions.get_extension(f.options, Brex.Elixir.PbExtension, :field)

IO.inspect(:stderr, {opts, f.options, extype_options}, label: :together)

opts
|> Map.put(:packed, f.options.packed)
|> Map.put(:deprecated, f.options.deprecated)
|> Map.put(:options, "#{inspect(extype_options)}")
end
end
24 changes: 24 additions & 0 deletions src/elixir.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
syntax = "proto2";

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

import "google/protobuf/descriptor.proto";

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

// Field level options
//
// For example,
// google.protobuf.StringValue my_string = 1 [(brex.elixirpb.field).extype="String.t"];

message FieldOptions {
// Specify an elixir type to generate for this field. This will override usual type.
optional string extype = 1;
}

extend google.protobuf.FieldOptions {
// number to change
optional FieldOptions field = 65007;
}
1 change: 1 addition & 0 deletions src/elixirpb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ message FileOptions {
extend google.protobuf.FileOptions {
optional FileOptions file = 1047;
}

5 changes: 5 additions & 0 deletions test/protobuf/dsl_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,9 @@ defmodule Protobuf.DSLTest do
assert msg_props.field_props[4].oneof == 1
refute msg_props.field_props[5].oneof
end

test "Extension use case" do
msg_props = TestMsg.Ext.UseCase.__message_props__()
assert %Protobuf.FieldProps{options: [extype: "String.t"]} = msg_props.field_props[1]
end
end
30 changes: 29 additions & 1 deletion test/protobuf/protoc/generator/message_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,35 @@ defmodule Protobuf.Protoc.Generator.MessageTest do
assert msg =~ "field :a, 1, optional: true, type: :int32, deprecated: true\n"
end

test "generete/2 supports message type field" do
test "generate/2 supports extensions on field options" do
ctx = %Context{package: ""}

opts = Google.Protobuf.FieldOptions.new()
custom_opts = Brex.Elixir.FieldOptions.new(extype: "String.t")

opts =
Google.Protobuf.FieldOptions.put_extension(opts, Brex.Elixir.PbExtension, :field, custom_opts)

desc =
Google.Protobuf.DescriptorProto.new(
name: "Foo",
field: [
Google.Protobuf.FieldDescriptorProto.new(
name: "my_string",
number: 1,
type: :TYPE_MESSAGE,
# type_name: ".google.protobuf.StringValue",
label: :LABEL_OPTIONAL,
options: opts
)
]
)

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

test "generate/2 supports message type field" do
ctx = %Context{
package: "",
dep_type_mapping: %{
Expand Down
12 changes: 12 additions & 0 deletions test/support/test_msg.ex
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,16 @@ defmodule TestMsg do
extend Ext.Foo2, :bar, 1047, optional: true, type: :string
extend Ext.Foo1, :"Parent.foo", 1048, optional: true, type: Ext.EnumFoo, enum: true
end

defmodule Ext.UseCase do
@moduledoc false
use Protobuf, syntax: :proto3

@type t :: %__MODULE__{
my_string: Google.Protobuf.StringValue.t() | nil
}
defstruct [:my_string]

field :my_string, 1, type: Google.Protobuf.StringValue, options: [extype: "String.t"]
end
end

0 comments on commit a0ed603

Please sign in to comment.