Skip to content

Commit

Permalink
Add julia_package option support
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkn committed Jun 8, 2024
1 parent 3eb59e1 commit 723a20b
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 5 deletions.
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
6 changes: 6 additions & 0 deletions test/test_codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ 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)
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

0 comments on commit 723a20b

Please sign in to comment.