Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add julia_package option support #252

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/parsing/Parsers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ function parse_proto_file(ps::ParserState)
definitions[type.name] = type
end
end
package_identifier = get(options, "julia_package", package_identifier)
package_parts = split(package_identifier, '.', keepempty=false)
preamble = ProtoFilePreamble(
ps.is_proto3,
Expand All @@ -225,4 +226,4 @@ function parse_proto_file(ps::ParserState)
)
end

end # module
end # module
23 changes: 19 additions & 4 deletions src/parsing/proto_options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ function _parse_option_value(ps) # TODO: proper value parsing with validation
return has_minus ? string("-", str_val) : str_val
end

function _parse_julia_package(ps)
val = _parse_option_value(ps)
if startswith(val, "\"") && endswith(val, "\"") || startswith(val, "'") && endswith(val, "'")
val = val[begin+1:end-1]
if all(Lexers.is_fully_qualified_ident_char, val)
return val
end
end
error("Invalid value for julia_package option: $(val)")
end

function _parse_option_name(ps)
buf = IOBuffer()
option_name = ""
Expand Down Expand Up @@ -91,11 +102,15 @@ function _parse_option!(ps::ParserState, options::Dict{String,Union{String,Dict{
option_name = _parse_option_name(ps)
accept(ps, Tokens.COLON)
expectnext(ps, Tokens.EQ) # =
if accept(ps, Tokens.LBRACE) # {key: val, ...}
options[option_name] = _parse_aggregate_option(ps)
# accept(ps, Tokens.SEMICOLON)
if option_name == "julia_package"
options[option_name] = _parse_julia_package(ps)
else
options[option_name] = _parse_option_value(ps)
if accept(ps, Tokens.LBRACE) # {key: val, ...}
options[option_name] = _parse_aggregate_option(ps)
# accept(ps, Tokens.SEMICOLON)
else
options[option_name] = _parse_option_value(ps)
end
end
return nothing
end
10 changes: 10 additions & 0 deletions test/test_codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ end
end # module"""
end

@testset "Minimal proto file with julia_package option" begin
s, p, ctx = translate_simple_proto("""syntax = "proto3"; option julia_package = "Foo.Bar.Baz";""", Options(always_use_modules=false))
@test "Foo.Bar.Baz" == p.preamble.options["julia_package"]
@test ["Foo", "Bar", "Baz"] == namespace(p)

@test_throws ErrorException begin
translate_simple_proto("""syntax = "proto3"; option julia_package = "Foo/Bar/Baz";""", Options(always_use_modules=false))
end
end

@testset "`force_required` option makes optional fields required" begin
s, p, ctx = translate_simple_proto("message A {} message B { optional A a = 1; }", Options(force_required=Dict("main" => Set(["B.a"]))))
ctx._toplevel_name[] = "B"
Expand Down
25 changes: 25 additions & 0 deletions test/test_protojl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,28 @@ using ProtoBuf
@test pairs_message.map_field == decoded_pairs.map_field
end
end

module TestJuliaPackage
using Test
using ProtoBuf

@testset "Use julia_package option" begin
mktempdir() do tmpdir
@testset "translate source" begin
@test isnothing(protojl(
"test_julia_package.proto",
joinpath(@__DIR__, "test_protos/"),
tmpdir;
always_use_modules=false,
parametrize_oneofs=false
))
end
@testset "include generated" begin
@test include(joinpath(tmpdir, "Foo/Foo.jl")) isa Module
@test Foo.Bar.Baz.Message isa Type
@test :message == fieldnames(Foo.Bar.Baz.Message)[1]
@test String == fieldtypes(Foo.Bar.Baz.Message)[1]
end
end
end
end
7 changes: 7 additions & 0 deletions test/test_protos/test_julia_package.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

option julia_package = "Foo.Bar.Baz";

message Message {
string message = 1;
};
Loading