Skip to content

Commit

Permalink
[bugfix] Fix incorrect package name extraction for nested messages (e…
Browse files Browse the repository at this point in the history
…lixir-grpc#21)

* add method get_package to Builder.Util

* revert helloworld.proto

* refine convert_symbol_to_module
  • Loading branch information
zhihuizhang17 authored Jan 3, 2024
1 parent 127a55c commit 20d579d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
4 changes: 2 additions & 2 deletions lib/grpc_reflection/service/builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ defmodule GrpcReflection.Service.Builder do
when extension_range != [] do
unencoded_extension_payload = %Google.Protobuf.FileDescriptorProto{
name: extension_file,
package: Util.package_from_name(symbol),
package: Util.get_package(symbol),
dependency: [symbol <> ".proto"],
syntax: Util.get_syntax(mod)
}
Expand Down Expand Up @@ -144,7 +144,7 @@ defmodule GrpcReflection.Service.Builder do
defp process_extensions(_, _, _, _), do: {:ignore, {nil, nil}}

defp process_common(name, module, descriptor) do
package = Util.package_from_name(name)
package = Util.get_package(name)

dependencies =
descriptor
Expand Down
31 changes: 16 additions & 15 deletions lib/grpc_reflection/service/builder/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ defmodule GrpcReflection.Service.Builder.Util do

@type_message Map.fetch!(Google.Protobuf.FieldDescriptorProto.Type.mapping(), :TYPE_MESSAGE)

def package_from_name(service_name) do
service_name
|> String.split(".")
|> Enum.reverse()
|> then(fn [_ | rest] -> rest end)
|> Enum.reverse()
|> Enum.join(".")
def get_package(symbol) do
parent_symbol = symbol |> String.split(".") |> Enum.slice(0..-2) |> Enum.join(".")

try do
parent_module = convert_symbol_to_module(parent_symbol)

if function_exported?(parent_module, :descriptor, 0) do
get_package(parent_symbol)
else
parent_symbol
end
rescue
_ -> parent_symbol
end
end

def upcase_first(<<first::utf8, rest::binary>>), do: String.upcase(<<first::utf8>>) <> rest
Expand Down Expand Up @@ -95,14 +102,8 @@ defmodule GrpcReflection.Service.Builder.Util do
name -> name
end)
|> String.split(".")
|> Enum.reverse()
|> then(fn
[m | segments] -> [m | Enum.map(segments, &upcase_first/1)]
end)
|> Enum.reverse()
|> Enum.join(".")
|> then(fn name -> "Elixir." <> name end)
|> String.to_existing_atom()
|> Enum.map(&upcase_first/1)
|> Module.safe_concat()
end

def is_message_descriptor?(%Google.Protobuf.FieldDescriptorProto{type: @type_message}),
Expand Down
22 changes: 20 additions & 2 deletions test/builder/util_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ defmodule GrpcReflection.Service.Builder.UtilTest do
end

describe "common utils" do
test "get package from module name" do
assert "a.b" == Util.package_from_name("a.b.CService")
test "get package from module" do
assert "testserviceV3" ==
Util.get_package("testserviceV3.TestRequest")

assert "testserviceV3" ==
Util.get_package("testserviceV3.TestRequest.Payload.Location")

assert "testserviceV3" ==
Util.get_package("testserviceV3.TestService")
end

test "upcase_first" do
Expand All @@ -21,6 +28,17 @@ defmodule GrpcReflection.Service.Builder.UtilTest do
test "downcase_first" do
assert "hello" == Util.downcase_first("Hello")
end

test "convert symbol to module succeed" do
assert TestserviceV3.TestRequest ==
Util.convert_symbol_to_module("testserviceV3.TestRequest")
end

test "convert symbol to module fail" do
assert_raise ArgumentError, fn ->
Util.convert_symbol_to_module("testservice.TestRequest.Payload.Location")
end
end
end

describe "utils for dealing with proto2 only" do
Expand Down

0 comments on commit 20d579d

Please sign in to comment.