Squashed 'third_party/upb/' changes from d8f3d6f9d4..ce1a399a19

ce1a399a19 Text format serializer for upb_msg (#242)
888f35cae6 Merge pull request #241 from haberman/conformance-fixes
46b93f8cea A bit more cleanup in the decoder.
ad2eb65a4b Refactored conformance_upb to use reflection, and fixed a decoder bug.
a202c5f84d Merge pull request #234 from haberman/parser
4c974cf72d Fixed generated files.
9a870d957f Removed upb_decframe and made ptr an explicit parameter and return.
a6c54729df Added UPB_ASSUME(), to work around warnings when optimization is enabled:
9e1f89ef2c Merge pull request #224 from haberman/maps
ce0496eb86 Merge branch 'master' into maps
e911aae5f6 Factored upb_map_entry into a shared place.
4c1a97ae9c Merge branch 'master' into maps
59fe620fa0 Merge branch 'maps' of github.com:haberman/upb into maps
744f8588da Cleanup to remove END_GROUP from descriptortype -> type tables.
f9efbcd5d6 Added missing append fallback.
c4b64e6a20 Slight simplification: NULL arena will avoid creating a new sub-object.
d541566a7b Moved upb_array_new() to upb/reflection.h where it belongs.
059f226d41 Unit tests for maps generated code.
520ddc1f11 c89 fixes.
806c8c9c6e Removed obsolete testing files.
2a85bef825 Generated code interface for maps is complete, though not yet tested.
7f5fe52dfa Fixes for non-C89 code.
6c2d732082 Fixed upb's map parsing to overwrite existing elements.
090a0c33a4 Fixed VLA error and rewrote the map parsing code to be clearer.
0fbae939d2 Removed stray fprintf().
572ba75d1c Removed comma after final enumerator.
c9135e5276 Fixed the build.
d040aa1302 Merge branch 'master' into maps
e18541a9dd Added some missing files.
92509cc3b2 Rename lua_test.
382f92a87f Maps encode and decode successfully!
4c57b1fefd More progress on Lua extension.
d6c3152c0b Added more Lua tests that are passing.
ae66e571d4 Fixed some bugs and added a few more tests.
bfc86d3577 Fixed many bugs, basic Lua test passes!
b518b06d75 Lua test program is loaded successfully.
6ae4a2694c Merge branch 'maps' of github.com:haberman/upb into maps
cc6db9fb0b Fixed crash bug.
88d996132e Added Lua main.c test driver program.
626ec4bfcf Everything builds, test pass except test_decoder.
5239655b99 WIP.
23825332e1 WIP.
27b95c969a WIP.
9a360ad43d Moved legacy_msg_reflection.{c,h} -> reflection.{c.h}.
dc58b657ee New reflection API doesn't need types as parameters for map/array.
c486da3970 WIP.
b76040cfcc Merge branch 'maps' of github.com:haberman/upb into maps
cc8e894b63 Merge branch 'master' into maps
946880c105 Merge branch 'master' into maps
1461da5056 WIP.
0a07f2714b Merge branch 'master' into maps
18de110b00 Merge branch 'master' into maps
283857f308 WIP.
5dea3f8486 Merge branch 'master' into maps
07ac6f0e8e Merge branch 'master' into maps
0c64c4b594 WIP.

git-subtree-dir: third_party/upb
git-subtree-split: ce1a399a19f11683d58ba4c2569ec3fdd5a67621
pull/23140/head
Mark D. Roth 5 years ago
parent f9d27c0b8c
commit 6a73cb0236
  1. 166
      BUILD
  2. 18
      CMakeLists.txt
  3. 91
      bazel/build_defs.bzl
  4. 73
      bazel/upb_proto_library.bzl
  5. 237
      generated_for_cmake/google/protobuf/descriptor.upb.h
  6. 6
      generated_for_cmake/upb/json/parser.c
  7. 165
      tests/bindings/googlepb/test_vs_proto2.cc
  8. 56
      tests/bindings/lua/main.c
  9. 946
      tests/bindings/lua/test_upb.lua
  10. 80
      tests/bindings/lua/test_upb.pb.lua
  11. 62
      tests/bindings/ruby/upb.rb
  12. 201
      tests/conformance_upb.c
  13. BIN
      tests/google_message1.dat
  14. BIN
      tests/google_message2.dat
  15. 149
      tests/google_messages.proto
  16. 33
      tests/pb/test_varint.c
  17. BIN
      tests/test.proto.pb
  18. 329
      tests/test_generated_code.c
  19. 3
      tests/test_table.cc
  20. 13
      tools/make_cmakelists.py
  21. 501
      upb/bindings/lua/def.c
  22. 109
      upb/bindings/lua/lua_proto_library.bzl
  23. 1298
      upb/bindings/lua/msg.c
  24. 170
      upb/bindings/lua/upb.c
  25. 119
      upb/bindings/lua/upb.h
  26. 182
      upb/bindings/lua/upb.lua
  27. 56
      upb/bindings/lua/upb/pb.c
  28. 3
      upb/bindings/lua/upb/pb.lua
  29. 112
      upb/bindings/lua/upbc.cc
  30. 487
      upb/decode.c
  31. 281
      upb/def.c
  32. 8
      upb/def.h
  33. 211
      upb/encode.c
  34. 105
      upb/generated_util.h
  35. 6
      upb/json/parser.rl
  36. 19
      upb/json/printer.c
  37. 399
      upb/legacy_msg_reflection.c
  38. 191
      upb/legacy_msg_reflection.h
  39. 149
      upb/msg.c
  40. 353
      upb/msg.h
  41. 248
      upb/msgfactory.c
  42. 48
      upb/msgfactory.h
  43. 4
      upb/pb/compile_decoder.c
  44. 20
      upb/pb/varint.int.h
  45. 17
      upb/port_def.inc
  46. 2
      upb/port_undef.inc
  47. 289
      upb/reflection.c
  48. 153
      upb/reflection.h
  49. 94
      upb/table.c
  50. 54
      upb/table.int.h
  51. 393
      upb/textencode.c
  52. 27
      upb/textencode.h
  53. 17
      upb/upb.h
  54. 174
      upbc/generator.cc
  55. 11
      upbc/message_layout.cc

166
BUILD

@ -2,10 +2,6 @@ load(
"//bazel:build_defs.bzl",
"generated_file_staleness_test",
"licenses", # copybara:strip_for_google3
"lua_binary",
"lua_cclibrary",
"lua_library",
"lua_test",
"make_shell_script",
"upb_amalgamation",
)
@ -14,6 +10,10 @@ load(
"upb_proto_library",
"upb_proto_reflection_library",
)
load(
"//:upb/bindings/lua/lua_proto_library.bzl",
"lua_proto_library",
)
licenses(["notice"]) # BSD (Google-authored w/ possible external contributions)
@ -32,6 +32,7 @@ CPPOPTS = [
COPTS = CPPOPTS + [
# copybara:strip_for_google3_begin
"-pedantic",
"-Werror=pedantic",
"-Wstrict-prototypes",
# copybara:strip_end
]
@ -70,7 +71,6 @@ cc_library(
srcs = [
"upb/decode.c",
"upb/encode.c",
"upb/generated_util.h",
"upb/msg.c",
"upb/msg.h",
"upb/table.c",
@ -99,7 +99,6 @@ cc_library(
cc_library(
name = "generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
hdrs = [
"upb/generated_util.h",
"upb/msg.h",
"upb/port_def.inc",
"upb/port_undef.inc",
@ -124,11 +123,11 @@ cc_library(
name = "reflection",
srcs = [
"upb/def.c",
"upb/msgfactory.c",
"upb/reflection.c",
],
hdrs = [
"upb/def.h",
"upb/msgfactory.h",
"upb/reflection.h",
],
copts = select({
":windows": [],
@ -143,37 +142,33 @@ cc_library(
],
)
# Internal C/C++ libraries #####################################################
cc_library(
name = "table",
hdrs = ["upb/table.int.h"],
name = "textformat",
srcs = [
"upb/textencode.c",
],
hdrs = [
"upb/textencode.h",
],
visibility = ["//visibility:public"],
deps = [
":port",
":upb",
":reflection",
],
)
# Legacy C/C++ Libraries (not recommended for new code) ########################
# Internal C/C++ libraries #####################################################
cc_library(
name = "legacy_msg_reflection",
srcs = [
"upb/msg.h",
"upb/legacy_msg_reflection.c",
],
hdrs = ["upb/legacy_msg_reflection.h"],
copts = select({
":windows": [],
"//conditions:default": COPTS
}),
name = "table",
hdrs = ["upb/table.int.h"],
deps = [
":port",
":table",
":upb",
],
)
# Legacy C/C++ Libraries (not recommended for new code) ########################
cc_library(
name = "handlers",
srcs = [
@ -359,6 +354,21 @@ cc_test(
],
)
cc_test(
name = "test_generated_code",
srcs = ["tests/test_generated_code.c"],
deps = [
":test_messages_proto3_proto_upb",
":upb_test",
],
)
upb_proto_reflection_library(
name = "test_messages_proto3_proto_upb",
testonly = 1,
deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
)
proto_library(
name = "test_decoder_proto",
srcs = [
@ -526,8 +536,20 @@ upb_proto_library(
deps = ["@com_google_protobuf//:conformance_proto"],
)
upb_proto_library(
name = "test_messages_proto3_proto_upb",
upb_proto_reflection_library(
name = "conformance_proto_upbdefs",
testonly = 1,
deps = ["@com_google_protobuf//:conformance_proto"],
)
upb_proto_reflection_library(
name = "test_messages_proto2_upbdefs",
testonly = 1,
deps = ["@com_google_protobuf//:test_messages_proto2_proto"],
)
upb_proto_reflection_library(
name = "test_messages_proto3_upbdefs",
testonly = 1,
deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
)
@ -544,7 +566,11 @@ cc_binary(
}) + ["-Ibazel-out/k8-fastbuild/bin"],
deps = [
":conformance_proto_upb",
":test_messages_proto3_proto_upb",
":conformance_proto_upbdefs",
":test_messages_proto2_upbdefs",
":test_messages_proto3_upbdefs",
":reflection",
":textformat",
":upb",
],
)
@ -552,7 +578,7 @@ cc_binary(
make_shell_script(
name = "gen_test_conformance_upb",
out = "test_conformance_upb.sh",
contents = "external/com_google_protobuf/conformance_test_runner ./conformance_upb",
contents = "external/com_google_protobuf/conformance_test_runner --enforce_recommended ./conformance_upb",
)
sh_test(
@ -563,6 +589,7 @@ sh_test(
":conformance_upb",
"@com_google_protobuf//:conformance_test_runner",
],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
# copybara:strip_for_google3_begin
@ -602,10 +629,10 @@ cc_library(
}),
)
# Lua libraries. ###############################################################
# Lua ##########################################################################
lua_cclibrary(
name = "lua/upb_c",
cc_library(
name = "lupb",
srcs = [
"upb/bindings/lua/def.c",
"upb/bindings/lua/msg.c",
@ -615,48 +642,56 @@ lua_cclibrary(
"upb/bindings/lua/upb.h",
],
deps = [
"legacy_msg_reflection",
"upb",
"upb_pb",
":reflection",
":upb",
"@lua//:liblua",
],
)
lua_library(
name = "lua/upb",
srcs = ["upb/bindings/lua/upb.lua"],
luadeps = ["lua/upb_c"],
strip_prefix = "upb/bindings/lua",
)
lua_cclibrary(
name = "lua/upb/pb_c",
srcs = ["upb/bindings/lua/upb/pb.c"],
luadeps = ["lua/upb_c"],
deps = ["upb_pb"],
cc_test(
name = "test_lua",
linkstatic = 1,
srcs = ["tests/bindings/lua/main.c"],
data = [
"@com_google_protobuf//:conformance_proto",
"@com_google_protobuf//:descriptor_proto",
":descriptor_proto_lua",
":test_messages_proto3_proto_lua",
"tests/bindings/lua/test_upb.lua",
"third_party/lunit/console.lua",
"third_party/lunit/lunit.lua",
"upb/bindings/lua/upb.lua",
],
deps = [
":lupb",
"@lua//:liblua",
]
)
lua_library(
name = "lua/upb/pb",
srcs = ["upb/bindings/lua/upb/pb.lua"],
luadeps = [
"lua/upb",
"lua/upb/pb_c",
cc_binary(
name = "protoc-gen-lua",
srcs = ["upb/bindings/lua/upbc.cc"],
copts = select({
":windows": [],
"//conditions:default": CPPOPTS
}),
visibility = ["//visibility:public"],
deps = [
"@com_google_absl//absl/strings",
"@com_google_protobuf//:protoc_lib"
],
strip_prefix = "upb/bindings/lua",
)
# Lua tests. ###################################################################
lua_test(
name = "lua/test_upb",
luadeps = ["lua/upb"],
luamain = "tests/bindings/lua/test_upb.lua",
lua_proto_library(
name = "descriptor_proto_lua",
visibility = ["//visibility:public"],
deps = ["@com_google_protobuf//:descriptor_proto"],
)
lua_test(
name = "lua/test_upb_pb",
luadeps = ["lua/upb/pb"],
luamain = "tests/bindings/lua/test_upb.pb.lua",
lua_proto_library(
name = "test_messages_proto3_proto_lua",
testonly = 1,
deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
)
# Test the CMake build #########################################################
@ -683,6 +718,7 @@ sh_test(
name = "cmake_build",
srcs = ["run_cmake_build.sh"],
data = [":cmake_files"],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
# Generated files ##############################################################

@ -65,7 +65,6 @@ add_library(port
add_library(upb
upb/decode.c
upb/encode.c
upb/generated_util.h
upb/msg.c
upb/msg.h
upb/table.c
@ -81,26 +80,23 @@ target_link_libraries(generated_code_support__only_for_generated_code_do_not_use
upb)
add_library(reflection
upb/def.c
upb/msgfactory.c
upb/reflection.c
upb/def.h
upb/msgfactory.h)
upb/reflection.h)
target_link_libraries(reflection
descriptor_upbproto
port
table
upb)
add_library(textformat
upb/textencode.c
upb/textencode.h)
target_link_libraries(textformat
reflection)
add_library(table INTERFACE)
target_link_libraries(table INTERFACE
port
upb)
add_library(legacy_msg_reflection
upb/msg.h
upb/legacy_msg_reflection.c
upb/legacy_msg_reflection.h)
target_link_libraries(legacy_msg_reflection
port
table
upb)
add_library(handlers
upb/handlers.c
upb/handlers-inl.h

@ -5,6 +5,19 @@ load(":upb_proto_library.bzl", "GeneratedSrcsInfo")
def _librule(name):
return name + "_lib"
runfiles_init = """\
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
"""
def _get_real_short_path(file):
# For some reason, files from other archives have short paths that look like:
# ../com_google_protobuf/google/protobuf/descriptor.proto
@ -26,42 +39,6 @@ def _get_real_roots(files):
roots[real_root] = True
return roots.keys()
def lua_cclibrary(name, srcs, hdrs = [], deps = [], luadeps = []):
lib_rule = name + "_lib"
so_rule = "lib" + name + ".so"
so_file = _remove_prefix(name, "lua/") + ".so"
native.cc_library(
name = _librule(name),
hdrs = hdrs,
srcs = srcs,
deps = deps + [_librule(dep) for dep in luadeps] + ["@lua//:liblua_headers"],
)
native.cc_binary(
name = so_rule,
linkshared = True,
deps = [_librule(name)],
linkopts = select({
":darwin": [
"-undefined dynamic_lookup",
],
"//conditions:default": [],
}),
)
native.genrule(
name = name + "_copy",
srcs = [":" + so_rule],
outs = [so_file],
cmd = "cp $< $@",
)
native.filegroup(
name = name,
data = [so_file],
)
def _remove_prefix(str, prefix):
if not str.startswith(prefix):
fail("%s doesn't start with %s" % (str, prefix))
@ -72,54 +49,14 @@ def _remove_suffix(str, suffix):
fail("%s doesn't end with %s" % (str, suffix))
return str[:-len(suffix)]
def lua_library(name, srcs, strip_prefix, luadeps = []):
outs = [_remove_prefix(src, strip_prefix + "/") for src in srcs]
native.genrule(
name = name + "_copy",
srcs = srcs,
outs = outs,
cmd = "cp $(SRCS) $(@D)",
)
native.filegroup(
name = name,
data = outs + luadeps,
)
def make_shell_script(name, contents, out):
contents = contents.replace("$", "$$")
contents = (runfiles_init + contents).replace("$", "$$")
native.genrule(
name = "gen_" + name,
outs = [out],
cmd = "(cat <<'HEREDOC'\n%s\nHEREDOC\n) > $@" % contents,
)
def _lua_binary_or_test(name, luamain, luadeps, rule):
script = name + ".sh"
make_shell_script(
name = "gen_" + name,
out = script,
contents = """
BASE=$(dirname $(rlocation upb/upb_c.so))
export LUA_CPATH="$BASE/?.so"
export LUA_PATH="$BASE/?.lua"
$(rlocation lua/lua) $(rlocation upb/tools/upbc.lua) "$@"
""",
)
rule(
name = name,
srcs = [script],
data = ["@lua//:lua", luamain] + luadeps,
)
def lua_binary(name, luamain, luadeps = []):
_lua_binary_or_test(name, luamain, luadeps, native.sh_binary)
def lua_test(name, luamain, luadeps = []):
_lua_binary_or_test(name, luamain, luadeps, native.sh_test)
def generated_file_staleness_test(name, outs, generated_pattern):
"""Tests that checked-in file(s) match the contents of generated file(s).

@ -146,8 +146,10 @@ GeneratedSrcsInfo = provider(
},
)
_WrappedCcInfo = provider(fields = ["cc_info"])
_UpbWrappedCcInfo = provider(fields = ["cc_info"])
_UpbDefsWrappedCcInfo = provider(fields = ["cc_info"])
_WrappedGeneratedSrcsInfo = provider(fields = ["srcs"])
_WrappedDefsGeneratedSrcsInfo = provider(fields = ["srcs"])
def _compile_upb_protos(ctx, proto_info, proto_sources, ext):
srcs = [_generate_output_file(ctx, name, ext + ".c") for name in proto_sources]
@ -175,11 +177,23 @@ def _upb_proto_rule_impl(ctx):
if len(ctx.attr.deps) != 1:
fail("only one deps dependency allowed.")
dep = ctx.attr.deps[0]
if _WrappedCcInfo not in dep or _WrappedGeneratedSrcsInfo not in dep:
fail("proto_library rule must generate _WrappedCcInfo and " +
"_WrappedGeneratedSrcsInfo (aspect should have handled this).")
cc_info = dep[_WrappedCcInfo].cc_info
srcs = dep[_WrappedGeneratedSrcsInfo].srcs
if _WrappedDefsGeneratedSrcsInfo in dep:
srcs = dep[_WrappedDefsGeneratedSrcsInfo].srcs
elif _WrappedGeneratedSrcsInfo in dep:
srcs = dep[_WrappedGeneratedSrcsInfo].srcs
else:
fail("proto_library rule must generate _WrappedGeneratedSrcsInfo or " +
"_WrappedDefsGeneratedSrcsInfo (aspect should have handled this).")
if _UpbDefsWrappedCcInfo in dep:
cc_info = dep[_UpbDefsWrappedCcInfo].cc_info
elif _UpbWrappedCcInfo in dep:
cc_info = dep[_UpbWrappedCcInfo].cc_info
else:
fail("proto_library rule must generate _UpbWrappedCcInfo or " +
"_UpbDefsWrappedCcInfo (aspect should have handled this).")
if type(cc_info.linking_context.libraries_to_link) == "list":
lib = cc_info.linking_context.libraries_to_link[0]
else:
@ -195,12 +209,19 @@ def _upb_proto_rule_impl(ctx):
cc_info,
]
def _upb_proto_aspect_impl(target, ctx):
def _upb_proto_aspect_impl(target, ctx, cc_provider, file_provider):
proto_info = target[ProtoInfo]
files = _compile_upb_protos(ctx, proto_info, proto_info.direct_sources, ctx.attr._ext)
deps = ctx.rule.attr.deps + ctx.attr._upb
if cc_provider == _UpbDefsWrappedCcInfo:
deps += ctx.attr._upb_reflection
dep_ccinfos = [dep[CcInfo] for dep in deps if CcInfo in dep]
dep_ccinfos += [dep[_WrappedCcInfo].cc_info for dep in deps if _WrappedCcInfo in dep]
dep_ccinfos += [dep[_UpbWrappedCcInfo].cc_info for dep in deps if _UpbWrappedCcInfo in dep]
dep_ccinfos += [dep[_UpbDefsWrappedCcInfo].cc_info for dep in deps if _UpbDefsWrappedCcInfo in dep]
if cc_provider == _UpbDefsWrappedCcInfo:
if _UpbWrappedCcInfo not in target:
fail("Target should have _UpbDefsWrappedCcInfo provider")
dep_ccinfos += [target[_UpbWrappedCcInfo].cc_info]
cc_info = _cc_library_func(
ctx = ctx,
name = ctx.rule.attr.name + ctx.attr._ext,
@ -208,7 +229,13 @@ def _upb_proto_aspect_impl(target, ctx):
srcs = files.srcs,
dep_ccinfos = dep_ccinfos,
)
return [_WrappedCcInfo(cc_info = cc_info), _WrappedGeneratedSrcsInfo(srcs = files)]
return [cc_provider(cc_info = cc_info), file_provider(srcs = files)]
def _upb_proto_library_aspect_impl(target, ctx):
return _upb_proto_aspect_impl(target, ctx, _UpbWrappedCcInfo, _WrappedGeneratedSrcsInfo)
def _upb_proto_reflection_library_aspect_impl(target, ctx):
return _upb_proto_aspect_impl(target, ctx, _UpbDefsWrappedCcInfo, _WrappedDefsGeneratedSrcsInfo)
def _maybe_add(d):
if not _is_bazel:
@ -242,7 +269,11 @@ _upb_proto_library_aspect = aspect(
]),
"_ext": attr.string(default = ".upb"),
}),
implementation = _upb_proto_aspect_impl,
implementation = _upb_proto_library_aspect_impl,
provides = [
_UpbWrappedCcInfo,
_WrappedGeneratedSrcsInfo,
],
attr_aspects = ["deps"],
fragments = ["cpp"],
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
@ -277,6 +308,7 @@ _upb_proto_reflection_library_aspect = aspect(
"_cc_toolchain": attr.label(
default = "@bazel_tools//tools/cpp:current_cc_toolchain",
),
# For unknown reasons, this gets overwritten.
"_upb": attr.label_list(
default = [
"//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
@ -284,9 +316,23 @@ _upb_proto_reflection_library_aspect = aspect(
"//:reflection",
],
),
"_upb_reflection": attr.label_list(
default = [
"//:upb",
"//:reflection",
],
),
"_ext": attr.string(default = ".upbdefs"),
}),
implementation = _upb_proto_aspect_impl,
implementation = _upb_proto_reflection_library_aspect_impl,
provides = [
_UpbDefsWrappedCcInfo,
_WrappedDefsGeneratedSrcsInfo,
],
required_aspect_providers = [
_UpbWrappedCcInfo,
_WrappedGeneratedSrcsInfo,
],
attr_aspects = ["deps"],
fragments = ["cpp"],
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
@ -297,7 +343,10 @@ upb_proto_reflection_library = rule(
implementation = _upb_proto_rule_impl,
attrs = {
"deps": attr.label_list(
aspects = [_upb_proto_reflection_library_aspect],
aspects = [
_upb_proto_library_aspect,
_upb_proto_reflection_library_aspect,
],
allow_rules = ["proto_library"],
providers = [ProtoInfo],
),

@ -9,7 +9,6 @@
#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_
#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_
#include "upb/generated_util.h"
#include "upb/msg.h"
#include "upb/decode.h"
#include "upb/encode.h"
@ -157,7 +156,7 @@ typedef enum {
/* google.protobuf.FileDescriptorSet */
UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_arena *arena) {
return (google_protobuf_FileDescriptorSet *)upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena);
return (google_protobuf_FileDescriptorSet *)_upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena);
}
UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -174,10 +173,10 @@ UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorS
return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) {
return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file(google_protobuf_FileDescriptorSet *msg, upb_arena *arena) {
struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)_upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -187,7 +186,7 @@ UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescr
/* google.protobuf.FileDescriptorProto */
UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_new(upb_arena *arena) {
return (google_protobuf_FileDescriptorProto *)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
return (google_protobuf_FileDescriptorProto *)_upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -228,20 +227,20 @@ UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(g
return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
}
UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_STRING, arena);
}
UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
arena);
}
UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto *msg, size_t *len) {
return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
}
UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -251,10 +250,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorP
return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
}
UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -264,10 +263,10 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescript
return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len);
}
UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)_upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -277,10 +276,10 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptor
return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len);
}
UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -293,7 +292,7 @@ UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_
UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_FileOptions* sub = (struct google_protobuf_FileOptions*)google_protobuf_FileDescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_FileOptions*)upb_msg_new(&google_protobuf_FileOptions_msginit, arena);
sub = (struct google_protobuf_FileOptions*)_upb_msg_new(&google_protobuf_FileOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_FileDescriptorProto_set_options(msg, sub);
}
@ -306,7 +305,7 @@ UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_
UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_SourceCodeInfo* sub = (struct google_protobuf_SourceCodeInfo*)google_protobuf_FileDescriptorProto_source_code_info(msg);
if (sub == NULL) {
sub = (struct google_protobuf_SourceCodeInfo*)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena);
sub = (struct google_protobuf_SourceCodeInfo*)_upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena);
if (!sub) return NULL;
google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub);
}
@ -316,21 +315,21 @@ UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependenc
return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len);
}
UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_TYPE_INT32, arena);
}
UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
arena);
}
UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) {
return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 120), len);
}
UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_TYPE_INT32, arena);
}
UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
arena);
}
UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
_upb_sethas(msg, 3);
@ -340,7 +339,7 @@ UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_F
/* google.protobuf.DescriptorProto */
UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new(upb_arena *arena) {
return (google_protobuf_DescriptorProto *)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
return (google_protobuf_DescriptorProto *)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -372,10 +371,10 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt
return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
}
UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -385,10 +384,10 @@ UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mut
return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
}
UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -398,10 +397,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto
return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
}
UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -411,10 +410,10 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_Desc
return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
}
UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -424,10 +423,10 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt
return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
}
UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -440,7 +439,7 @@ UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_Desc
UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProto_mutable_options(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_MessageOptions* sub = (struct google_protobuf_MessageOptions*)google_protobuf_DescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_MessageOptions*)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena);
sub = (struct google_protobuf_MessageOptions*)_upb_msg_new(&google_protobuf_MessageOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_DescriptorProto_set_options(msg, sub);
}
@ -450,10 +449,10 @@ UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProt
return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
}
UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)_upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -463,10 +462,10 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_Descr
return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
}
UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -476,17 +475,17 @@ UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(go
return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
}
UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_STRING, arena);
}
UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
arena);
}
/* google.protobuf.DescriptorProto.ExtensionRange */
UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena *arena) {
return (google_protobuf_DescriptorProto_ExtensionRange *)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
return (google_protobuf_DescriptorProto_ExtensionRange *)_upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
}
UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -519,7 +518,7 @@ UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(googl
UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_mutable_options(google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena) {
struct google_protobuf_ExtensionRangeOptions* sub = (struct google_protobuf_ExtensionRangeOptions*)google_protobuf_DescriptorProto_ExtensionRange_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_ExtensionRangeOptions*)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena);
sub = (struct google_protobuf_ExtensionRangeOptions*)_upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub);
}
@ -529,7 +528,7 @@ UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_Descrip
/* google.protobuf.DescriptorProto.ReservedRange */
UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_new(upb_arena *arena) {
return (google_protobuf_DescriptorProto_ReservedRange *)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
return (google_protobuf_DescriptorProto_ReservedRange *)_upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
}
UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -557,7 +556,7 @@ UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_pro
/* google.protobuf.ExtensionRangeOptions */
UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_new(upb_arena *arena) {
return (google_protobuf_ExtensionRangeOptions *)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena);
return (google_protobuf_ExtensionRangeOptions *)_upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena);
}
UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -574,10 +573,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeO
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -587,7 +586,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_Extension
/* google.protobuf.FieldDescriptorProto */
UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_new(upb_arena *arena) {
return (google_protobuf_FieldDescriptorProto *)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
return (google_protobuf_FieldDescriptorProto *)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -654,7 +653,7 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf
UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_FieldOptions*)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena);
sub = (struct google_protobuf_FieldOptions*)_upb_msg_new(&google_protobuf_FieldOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_FieldDescriptorProto_set_options(msg, sub);
}
@ -672,7 +671,7 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protob
/* google.protobuf.OneofDescriptorProto */
UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_new(upb_arena *arena) {
return (google_protobuf_OneofDescriptorProto *)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
return (google_protobuf_OneofDescriptorProto *)_upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -699,7 +698,7 @@ UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf
UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_mutable_options(google_protobuf_OneofDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_OneofOptions* sub = (struct google_protobuf_OneofOptions*)google_protobuf_OneofDescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_OneofOptions*)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena);
sub = (struct google_protobuf_OneofOptions*)_upb_msg_new(&google_protobuf_OneofOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_OneofDescriptorProto_set_options(msg, sub);
}
@ -709,7 +708,7 @@ UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorP
/* google.protobuf.EnumDescriptorProto */
UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_new(upb_arena *arena) {
return (google_protobuf_EnumDescriptorProto *)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
return (google_protobuf_EnumDescriptorProto *)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -736,10 +735,10 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescri
return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
}
UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)_upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -752,7 +751,7 @@ UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_
UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_mutable_options(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_EnumOptions* sub = (struct google_protobuf_EnumOptions*)google_protobuf_EnumDescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_EnumOptions*)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena);
sub = (struct google_protobuf_EnumOptions*)_upb_msg_new(&google_protobuf_EnumOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_EnumDescriptorProto_set_options(msg, sub);
}
@ -762,10 +761,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protob
return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
}
UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -775,17 +774,17 @@ UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_nam
return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
}
UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
}
UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
arena);
}
/* google.protobuf.EnumDescriptorProto.EnumReservedRange */
UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena *arena) {
return (google_protobuf_EnumDescriptorProto_EnumReservedRange *)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
return (google_protobuf_EnumDescriptorProto_EnumReservedRange *)_upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
}
UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -813,7 +812,7 @@ UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(go
/* google.protobuf.EnumValueDescriptorProto */
UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_new(upb_arena *arena) {
return (google_protobuf_EnumValueDescriptorProto *)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
return (google_protobuf_EnumValueDescriptorProto *)_upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -846,7 +845,7 @@ UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_prot
UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_mutable_options(google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_EnumValueOptions* sub = (struct google_protobuf_EnumValueOptions*)google_protobuf_EnumValueDescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_EnumValueOptions*)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena);
sub = (struct google_protobuf_EnumValueOptions*)_upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_EnumValueDescriptorProto_set_options(msg, sub);
}
@ -856,7 +855,7 @@ UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDes
/* google.protobuf.ServiceDescriptorProto */
UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_new(upb_arena *arena) {
return (google_protobuf_ServiceDescriptorProto *)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
return (google_protobuf_ServiceDescriptorProto *)_upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -881,10 +880,10 @@ UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescri
return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
}
UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) {
return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)_upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -897,7 +896,7 @@ UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protob
UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_mutable_options(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_ServiceOptions* sub = (struct google_protobuf_ServiceOptions*)google_protobuf_ServiceDescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_ServiceOptions*)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena);
sub = (struct google_protobuf_ServiceOptions*)_upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_ServiceDescriptorProto_set_options(msg, sub);
}
@ -907,7 +906,7 @@ UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescrip
/* google.protobuf.MethodDescriptorProto */
UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_new(upb_arena *arena) {
return (google_protobuf_MethodDescriptorProto *)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
return (google_protobuf_MethodDescriptorProto *)_upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
}
UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -950,7 +949,7 @@ UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobu
UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options(google_protobuf_MethodDescriptorProto *msg, upb_arena *arena) {
struct google_protobuf_MethodOptions* sub = (struct google_protobuf_MethodOptions*)google_protobuf_MethodDescriptorProto_options(msg);
if (sub == NULL) {
sub = (struct google_protobuf_MethodOptions*)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena);
sub = (struct google_protobuf_MethodOptions*)_upb_msg_new(&google_protobuf_MethodOptions_msginit, arena);
if (!sub) return NULL;
google_protobuf_MethodDescriptorProto_set_options(msg, sub);
}
@ -968,7 +967,7 @@ UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(googl
/* google.protobuf.FileOptions */
UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_arena *arena) {
return (google_protobuf_FileOptions *)upb_msg_new(&google_protobuf_FileOptions_msginit, arena);
return (google_protobuf_FileOptions *)_upb_msg_new(&google_protobuf_FileOptions_msginit, arena);
}
UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1105,10 +1104,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mut
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option(google_protobuf_FileOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1118,7 +1117,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptio
/* google.protobuf.MessageOptions */
UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(upb_arena *arena) {
return (google_protobuf_MessageOptions *)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena);
return (google_protobuf_MessageOptions *)_upb_msg_new(&google_protobuf_MessageOptions_msginit, arena);
}
UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1159,10 +1158,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1172,7 +1171,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOp
/* google.protobuf.FieldOptions */
UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_arena *arena) {
return (google_protobuf_FieldOptions *)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena);
return (google_protobuf_FieldOptions *)_upb_msg_new(&google_protobuf_FieldOptions_msginit, arena);
}
UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1225,10 +1224,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mu
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1238,7 +1237,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOpti
/* google.protobuf.OneofOptions */
UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) {
return (google_protobuf_OneofOptions *)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena);
return (google_protobuf_OneofOptions *)_upb_msg_new(&google_protobuf_OneofOptions_msginit, arena);
}
UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1255,10 +1254,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mu
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1268,7 +1267,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOpti
/* google.protobuf.EnumOptions */
UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_arena *arena) {
return (google_protobuf_EnumOptions *)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena);
return (google_protobuf_EnumOptions *)_upb_msg_new(&google_protobuf_EnumOptions_msginit, arena);
}
UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1297,10 +1296,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mut
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1310,7 +1309,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptio
/* google.protobuf.EnumValueOptions */
UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_new(upb_arena *arena) {
return (google_protobuf_EnumValueOptions *)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena);
return (google_protobuf_EnumValueOptions *)_upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena);
}
UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1333,10 +1332,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOption
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1346,7 +1345,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValue
/* google.protobuf.ServiceOptions */
UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(upb_arena *arena) {
return (google_protobuf_ServiceOptions *)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena);
return (google_protobuf_ServiceOptions *)_upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena);
}
UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1369,10 +1368,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1382,7 +1381,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOp
/* google.protobuf.MethodOptions */
UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_arena *arena) {
return (google_protobuf_MethodOptions *)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena);
return (google_protobuf_MethodOptions *)_upb_msg_new(&google_protobuf_MethodOptions_msginit, arena);
}
UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1411,10 +1410,10 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_m
return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len);
}
UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1424,7 +1423,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOpt
/* google.protobuf.UninterpretedOption */
UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_new(upb_arena *arena) {
return (google_protobuf_UninterpretedOption *)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
return (google_protobuf_UninterpretedOption *)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
}
UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1453,10 +1452,10 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_Uninte
return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len);
}
UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) {
return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name(google_protobuf_UninterpretedOption *msg, upb_arena *arena) {
struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)_upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1490,7 +1489,7 @@ UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_p
/* google.protobuf.UninterpretedOption.NamePart */
UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_new(upb_arena *arena) {
return (google_protobuf_UninterpretedOption_NamePart *)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
return (google_protobuf_UninterpretedOption_NamePart *)_upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
}
UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1518,7 +1517,7 @@ UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(go
/* google.protobuf.SourceCodeInfo */
UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(upb_arena *arena) {
return (google_protobuf_SourceCodeInfo *)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena);
return (google_protobuf_SourceCodeInfo *)_upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena);
}
UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1535,10 +1534,10 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeI
return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) {
return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location(google_protobuf_SourceCodeInfo *msg, upb_arena *arena) {
struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)_upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1548,7 +1547,7 @@ UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_Sourc
/* google.protobuf.SourceCodeInfo.Location */
UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_new(upb_arena *arena) {
return (google_protobuf_SourceCodeInfo_Location *)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
return (google_protobuf_SourceCodeInfo_Location *)_upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
}
UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1571,21 +1570,21 @@ UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_
return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
}
UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_INT32, arena);
}
UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
arena);
}
UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) {
return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
}
UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_INT32, arena);
}
UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
arena);
}
UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) {
_upb_sethas(msg, 1);
@ -1599,17 +1598,17 @@ UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_
return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
}
UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena);
}
UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
arena);
}
/* google.protobuf.GeneratedCodeInfo */
UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_new(upb_arena *arena) {
return (google_protobuf_GeneratedCodeInfo *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena);
return (google_protobuf_GeneratedCodeInfo *)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena);
}
UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1626,10 +1625,10 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_Genera
return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) {
return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
}
UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena) {
struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
bool ok = _upb_array_append_accessor(
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
if (!ok) return NULL;
@ -1639,7 +1638,7 @@ UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_
/* google.protobuf.GeneratedCodeInfo.Annotation */
UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena *arena) {
return (google_protobuf_GeneratedCodeInfo_Annotation *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
return (google_protobuf_GeneratedCodeInfo_Annotation *)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
}
UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse(const char *buf, size_t size,
upb_arena *arena) {
@ -1662,11 +1661,11 @@ UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(go
return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len);
}
UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) {
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_TYPE_INT32, arena);
}
UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t val, upb_arena *arena) {
return _upb_array_append_accessor(
msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
return _upb_array_append_accessor(msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
arena);
}
UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) {
_upb_sethas(msg, 3);

@ -391,7 +391,7 @@ static upb_selector_t getsel_for_handlertype(upb_json_parser *p,
upb_handlertype_t type) {
upb_selector_t sel;
bool ok = upb_handlers_getselector(p->top->f, type, &sel);
UPB_ASSERT(ok);
UPB_ASSUME(ok);
return sel;
}
@ -416,7 +416,7 @@ static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) {
const upb_json_parsermethod *method;
ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v);
UPB_ASSERT(ok);
UPB_ASSUME(ok);
method = upb_value_getconstptr(v);
frame->name_table = &method->name_table;
@ -2021,7 +2021,7 @@ static void end_member(upb_json_parser *p) {
/* send ENDSUBMSG in repeated-field-of-mapentries frame. */
p->top--;
ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel);
UPB_ASSERT(ok);
UPB_ASSUME(ok);
upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel);
}

@ -1,165 +0,0 @@
/*
*
* A test that verifies that our results are identical to proto2 for a
* given proto type and input protobuf.
*/
#define __STDC_LIMIT_MACROS // So we get UINT32_MAX
#include <assert.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/wire_format_lite.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "tests/google_messages.pb.h"
#include "tests/upb_test.h"
#include "upb/bindings/googlepb/bridge.h"
#include "upb/def.h"
#include "upb/handlers.h"
#include "upb/pb/decoder.h"
#include "upb/pb/glue.h"
#include "upb/pb/varint.int.h"
// Pull in string data from tests/google_message{1,2}.dat
// (the .h files are generated with xxd).
const unsigned char message1_data[] = {
#include "tests/google_message1.h"
};
const unsigned char message2_data[] = {
#include "tests/google_message2.h"
};
void compare_metadata(const google::protobuf::Descriptor* d,
const upb::MessageDef *upb_md) {
ASSERT(d->field_count() == upb_md->field_count());
for (upb::MessageDef::const_field_iterator i = upb_md->field_begin();
i != upb_md->field_end(); ++i) {
const upb::FieldDef* upb_f = *i;
const google::protobuf::FieldDescriptor *proto2_f =
d->FindFieldByNumber(upb_f->number());
ASSERT(upb_f);
ASSERT(proto2_f);
ASSERT(upb_f->number() == (uint32_t)proto2_f->number());
ASSERT(std::string(upb_f->name()) == proto2_f->name());
ASSERT(upb_f->descriptor_type() ==
static_cast<upb::FieldDef::DescriptorType>(proto2_f->type()));
ASSERT(upb_f->IsSequence() == proto2_f->is_repeated());
}
}
void print_diff(const google::protobuf::Message& msg1,
const google::protobuf::Message& msg2) {
std::string text_str1;
std::string text_str2;
google::protobuf::TextFormat::PrintToString(msg1, &text_str1);
google::protobuf::TextFormat::PrintToString(msg2, &text_str2);
fprintf(stderr, "str1: %s, str2: %s\n", text_str1.c_str(), text_str2.c_str());
}
void parse_and_compare(google::protobuf::Message *msg1,
google::protobuf::Message *msg2,
const upb::Handlers *protomsg_handlers,
const char *str, size_t len, bool allow_jit) {
// Parse to both proto2 and upb.
ASSERT(msg1->ParseFromArray(str, len));
upb::pb::CodeCache cache;
ASSERT(cache.set_allow_jit(allow_jit));
upb::reffed_ptr<const upb::pb::DecoderMethod> decoder_method(
cache.GetDecoderMethod(upb::pb::DecoderMethodOptions(protomsg_handlers)));
upb::Status status;
upb::Environment env;
env.ReportErrorsTo(&status);
upb::Sink protomsg_sink(protomsg_handlers, msg2);
upb::pb::Decoder* decoder =
upb::pb::Decoder::Create(&env, decoder_method.get(), &protomsg_sink);
msg2->Clear();
bool ok = upb::BufferSource::PutBuffer(str, len, decoder->input());
if (!ok) {
fprintf(stderr, "error parsing: %s\n", status.error_message());
print_diff(*msg1, *msg2);
}
ASSERT(ok);
ASSERT(status.ok());
// Would like to just compare the message objects themselves, but
// unfortunately MessageDifferencer is not part of the open-source release of
// proto2, so we compare their serialized strings, which we expect will be
// equivalent.
std::string str1;
std::string str2;
msg1->SerializeToString(&str1);
msg2->SerializeToString(&str2);
if (str1 != str2) {
print_diff(*msg1, *msg2);
}
ASSERT(str1 == str2);
ASSERT(std::string(str, len) == str2);
}
void test_zig_zag() {
for (uint64_t num = 5; num * 1.5 < UINT64_MAX; num *= 1.5) {
ASSERT(upb_zzenc_64(num) ==
google::protobuf::internal::WireFormatLite::ZigZagEncode64(num));
if (num < UINT32_MAX) {
ASSERT(upb_zzenc_32(num) ==
google::protobuf::internal::WireFormatLite::ZigZagEncode32(num));
}
}
}
extern "C" {
int run_tests(int argc, char *argv[]) {
UPB_UNUSED(argc);
UPB_UNUSED(argv);
UPB_UNUSED(message1_data);
UPB_UNUSED(message2_data);
size_t len = sizeof(MESSAGE_DATA_IDENT);
const char *str = (const char*)MESSAGE_DATA_IDENT;
MESSAGE_CIDENT msg1;
MESSAGE_CIDENT msg2;
upb::reffed_ptr<const upb::Handlers> h(
upb::googlepb::WriteHandlers::New(msg1));
compare_metadata(msg1.GetDescriptor(), h->message_def());
// Run twice to test proper object reuse.
parse_and_compare(&msg1, &msg2, h.get(), str, len, false);
parse_and_compare(&msg1, &msg2, h.get(), str, len, true);
parse_and_compare(&msg1, &msg2, h.get(), str, len, false);
parse_and_compare(&msg1, &msg2, h.get(), str, len, true);
// Test with DynamicMessage.
google::protobuf::DynamicMessageFactory* factory =
new google::protobuf::DynamicMessageFactory;
const google::protobuf::Message* prototype =
factory->GetPrototype(msg1.descriptor());
google::protobuf::Message* dyn_msg1 = prototype->New();
google::protobuf::Message* dyn_msg2 = prototype->New();
h = upb::googlepb::WriteHandlers::New(*dyn_msg1);
parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, false);
parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, true);
delete dyn_msg1;
delete dyn_msg2;
delete factory;
test_zig_zag();
printf("All tests passed, %d assertions.\n", num_assertions);
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
}

@ -0,0 +1,56 @@
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include <signal.h>
#include "upb/bindings/lua/upb.h"
lua_State *L;
static void interrupt(lua_State *L, lua_Debug *ar) {
(void)ar;
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "SIGINT");
}
static void sighandler(int i) {
fprintf(stderr, "Signal!\n");
signal(i, SIG_DFL);
lua_sethook(L, interrupt, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
const char *init =
"package.preload['lupb'] = ... "
"package.path = '"
"./?.lua;"
"./third_party/lunit/?.lua;"
"external/com_google_protobuf/?.lua;"
"external/com_google_protobuf/src/?.lua;"
"bazel-bin/external/com_google_protobuf/src/?.lua;"
"bazel-bin/external/com_google_protobuf/?.lua;"
"upb/bindings/lua/?.lua"
"'";
int main() {
int ret = 0;
L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L, luaopen_lupb);
ret = luaL_loadstring(L, init);
lua_pushcfunction(L, luaopen_lupb);
signal(SIGINT, sighandler);
ret = ret ||
lua_pcall(L, 1, LUA_MULTRET, 0) ||
luaL_dofile(L, "tests/bindings/lua/test_upb.lua");
signal(SIGINT, SIG_DFL);
if (ret) {
fprintf(stderr, "error testing Lua: %s\n", lua_tostring(L, -1));
ret = 1;
}
lua_close(L);
return ret;
}

File diff suppressed because it is too large Load Diff

@ -1,80 +0,0 @@
-- Require "pb" first to ensure that the transitive require of "upb" is
-- handled properly by the "pb" module.
local pb = require "upb.pb"
local upb = require "upb"
local lunit = require "lunit"
if _VERSION >= 'Lua 5.2' then
_ENV = lunit.module("testupb_pb", "seeall")
else
module("testupb_pb", lunit.testcase, package.seeall)
end
local symtab = upb.SymbolTable{
upb.MessageDef{full_name = "TestMessage", fields = {
upb.FieldDef{name = "i32", number = 1, type = upb.TYPE_INT32},
upb.FieldDef{name = "u32", number = 2, type = upb.TYPE_UINT32},
upb.FieldDef{name = "i64", number = 3, type = upb.TYPE_INT64},
upb.FieldDef{name = "u64", number = 4, type = upb.TYPE_UINT64},
upb.FieldDef{name = "dbl", number = 5, type = upb.TYPE_DOUBLE},
upb.FieldDef{name = "flt", number = 6, type = upb.TYPE_FLOAT},
upb.FieldDef{name = "bool", number = 7, type = upb.TYPE_BOOL},
}
}
}
local factory = upb.MessageFactory(symtab);
local TestMessage = factory:get_message_class("TestMessage")
function test_parse_primitive()
local binary_pb =
"\008\128\128\128\128\002\016\128\128\128\128\004\024\128\128"
.. "\128\128\128\128\128\002\032\128\128\128\128\128\128\128\001\041\000"
.. "\000\000\000\000\000\248\063\053\000\000\096\064\056\001"
local msg = TestMessage()
pb.decode(msg, binary_pb)
assert_equal(536870912, msg.i32)
assert_equal(1073741824, msg.u32)
assert_equal(1125899906842624, msg.i64)
assert_equal(562949953421312, msg.u64)
assert_equal(1.5, msg.dbl)
assert_equal(3.5, msg.flt)
assert_equal(true, msg.bool)
local encoded = pb.encode(msg)
local msg2 = TestMessage()
pb.decode(msg2, encoded)
assert_equal(536870912, msg.i32)
assert_equal(1073741824, msg.u32)
assert_equal(1125899906842624, msg.i64)
assert_equal(562949953421312, msg.u64)
assert_equal(1.5, msg.dbl)
assert_equal(3.5, msg.flt)
assert_equal(true, msg.bool)
end
function test_parse_string()
local symtab = upb.SymbolTable{
upb.MessageDef{full_name = "TestMessage", fields = {
upb.FieldDef{name = "str", number = 1, type = upb.TYPE_STRING},
}
}
}
local factory = upb.MessageFactory(symtab);
local TestMessage = factory:get_message_class("TestMessage")
local binary_pb = "\010\005Hello"
msg = TestMessage()
pb.decode(msg, binary_pb)
-- TODO(haberman): re-enable when this stuff works better.
-- assert_equal("Hello", msg.str)
end
local stats = lunit.main()
if stats.failed > 0 or stats.errors > 0 then
error("One or more errors in test suite")
end

@ -1,62 +0,0 @@
#!/usr/bin/ruby
#
# Tests for Ruby upb extension.
require 'test/unit'
require 'set'
require 'upb'
def get_descriptor
File.open("upb/descriptor/descriptor.pb").read
end
def load_descriptor
symtab = Upb::SymbolTable.new
symtab.load_descriptor(get_descriptor())
return symtab
end
def get_message_class(name)
return Upb.get_message_class(load_descriptor().lookup(name))
end
class TestRubyExtension < Test::Unit::TestCase
def test_parsedescriptor
msgdef = load_descriptor.lookup("google.protobuf.FileDescriptorSet")
assert_instance_of(Upb::MessageDef, msgdef)
file_descriptor_set = Upb.get_message_class(msgdef)
msg = file_descriptor_set.parse(get_descriptor())
# A couple message types we know should exist.
names = Set.new(["DescriptorProto", "FieldDescriptorProto"])
msg.file.each { |file|
file.message_type.each { |message_type|
names.delete(message_type.name)
}
}
assert_equal(0, names.size)
end
def test_parseserialize
field_descriptor_proto = get_message_class("google.protobuf.FieldDescriptorProto")
field_options = get_message_class("google.protobuf.FieldOptions")
field = field_descriptor_proto.new
field.name = "MyName"
field.number = 5
field.options = field_options.new
field.options.packed = true
serialized = Upb::Message.serialize(field)
field2 = field_descriptor_proto.parse(serialized)
assert_equal("MyName", field2.name)
assert_equal(5, field2.number)
assert_equal(true, field2.options.packed)
end
end

@ -9,9 +9,16 @@
#include <unistd.h>
#include "conformance/conformance.upb.h"
#include "src/google/protobuf/test_messages_proto3.upb.h"
#include "conformance/conformance.upbdefs.h"
#include "src/google/protobuf/test_messages_proto2.upbdefs.h"
#include "src/google/protobuf/test_messages_proto3.upbdefs.h"
#include "upb/decode.h"
#include "upb/encode.h"
#include "upb/reflection.h"
#include "upb/textencode.h"
int test_count = 0;
bool verbose = false; /* Set to true to get req/resp printed on stderr. */
bool CheckedRead(int fd, void *buf, size_t len) {
size_t ofs = 0;
@ -39,138 +46,178 @@ void CheckedWrite(int fd, const void *buf, size_t len) {
}
}
bool strview_eql(upb_strview view, const char *str) {
return view.size == strlen(str) && memcmp(view.data, str, view.size) == 0;
typedef struct {
const conformance_ConformanceRequest *request;
conformance_ConformanceResponse *response;
upb_arena *arena;
const upb_symtab *symtab;
} ctx;
bool parse_proto(upb_msg *msg, const upb_msgdef *m, const ctx* c) {
upb_strview proto =
conformance_ConformanceRequest_protobuf_payload(c->request);
if (upb_decode(proto.data, proto.size, msg, upb_msgdef_layout(m), c->arena)) {
return true;
} else {
static const char msg[] = "Parse error";
conformance_ConformanceResponse_set_parse_error(
c->response, upb_strview_make(msg, strlen(msg)));
return false;
}
}
static const char *proto3_msg =
"protobuf_test_messages.proto3.TestAllTypesProto3";
void DoTest(
const conformance_ConformanceRequest* request,
conformance_ConformanceResponse *response,
upb_arena *arena) {
protobuf_test_messages_proto3_TestAllTypesProto3 *test_message;
if (!strview_eql(conformance_ConformanceRequest_message_type(request),
proto3_msg)) {
static const char msg[] = "Only proto3 for now.";
conformance_ConformanceResponse_set_skipped(
response, upb_strview_make(msg, sizeof(msg)));
return;
void serialize_proto(const upb_msg *msg, const upb_msgdef *m, const ctx *c) {
size_t len;
char *data = upb_encode(msg, upb_msgdef_layout(m), c->arena, &len);
if (data) {
conformance_ConformanceResponse_set_protobuf_payload(
c->response, upb_strview_make(data, len));
} else {
static const char msg[] = "Error serializing.";
conformance_ConformanceResponse_set_serialize_error(
c->response, upb_strview_make(msg, strlen(msg)));
}
}
switch (conformance_ConformanceRequest_payload_case(request)) {
case conformance_ConformanceRequest_payload_protobuf_payload: {
upb_strview payload = conformance_ConformanceRequest_protobuf_payload(request);
test_message = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
payload.data, payload.size, arena);
if (!test_message) {
static const char msg[] = "Parse error";
conformance_ConformanceResponse_set_parse_error(
response, upb_strview_make(msg, sizeof(msg)));
return;
}
break;
}
void serialize_text(const upb_msg *msg, const upb_msgdef *m, const ctx *c) {
size_t len;
size_t len2;
int opts = 0;
char *data;
if (!conformance_ConformanceRequest_print_unknown_fields(c->request)) {
opts |= UPB_TXTENC_SKIPUNKNOWN;
}
len = upb_textencode(msg, m, c->symtab, opts, NULL, 0);
data = upb_arena_malloc(c->arena, len + 1);
len2 = upb_textencode(msg, m, c->symtab, opts, data, len + 1);
assert(len == len2);
conformance_ConformanceResponse_set_text_payload(
c->response, upb_strview_make(data, len));
}
bool parse_input(upb_msg *msg, const upb_msgdef *m, const ctx* c) {
switch (conformance_ConformanceRequest_payload_case(c->request)) {
case conformance_ConformanceRequest_payload_protobuf_payload:
return parse_proto(msg, m, c);
case conformance_ConformanceRequest_payload_NOT_SET:
fprintf(stderr, "conformance_upb: Request didn't have payload.\n");
return;
return false;
default: {
static const char msg[] = "Unsupported input format.";
conformance_ConformanceResponse_set_skipped(
response, upb_strview_make(msg, sizeof(msg)));
return;
c->response, upb_strview_make(msg, strlen(msg)));
return false;
}
}
}
switch (conformance_ConformanceRequest_requested_output_format(request)) {
void write_output(const upb_msg *msg, const upb_msgdef *m, const ctx* c) {
switch (conformance_ConformanceRequest_requested_output_format(c->request)) {
case conformance_UNSPECIFIED:
fprintf(stderr, "conformance_upb: Unspecified output format.\n");
exit(1);
case conformance_PROTOBUF: {
size_t serialized_len;
char *serialized =
protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
test_message, arena, &serialized_len);
if (!serialized) {
static const char msg[] = "Error serializing.";
conformance_ConformanceResponse_set_serialize_error(
response, upb_strview_make(msg, sizeof(msg)));
return;
}
conformance_ConformanceResponse_set_protobuf_payload(
response, upb_strview_make(serialized, serialized_len));
case conformance_PROTOBUF:
serialize_proto(msg, m, c);
break;
case conformance_TEXT_FORMAT:
serialize_text(msg, m, c);
break;
}
default: {
static const char msg[] = "Unsupported output format.";
conformance_ConformanceResponse_set_skipped(
response, upb_strview_make(msg, sizeof(msg)));
return;
c->response, upb_strview_make(msg, strlen(msg)));
break;
}
}
}
void DoTest(const ctx* c) {
upb_msg *msg;
upb_strview name = conformance_ConformanceRequest_message_type(c->request);
const upb_msgdef *m = upb_symtab_lookupmsg2(c->symtab, name.data, name.size);
if (!m) {
static const char msg[] = "Unknown message type.";
conformance_ConformanceResponse_set_skipped(
c->response, upb_strview_make(msg, strlen(msg)));
return;
}
msg = upb_msg_new(m, c->arena);
return;
if (parse_input(msg, m, c)) {
write_output(msg, m, c);
}
}
bool DoTestIo(void) {
upb_arena *arena;
upb_alloc *alloc;
void debug_print(const char *label, const upb_msg *msg, const upb_msgdef *m,
const ctx *c) {
char buf[512];
upb_textencode(msg, m, c->symtab, UPB_TXTENC_SINGLELINE, buf, sizeof(buf));
fprintf(stderr, "%s: %s\n", label, buf);
}
bool DoTestIo(upb_symtab *symtab) {
upb_status status;
char *serialized_input;
char *serialized_output;
char *input;
char *output;
uint32_t input_size;
size_t output_size;
conformance_ConformanceRequest *request;
conformance_ConformanceResponse *response;
ctx c;
if (!CheckedRead(STDIN_FILENO, &input_size, sizeof(uint32_t))) {
/* EOF. */
return false;
}
arena = upb_arena_new();
alloc = upb_arena_alloc(arena);
serialized_input = upb_malloc(alloc, input_size);
c.symtab = symtab;
c.arena = upb_arena_new();
input = upb_arena_malloc(c.arena, input_size);
if (!CheckedRead(STDIN_FILENO, serialized_input, input_size)) {
if (!CheckedRead(STDIN_FILENO, input, input_size)) {
fprintf(stderr, "conformance_upb: unexpected EOF on stdin.\n");
exit(1);
}
request =
conformance_ConformanceRequest_parse(serialized_input, input_size, arena);
response = conformance_ConformanceResponse_new(arena);
c.request = conformance_ConformanceRequest_parse(input, input_size, c.arena);
c.response = conformance_ConformanceResponse_new(c.arena);
if (request) {
DoTest(request, response, arena);
if (c.request) {
DoTest(&c);
} else {
fprintf(stderr, "conformance_upb: parse of ConformanceRequest failed: %s\n",
upb_status_errmsg(&status));
}
serialized_output = conformance_ConformanceResponse_serialize(
response, arena, &output_size);
output = conformance_ConformanceResponse_serialize(c.response, c.arena,
&output_size);
CheckedWrite(STDOUT_FILENO, &output_size, sizeof(uint32_t));
CheckedWrite(STDOUT_FILENO, serialized_output, output_size);
CheckedWrite(STDOUT_FILENO, output, output_size);
test_count++;
upb_arena_free(arena);
if (verbose) {
debug_print("Request", c.request,
conformance_ConformanceRequest_getmsgdef(symtab), &c);
debug_print("Response", c.response,
conformance_ConformanceResponse_getmsgdef(symtab), &c);
fprintf(stderr, "\n");
}
upb_arena_free(c.arena);
return true;
}
int main(void) {
upb_symtab *symtab = upb_symtab_new();
protobuf_test_messages_proto2_TestAllTypesProto2_getmsgdef(symtab);
protobuf_test_messages_proto3_TestAllTypesProto3_getmsgdef(symtab);
while (1) {
if (!DoTestIo()) {
if (!DoTestIo(symtab)) {
fprintf(stderr, "conformance_upb: received EOF from test runner "
"after %d tests, exiting\n", test_count);
return 0;

Binary file not shown.

Binary file not shown.

@ -1,149 +0,0 @@
package benchmarks;
option optimize_for = SPEED;
enum Foo {
FOO_VALUE = 1;
FOO_VALUE2 = 2;
}
message Simple {
message M2 {
optional int32 f1 = 1234567;
}
optional M2 m2 = 1;
}
message SpeedMessage1 {
required string field1 = 1;
optional string field9 = 9;
optional string field18 = 18;
optional bool field80 = 80 [default=false];
optional bool field81 = 81 [default=true];
required int32 field2 = 2;
required int32 field3 = 3;
optional int32 field280 = 280;
optional int32 field6 = 6 [default=0];
optional int64 field22 = 22;
optional string field4 = 4;
repeated fixed64 field5 = 5;
optional bool field59 = 59 [default=false];
optional string field7 = 7;
optional int32 field16 = 16;
optional int32 field130 = 130 [default=0];
optional bool field12 = 12 [default=true];
optional bool field17 = 17 [default=true];
optional bool field13 = 13 [default=true];
optional bool field14 = 14 [default=true];
optional int32 field104 = 104 [default=0];
optional int32 field100 = 100 [default=0];
optional int32 field101 = 101 [default=0];
optional string field102 = 102;
optional string field103 = 103;
optional int32 field29 = 29 [default=0];
optional bool field30 = 30 [default=false];
optional int32 field60 = 60 [default=-1];
optional int32 field271 = 271 [default=-1];
optional int32 field272 = 272 [default=-1];
optional int32 field150 = 150;
optional int32 field23 = 23 [default=0];
optional bool field24 = 24 [default=false];
optional int32 field25 = 25 [default=0];
optional SpeedMessage1SubMessage field15 = 15;
optional bool field78 = 78;
optional int32 field67 = 67 [default=0];
optional int32 field68 = 68;
optional int32 field128 = 128 [default=0];
optional string field129 = 129 [default="xxxxxxxxxxxxxxxxxxxxx"];
optional int32 field131 = 131 [default=0];
optional Foo field132 = 132 [default=FOO_VALUE];
}
message SpeedMessage1SubMessage {
optional int32 field1 = 1 [default=0];
optional int32 field2 = 2 [default=0];
optional int32 field3 = 3 [default=0];
optional string field15 = 15 [default="FOOBAR!"];
optional bool field12 = 12 [default=true];
optional int64 field13 = 13;
optional int64 field14 = 14;
optional int32 field16 = 16;
optional int32 field19 = 19 [default=2];
optional bool field20 = 20 [default=true];
optional bool field28 = 28 [default=true];
optional fixed64 field21 = 21;
optional int32 field22 = 22;
optional bool field23 = 23 [ default=false ];
optional bool field206 = 206 [default=false];
optional fixed32 field203 = 203;
optional int32 field204 = 204;
optional string field205 = 205;
optional uint64 field207 = 207;
optional uint64 field300 = 300;
}
message SpeedMessage2 {
optional string field1 = 1;
optional int64 field3 = 3;
optional int64 field4 = 4;
optional int64 field30 = 30;
optional bool field75 = 75 [default=false];
optional string field6 = 6;
optional bytes field2 = 2;
optional int32 field21 = 21 [default=0];
optional int32 field71 = 71;
optional float field25 = 25;
optional int32 field109 = 109 [default=0];
optional int32 field210 = 210 [default=0];
optional int32 field211 = 211 [default=0];
optional int32 field212 = 212 [default=0];
optional int32 field213 = 213 [default=0];
optional int32 field216 = 216 [default=0];
optional int32 field217 = 217 [default=0];
optional int32 field218 = 218 [default=0];
optional int32 field220 = 220 [default=0];
optional int32 field221 = 221 [default=0];
optional float field222 = 222 [default=0.0];
optional int32 field63 = 63;
repeated group Group1 = 10 {
required float field11 = 11;
optional float field26 = 26;
optional string field12 = 12;
optional string field13 = 13;
repeated string field14 = 14;
required uint64 field15 = 15;
optional int32 field5 = 5;
optional string field27 = 27;
optional int32 field28 = 28;
optional string field29 = 29;
optional string field16 = 16;
repeated string field22 = 22;
repeated int32 field73 = 73;
optional int32 field20 = 20 [default=0];
optional string field24 = 24;
optional SpeedMessage2GroupedMessage field31 = 31;
}
repeated string field128 = 128;
optional int64 field131 = 131;
repeated string field127 = 127;
optional int32 field129 = 129;
repeated int64 field130 = 130;
optional bool field205 = 205 [default=false];
optional bool field206 = 206 [default=false];
}
message SpeedMessage2GroupedMessage {
optional float field1 = 1;
optional float field2 = 2;
optional float field3 = 3 [default=0.0];
optional bool field4 = 4;
optional bool field5 = 5;
optional bool field6 = 6 [default=true];
optional bool field7 = 7 [default=false];
optional float field8 = 8;
optional bool field9 = 9;
optional float field10 = 10;
optional int64 field11 = 11;
}

@ -53,6 +53,13 @@ static void test_varint_for_num(upb_decoderet (*decoder)(const char*),
ASSERT(upb_zzenc_64(upb_zzdec_64(num)) == num);
}
/* Making up for the lack of 64-bit constants in C89. */
static uint64_t make_u64(uint32_t high, uint32_t low) {
uint64_t ret = high;
ret = (ret << 32) | low;
return ret;
}
static void test_varint_decoder(upb_decoderet (*decoder)(const char*)) {
#define TEST(bytes, expected_val) {\
size_t n = sizeof(bytes) - 1; /* for NULL */ \
@ -74,18 +81,20 @@ static void test_varint_decoder(upb_decoderet (*decoder)(const char*)) {
upb_decoderet r = decoder(twelvebyte_buf);
ASSERT(r.p == NULL);
TEST("\x00", 0ULL);
TEST("\x01", 1ULL);
TEST("\x81\x14", 0xa01ULL);
TEST("\x81\x03", 0x181ULL);
TEST("\x81\x83\x07", 0x1c181ULL);
TEST("\x81\x83\x87\x0f", 0x1e1c181ULL);
TEST("\x81\x83\x87\x8f\x1f", 0x1f1e1c181ULL);
TEST("\x81\x83\x87\x8f\x9f\x3f", 0x1f9f1e1c181ULL);
TEST("\x81\x83\x87\x8f\x9f\xbf\x7f", 0x1fdf9f1e1c181ULL);
TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x01", 0x3fdf9f1e1c181ULL);
TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x03", 0x303fdf9f1e1c181ULL);
TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x83\x07", 0x8303fdf9f1e1c181ULL);
TEST("\x00", 0UL);
TEST("\x01", 1UL);
TEST("\x81\x14", 0xa01UL);
TEST("\x81\x03", 0x181UL);
TEST("\x81\x83\x07", 0x1c181UL);
TEST("\x81\x83\x87\x0f", 0x1e1c181UL);
TEST("\x81\x83\x87\x8f\x1f", make_u64(0x1, 0xf1e1c181UL));
TEST("\x81\x83\x87\x8f\x9f\x3f", make_u64(0x1f9, 0xf1e1c181UL));
TEST("\x81\x83\x87\x8f\x9f\xbf\x7f", make_u64(0x1fdf9, 0xf1e1c181UL));
TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x01", make_u64(0x3fdf9, 0xf1e1c181UL));
TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x03",
make_u64(0x303fdf9, 0xf1e1c181UL));
TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x83\x07",
make_u64(0x8303fdf9, 0xf1e1c181UL));
#undef TEST
for (num = 5; num * 1.5 < UINT64_MAX; num *= 1.5) {

Binary file not shown.

@ -0,0 +1,329 @@
/* Test of generated code, with a special focus on features that are not used in
* descriptor.proto or conformance.proto (since these get some testing from
* upb/def.c and tests/conformance_upb.c, respectively).
*/
#include "src/google/protobuf/test_messages_proto3.upb.h"
#include "tests/upb_test.h"
const char test_str[] = "abcdefg";
const char test_str2[] = "12345678910";
const char test_str3[] = "rstlnezxcvbnm";
const char test_str4[] = "just another test string";
const upb_strview test_str_view = {test_str, sizeof(test_str) - 1};
const upb_strview test_str_view2 = {test_str2, sizeof(test_str2) - 1};
const upb_strview test_str_view3 = {test_str3, sizeof(test_str3) - 1};
const upb_strview test_str_view4 = {test_str4, sizeof(test_str4) - 1};
const int32_t test_int32 = 10;
const int32_t test_int32_2 = -20;
const int32_t test_int32_3 = 30;
const int32_t test_int32_4 = -40;
static void test_scalars() {
upb_arena *arena = upb_arena_new();
protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
protobuf_test_messages_proto3_TestAllTypesProto3 *msg2;
upb_strview serialized;
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int32(msg, 10);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int64(msg, 20);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_uint32(msg, 30);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_uint64(msg, 40);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_float(msg, 50.5);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_double(msg, 60.6);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_bool(msg, 1);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_string(
msg, test_str_view);
serialized.data = protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
msg, arena, &serialized.size);
msg2 = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
serialized.data, serialized.size, arena);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_int32(
msg2) == 10);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(
msg2) == 20);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint32(
msg2) == 30);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(
msg2) == 40);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_float(
msg2) == 50.5);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_double(
msg2) == 60.6);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_bool(
msg2) == 1);
ASSERT(upb_strview_eql(
protobuf_test_messages_proto3_TestAllTypesProto3_optional_string(msg2),
test_str_view));
upb_arena_free(arena);
}
static void check_string_map_empty(
protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
size_t iter;
ASSERT(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_size(
msg) == 0);
ASSERT(
!protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter));
}
static void check_string_map_one_entry(
protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry
*const_ent;
size_t iter;
upb_strview str;
ASSERT(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_size(
msg) == 1);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_get(
msg, test_str_view, &str));
ASSERT(upb_strview_eql(str, test_str_view2));
ASSERT(
!protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_get(
msg, test_str_view3, &str));
/* Test that iteration reveals a single k/v pair in the map. */
iter = UPB_MAP_BEGIN;
const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter);
ASSERT(const_ent);
ASSERT(upb_strview_eql(
test_str_view,
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
const_ent)));
ASSERT(upb_strview_eql(
test_str_view2,
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
const_ent)));
const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter);
ASSERT(!const_ent);
}
static void test_string_map() {
upb_arena *arena = upb_arena_new();
protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry
*const_ent;
size_t iter, count;
check_string_map_empty(msg);
/* Set map[test_str_view] = test_str_view2 */
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
msg, test_str_view, test_str_view2, arena);
check_string_map_one_entry(msg);
/* Deleting a non-existent key does nothing. */
ASSERT(
!protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_delete(
msg, test_str_view3));
check_string_map_one_entry(msg);
/* Deleting the key sets the map back to empty. */
ASSERT(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_delete(
msg, test_str_view));
check_string_map_empty(msg);
/* Set two keys this time:
* map[test_str_view] = test_str_view2
* map[test_str_view3] = test_str_view4
*/
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
msg, test_str_view, test_str_view2, arena);
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
msg, test_str_view3, test_str_view4, arena);
/* Test iteration */
iter = UPB_MAP_BEGIN;
count = 0;
while (
(const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter)) != NULL) {
upb_strview key =
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
const_ent);
upb_strview val =
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
const_ent);
count++;
if (upb_strview_eql(key, test_str_view)) {
ASSERT(upb_strview_eql(val, test_str_view2));
} else {
ASSERT(upb_strview_eql(key, test_str_view3));
ASSERT(upb_strview_eql(val, test_str_view4));
}
}
ASSERT(count == 2);
/* Clearing the map goes back to empty. */
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_clear(msg);
check_string_map_empty(msg);
upb_arena_free(arena);
}
static void check_int32_map_empty(
protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
size_t iter;
ASSERT(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_size(
msg) == 0);
ASSERT(
!protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter));
}
static void check_int32_map_one_entry(
protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry
*const_ent;
size_t iter;
int32_t val;
ASSERT(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_size(
msg) == 1);
ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_get(
msg, test_int32, &val));
ASSERT(val == test_int32_2);
ASSERT(
!protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_get(
msg, test_int32_3, &val));
/* Test that iteration reveals a single k/v pair in the map. */
iter = UPB_MAP_BEGIN;
const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter);
ASSERT(const_ent);
ASSERT(
test_int32 ==
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
const_ent));
ASSERT(
test_int32_2 ==
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
const_ent));
const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter);
ASSERT(!const_ent);
}
static void test_int32_map() {
upb_arena *arena = upb_arena_new();
protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry
*const_ent;
size_t iter, count;
check_int32_map_empty(msg);
/* Set map[test_int32] = test_int32_2 */
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
msg, test_int32, test_int32_2, arena);
check_int32_map_one_entry(msg);
/* Deleting a non-existent key does nothing. */
ASSERT(
!protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_delete(
msg, test_int32_3));
check_int32_map_one_entry(msg);
/* Deleting the key sets the map back to empty. */
ASSERT(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_delete(
msg, test_int32));
check_int32_map_empty(msg);
/* Set two keys this time:
* map[test_int32] = test_int32_2
* map[test_int32_3] = test_int32_4
*/
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
msg, test_int32, test_int32_2, arena);
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
msg, test_int32_3, test_int32_4, arena);
/* Test iteration */
iter = UPB_MAP_BEGIN;
count = 0;
while (
(const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter)) != NULL) {
int32_t key =
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
const_ent);
int32_t val =
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
const_ent);
count++;
if (key == test_int32) {
ASSERT(val == test_int32_2);
} else {
ASSERT(key == test_int32_3);
ASSERT(val == test_int32_4);
}
}
ASSERT(count == 2);
/* Clearing the map goes back to empty. */
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_clear(msg);
check_int32_map_empty(msg);
upb_arena_free(arena);
}
void test_repeated() {
upb_arena *arena = upb_arena_new();
protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
size_t size;
const int *elems;
protobuf_test_messages_proto3_TestAllTypesProto3_add_repeated_int32(
msg, 5, arena);
elems = protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32(
msg, &size);
ASSERT(size == 1);
ASSERT(elems[0] == 5);
upb_arena_free(arena);
}
int run_tests(int argc, char *argv[]) {
test_scalars();
test_string_map();
test_int32_map();
test_repeated();
return 0;
}

@ -166,7 +166,8 @@ class StrTable {
std::pair<std::string, upb_value> operator*() const {
std::pair<std::string, upb_value> ret;
ret.first.assign(upb_strtable_iter_key(&iter_));
upb_strview view = upb_strtable_iter_key(&iter_);
ret.first.assign(view.data, view.size);
ret.second = upb_strtable_iter_value(&iter_);
return ret;
}

@ -38,6 +38,8 @@ class BuildFileFunctions(object):
def cc_library(self, **kwargs):
if kwargs["name"] == "amalgamation" or kwargs["name"] == "upbc_generator":
return
if kwargs["name"] == "lupb":
return
files = kwargs.get("srcs", []) + kwargs.get("hdrs", [])
found_files = []
for file in files:
@ -98,16 +100,7 @@ class BuildFileFunctions(object):
def py_binary(self, **kwargs):
pass
def lua_cclibrary(self, **kwargs):
pass
def lua_library(self, **kwargs):
pass
def lua_binary(self, **kwargs):
pass
def lua_test(self, **kwargs):
def lua_proto_library(self, **kwargs):
pass
def sh_test(self, **kwargs):

@ -15,97 +15,71 @@
#define LUPB_SYMTAB "lupb.symtab"
#define LUPB_OBJCACHE "lupb.objcache"
#define CHK(pred) \
do { \
upb_status status; \
upb_status_clear(&status); \
pred; \
lupb_checkstatus(L, &status); \
} while (0)
static void lupb_symtab_pushwrapper(lua_State *L, int narg, const void *def,
const char *type);
/* lupb_wrapper ***************************************************************/
/* Wrappers around upb objects. */
/* Wrappers around upb def objects. The userval contains a reference to the
* symtab. */
/* Checks type; if it matches, pulls the pointer out of the wrapper. */
void *lupb_checkwrapper(lua_State *L, int narg, const char *type) {
void *ud = lua_touserdata(L, narg);
void *ret;
#define LUPB_SYMTAB_INDEX 1
if (!ud) {
luaL_typerror(L, narg, "upb wrapper");
}
memcpy(&ret, ud, sizeof(ret));
if (!ret) {
luaL_error(L, "called into dead object");
}
typedef struct {
const void* def; /* upb_msgdef, upb_enumdef, upb_oneofdef, etc. */
} lupb_wrapper;
luaL_checkudata(L, narg, type);
return ret;
static const void *lupb_wrapper_check(lua_State *L, int narg,
const char *type) {
lupb_wrapper *w = luaL_checkudata(L, narg, type);
return w->def;
}
void lupb_pushwrapper(lua_State *L, const void *obj, const char *type) {
void *ud;
if (obj == NULL) {
lua_pushnil(L);
return;
}
/* Lookup our cache in the registry (we don't put our objects in the registry
* directly because we need our cache to be a weak table). */
lua_getfield(L, LUA_REGISTRYINDEX, LUPB_OBJCACHE);
UPB_ASSERT(!lua_isnil(L, -1)); /* Should have been created by luaopen_upb. */
lua_pushlightuserdata(L, (void*)obj);
lua_rawget(L, -2);
/* Stack is now: objcache, cached value. */
if (lua_isnil(L, -1)) {
/* Remove bad cached value and push new value. */
lua_pop(L, 1);
ud = lua_newuserdata(L, sizeof(*ud));
memcpy(ud, &obj, sizeof(*ud));
luaL_getmetatable(L, type);
/* Should have been created by luaopen_upb. */
lupb_assert(L, !lua_isnil(L, -1));
lua_setmetatable(L, -2);
/* Set it in the cache. */
lua_pushlightuserdata(L, (void*)obj);
lua_pushvalue(L, -2);
lua_rawset(L, -4);
}
lua_insert(L, -2);
lua_pop(L, 1);
static void lupb_wrapper_pushsymtab(lua_State *L, int narg) {
lua_getiuservalue(L, narg, LUPB_SYMTAB_INDEX);
}
void lupb_msgdef_pushwrapper(lua_State *L, const upb_msgdef *m);
void lupb_oneofdef_pushwrapper(lua_State *L, const upb_oneofdef *o);
static void lupb_enumdef_pushwrapper(lua_State *L, const upb_enumdef *e);
/* lupb_wrapper_pushwrapper()
*
* For a given def wrapper at index |narg|, pushes a wrapper for the given |def|
* and the given |type|. The new wrapper will be part of the same symtab. */
static void lupb_wrapper_pushwrapper(lua_State *L, int narg, const void *def,
const char *type) {
lupb_wrapper_pushsymtab(L, narg);
lupb_symtab_pushwrapper(L, -1, def, type);
lua_replace(L, -2); /* Remove symtab from stack. */
}
/* lupb_msgdef_pushsubmsgdef()
*
* Pops the msgdef wrapper at the top of the stack and replaces it with a msgdef
* wrapper for field |f| of this msgdef.
*/
void lupb_msgdef_pushsubmsgdef(lua_State *L, const upb_fielddef *f) {
assert(luaL_testudata(L, -1, LUPB_MSGDEF));
const upb_msgdef *m = upb_fielddef_msgsubdef(f);
assert(upb_fielddef_containingtype(f) == lupb_msgdef_check(L, -1));
lupb_wrapper_pushwrapper(L, -1, m, LUPB_MSGDEF);
lua_replace(L, -2); /* Replace msgdef with submsgdef. */
}
/* lupb_fielddef **************************************************************/
void lupb_fielddef_pushwrapper(lua_State *L, const upb_fielddef *f) {
lupb_pushwrapper(L, f, LUPB_FIELDDEF);
}
const upb_fielddef *lupb_fielddef_check(lua_State *L, int narg) {
return lupb_checkwrapper(L, narg, LUPB_FIELDDEF);
return lupb_wrapper_check(L, narg, LUPB_FIELDDEF);
}
static int lupb_fielddef_containingoneof(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
lupb_oneofdef_pushwrapper(L, upb_fielddef_containingoneof(f));
const upb_oneofdef *o = upb_fielddef_containingoneof(f);
lupb_wrapper_pushwrapper(L, 1, o, LUPB_ONEOFDEF);
return 1;
}
static int lupb_fielddef_containingtype(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
lupb_msgdef_pushwrapper(L, upb_fielddef_containingtype(f));
const upb_msgdef *m = upb_fielddef_containingtype(f);
lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
return 1;
}
@ -146,17 +120,6 @@ static int lupb_fielddef_descriptortype(lua_State *L) {
return 1;
}
static int lupb_fielddef_getsel(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
upb_selector_t sel;
if (upb_handlers_getselector(f, luaL_checknumber(L, 2), &sel)) {
lua_pushinteger(L, sel);
return 1;
} else {
return 0;
}
}
static int lupb_fielddef_hassubdef(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
lua_pushboolean(L, upb_fielddef_hassubdef(f));
@ -211,22 +174,21 @@ static int lupb_fielddef_packed(lua_State *L) {
static int lupb_fielddef_msgsubdef(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
lupb_msgdef_pushwrapper(L, upb_fielddef_msgsubdef(f));
const upb_msgdef *m = upb_fielddef_msgsubdef(f);
lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
return 1;
}
static int lupb_fielddef_enumsubdef(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
lupb_enumdef_pushwrapper(L, upb_fielddef_enumsubdef(f));
const upb_enumdef *e = upb_fielddef_enumsubdef(f);
lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
return 1;
}
static int lupb_fielddef_type(lua_State *L) {
const upb_fielddef *f = lupb_fielddef_check(L, 1);
if (upb_fielddef_typeisset(f))
lua_pushinteger(L, upb_fielddef_type(f));
else
lua_pushnil(L);
lua_pushinteger(L, upb_fielddef_type(f));
return 1;
}
@ -235,7 +197,6 @@ static const struct luaL_Reg lupb_fielddef_m[] = {
{"containing_type", lupb_fielddef_containingtype},
{"default", lupb_fielddef_default},
{"descriptor_type", lupb_fielddef_descriptortype},
{"getsel", lupb_fielddef_getsel},
{"has_subdef", lupb_fielddef_hassubdef},
{"index", lupb_fielddef_index},
{"is_extension", lupb_fielddef_isextension},
@ -250,55 +211,64 @@ static const struct luaL_Reg lupb_fielddef_m[] = {
{NULL, NULL}
};
/* lupb_oneofdef **************************************************************/
void lupb_oneofdef_pushwrapper(lua_State *L, const upb_oneofdef *o) {
lupb_pushwrapper(L, o, LUPB_ONEOFDEF);
}
const upb_oneofdef *lupb_oneofdef_check(lua_State *L, int narg) {
return lupb_checkwrapper(L, narg, LUPB_ONEOFDEF);
return lupb_wrapper_check(L, narg, LUPB_ONEOFDEF);
}
static int lupb_oneofdef_containingtype(lua_State *L) {
const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
lupb_msgdef_pushwrapper(L, upb_oneofdef_containingtype(o));
const upb_msgdef *m = upb_oneofdef_containingtype(o);
lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
return 1;
}
/* lupb_oneofdef_field()
*
* Handles:
* oneof.field(field_number)
* oneof.field(field_name)
*/
static int lupb_oneofdef_field(lua_State *L) {
const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
int type = lua_type(L, 2);
const upb_fielddef *f;
if (type == LUA_TNUMBER) {
f = upb_oneofdef_itof(o, lua_tointeger(L, 2));
} else if (type == LUA_TSTRING) {
f = upb_oneofdef_ntofz(o, lua_tostring(L, 2));
} else {
const char *msg = lua_pushfstring(L, "number or string expected, got %s",
luaL_typename(L, 2));
return luaL_argerror(L, 2, msg);
switch (lua_type(L, 2)) {
case LUA_TNUMBER:
f = upb_oneofdef_itof(o, lua_tointeger(L, 2));
break;
case LUA_TSTRING:
f = upb_oneofdef_ntofz(o, lua_tostring(L, 2));
break;
default: {
const char *msg = lua_pushfstring(L, "number or string expected, got %s",
luaL_typename(L, 2));
return luaL_argerror(L, 2, msg);
}
}
lupb_fielddef_pushwrapper(L, f);
lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
return 1;
}
static int lupb_oneofiter_next(lua_State *L) {
upb_oneof_iter *i = lua_touserdata(L, lua_upvalueindex(1));
const upb_fielddef *f;
if (upb_oneof_done(i)) return 0;
lupb_fielddef_pushwrapper(L, upb_oneof_iter_field(i));
f = upb_oneof_iter_field(i);
upb_oneof_next(i);
lupb_symtab_pushwrapper(L, lua_upvalueindex(2), f, LUPB_FIELDDEF);
return 1;
}
static int lupb_oneofdef_fields(lua_State *L) {
const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
upb_oneof_iter *i = lua_newuserdata(L, sizeof(upb_oneof_iter));
lupb_wrapper_pushsymtab(L, 1);
upb_oneof_begin(i, o);
/* Need to guarantee that the msgdef outlives the iter. */
lua_pushvalue(L, 1);
/* Closure upvalues are: iter, symtab. */
lua_pushcclosure(L, &lupb_oneofiter_next, 2);
return 1;
}
@ -335,12 +305,8 @@ typedef struct {
const upb_msgdef *md;
} lupb_msgdef;
void lupb_msgdef_pushwrapper(lua_State *L, const upb_msgdef *m) {
lupb_pushwrapper(L, m, LUPB_MSGDEF);
}
const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg) {
return lupb_checkwrapper(L, narg, LUPB_MSGDEF);
return lupb_wrapper_check(L, narg, LUPB_MSGDEF);
}
static int lupb_msgdef_len(lua_State *L) {
@ -349,42 +315,73 @@ static int lupb_msgdef_len(lua_State *L) {
return 1;
}
/* lupb_msgdef_field()
*
* Handles:
* msg.field(field_number) -> fielddef
* msg.field(field_name) -> fielddef
*/
static int lupb_msgdef_field(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
int type = lua_type(L, 2);
const upb_fielddef *f;
if (type == LUA_TNUMBER) {
f = upb_msgdef_itof(m, lua_tointeger(L, 2));
} else if (type == LUA_TSTRING) {
f = upb_msgdef_ntofz(m, lua_tostring(L, 2));
} else {
const char *msg = lua_pushfstring(L, "number or string expected, got %s",
luaL_typename(L, 2));
return luaL_argerror(L, 2, msg);
switch (lua_type(L, 2)) {
case LUA_TNUMBER:
f = upb_msgdef_itof(m, lua_tointeger(L, 2));
break;
case LUA_TSTRING:
f = upb_msgdef_ntofz(m, lua_tostring(L, 2));
break;
default: {
const char *msg = lua_pushfstring(L, "number or string expected, got %s",
luaL_typename(L, 2));
return luaL_argerror(L, 2, msg);
}
}
lupb_fielddef_pushwrapper(L, f);
lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
return 1;
}
/* lupb_msgdef_lookupname()
*
* Handles:
* msg.lookup_name(name) -> fielddef or oneofdef
*/
static int lupb_msgdef_lookupname(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
const upb_fielddef *f;
const upb_oneofdef *o;
if (!upb_msgdef_lookupnamez(m, lua_tostring(L, 2), &f, &o)) {
lua_pushnil(L);
} else if (o) {
lupb_oneofdef_pushwrapper(L, o);
lupb_wrapper_pushwrapper(L, 1, o, LUPB_ONEOFDEF);
} else {
lupb_fielddef_pushwrapper(L, f);
lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
}
return 1;
}
/* lupb_msgdef_name()
*
* Handles:
* msg.name() -> string
*/
static int lupb_msgdef_name(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
lua_pushstring(L, upb_msgdef_name(m));
return 1;
}
static int lupb_msgfielditer_next(lua_State *L) {
upb_msg_field_iter *i = lua_touserdata(L, lua_upvalueindex(1));
const upb_fielddef *f;
if (upb_msg_field_done(i)) return 0;
lupb_fielddef_pushwrapper(L, upb_msg_iter_field(i));
f = upb_msg_iter_field(i);
lupb_symtab_pushwrapper(L, lua_upvalueindex(2), f, LUPB_FIELDDEF);
upb_msg_field_next(i);
return 1;
}
@ -392,27 +389,44 @@ static int lupb_msgfielditer_next(lua_State *L) {
static int lupb_msgdef_fields(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
upb_msg_field_iter *i = lua_newuserdata(L, sizeof(upb_msg_field_iter));
lupb_wrapper_pushsymtab(L, 1);
upb_msg_field_begin(i, m);
/* Need to guarantee that the msgdef outlives the iter. */
lua_pushvalue(L, 1);
/* Closure upvalues are: iter, symtab. */
lua_pushcclosure(L, &lupb_msgfielditer_next, 2);
return 1;
}
static int lupb_msgdef_file(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
const upb_filedef *file = upb_msgdef_file(m);
lupb_wrapper_pushwrapper(L, 1, file, LUPB_FILEDEF);
return 1;
}
static int lupb_msgdef_fullname(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
lua_pushstring(L, upb_msgdef_fullname(m));
return 1;
}
static int lupb_msgoneofiter_next(lua_State *L) {
upb_msg_oneof_iter *i = lua_touserdata(L, lua_upvalueindex(1));
const upb_oneofdef *o;
if (upb_msg_oneof_done(i)) return 0;
lupb_oneofdef_pushwrapper(L, upb_msg_iter_oneof(i));
o = upb_msg_iter_oneof(i);
upb_msg_oneof_next(i);
lupb_symtab_pushwrapper(L, lua_upvalueindex(2), o, LUPB_ONEOFDEF);
return 1;
}
static int lupb_msgdef_oneofs(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
upb_msg_oneof_iter *i = lua_newuserdata(L, sizeof(upb_msg_oneof_iter));
lupb_wrapper_pushsymtab(L, 1);
upb_msg_oneof_begin(i, m);
/* Need to guarantee that the msgdef outlives the iter. */
lua_pushvalue(L, 1);
/* Closure upvalues are: iter, symtab. */
lua_pushcclosure(L, &lupb_msgoneofiter_next, 2);
return 1;
}
@ -429,15 +443,27 @@ static int lupb_msgdef_syntax(lua_State *L) {
return 1;
}
static int lupb_msgdef_tostring(lua_State *L) {
const upb_msgdef *m = lupb_msgdef_check(L, 1);
lua_pushfstring(L, "<upb.MessageDef name=%s, field_count=%d>",
upb_msgdef_fullname(m), (int)upb_msgdef_numfields(m));
return 1;
}
static const struct luaL_Reg lupb_msgdef_mm[] = {
{"__call", lupb_msg_pushnew},
{"__len", lupb_msgdef_len},
{"__tostring", lupb_msgdef_tostring},
{NULL, NULL}
};
static const struct luaL_Reg lupb_msgdef_m[] = {
{"field", lupb_msgdef_field},
{"fields", lupb_msgdef_fields},
{"file", lupb_msgdef_file},
{"full_name", lupb_msgdef_fullname},
{"lookup_name", lupb_msgdef_lookupname},
{"name", lupb_msgdef_name},
{"oneofs", lupb_msgdef_oneofs},
{"syntax", lupb_msgdef_syntax},
{"_map_entry", lupb_msgdef_mapentry},
@ -448,11 +474,7 @@ static const struct luaL_Reg lupb_msgdef_m[] = {
/* lupb_enumdef ***************************************************************/
const upb_enumdef *lupb_enumdef_check(lua_State *L, int narg) {
return lupb_checkwrapper(L, narg, LUPB_ENUMDEF);
}
static void lupb_enumdef_pushwrapper(lua_State *L, const upb_enumdef *e) {
lupb_pushwrapper(L, e, LUPB_ENUMDEF);
return lupb_wrapper_check(L, narg, LUPB_ENUMDEF);
}
static int lupb_enumdef_len(lua_State *L) {
@ -461,26 +483,46 @@ static int lupb_enumdef_len(lua_State *L) {
return 1;
}
static int lupb_enumdef_file(lua_State *L) {
const upb_enumdef *e = lupb_enumdef_check(L, 1);
const upb_filedef *file = upb_enumdef_file(e);
lupb_wrapper_pushwrapper(L, 1, file, LUPB_FILEDEF);
return 1;
}
/* lupb_enumdef_value()
*
* Handles:
* enum.value(number) -> name
* enum.value(name) -> number
*/
static int lupb_enumdef_value(lua_State *L) {
const upb_enumdef *e = lupb_enumdef_check(L, 1);
int type = lua_type(L, 2);
if (type == LUA_TNUMBER) {
/* Pushes "nil" for a NULL pointer. */
int32_t key = lupb_checkint32(L, 2);
lua_pushstring(L, upb_enumdef_iton(e, key));
} else if (type == LUA_TSTRING) {
const char *key = lua_tostring(L, 2);
int32_t num;
if (upb_enumdef_ntoiz(e, key, &num)) {
lua_pushinteger(L, num);
} else {
lua_pushnil(L);
switch (lua_type(L, 2)) {
case LUA_TNUMBER: {
int32_t key = lupb_checkint32(L, 2);
/* Pushes "nil" for a NULL pointer. */
lua_pushstring(L, upb_enumdef_iton(e, key));
break;
}
case LUA_TSTRING: {
const char *key = lua_tostring(L, 2);
int32_t num;
if (upb_enumdef_ntoiz(e, key, &num)) {
lua_pushinteger(L, num);
} else {
lua_pushnil(L);
}
break;
}
default: {
const char *msg = lua_pushfstring(L, "number or string expected, got %s",
luaL_typename(L, 2));
return luaL_argerror(L, 2, msg);
}
} else {
const char *msg = lua_pushfstring(L, "number or string expected, got %s",
luaL_typename(L, 2));
return luaL_argerror(L, 2, msg);
}
return 1;
}
@ -496,9 +538,10 @@ static int lupb_enumiter_next(lua_State *L) {
static int lupb_enumdef_values(lua_State *L) {
const upb_enumdef *e = lupb_enumdef_check(L, 1);
upb_enum_iter *i = lua_newuserdata(L, sizeof(upb_enum_iter));
lupb_wrapper_pushsymtab(L, 1);
upb_enum_begin(i, e);
/* Need to guarantee that the enumdef outlives the iter. */
lua_pushvalue(L, 1);
/* Closure upvalues are: iter, symtab. */
lua_pushcclosure(L, &lupb_enumiter_next, 2);
return 1;
}
@ -509,6 +552,7 @@ static const struct luaL_Reg lupb_enumdef_mm[] = {
};
static const struct luaL_Reg lupb_enumdef_m[] = {
{"file", lupb_enumdef_file},
{"value", lupb_enumdef_value},
{"values", lupb_enumdef_values},
{NULL, NULL}
@ -517,18 +561,15 @@ static const struct luaL_Reg lupb_enumdef_m[] = {
/* lupb_filedef ***************************************************************/
void lupb_filedef_pushwrapper(lua_State *L, const upb_filedef *f) {
lupb_pushwrapper(L, f, LUPB_FILEDEF);
}
const upb_filedef *lupb_filedef_check(lua_State *L, int narg) {
return lupb_checkwrapper(L, narg, LUPB_FILEDEF);
return lupb_wrapper_check(L, narg, LUPB_FILEDEF);
}
static int lupb_filedef_dep(lua_State *L) {
const upb_filedef *f = lupb_filedef_check(L, 1);
int index = luaL_checkint(L, 2);
lupb_filedef_pushwrapper(L, upb_filedef_dep(f, index));
const upb_filedef *dep = upb_filedef_dep(f, index);
lupb_wrapper_pushwrapper(L, 1, dep, LUPB_FILEDEF);
return 1;
}
@ -541,7 +582,8 @@ static int lupb_filedef_depcount(lua_State *L) {
static int lupb_filedef_enum(lua_State *L) {
const upb_filedef *f = lupb_filedef_check(L, 1);
int index = luaL_checkint(L, 2);
lupb_enumdef_pushwrapper(L, upb_filedef_enum(f, index));
const upb_enumdef *e = upb_filedef_enum(f, index);
lupb_wrapper_pushwrapper(L, 1, e, LUPB_ENUMDEF);
return 1;
}
@ -554,7 +596,8 @@ static int lupb_filedef_enumcount(lua_State *L) {
static int lupb_filedef_msg(lua_State *L) {
const upb_filedef *f = lupb_filedef_check(L, 1);
int index = luaL_checkint(L, 2);
lupb_msgdef_pushwrapper(L, upb_filedef_msg(f, index));
const upb_msgdef *m = upb_filedef_msg(f, index);
lupb_wrapper_pushwrapper(L, 1, m, LUPB_MSGDEF);
return 1;
}
@ -598,6 +641,13 @@ static const struct luaL_Reg lupb_filedef_m[] = {
/* lupb_symtab ****************************************************************/
/* The symtab owns all defs. Thus GC-rooting the symtab ensures that all
* underlying defs stay alive.
*
* The symtab's userval is a cache of def* -> object. */
#define LUPB_CACHE_INDEX 1
typedef struct {
upb_symtab *symtab;
} lupb_symtab;
@ -610,11 +660,61 @@ upb_symtab *lupb_symtab_check(lua_State *L, int narg) {
return lsymtab->symtab;
}
void lupb_symtab_pushwrapper(lua_State *L, int narg, const void *def,
const char *type) {
narg = lua_absindex(L, narg);
assert(luaL_testudata(L, narg, LUPB_SYMTAB));
if (def == NULL) {
lua_pushnil(L);
return;
}
lua_getiuservalue(L, narg, LUPB_CACHE_INDEX); /* Get cache. */
/* Index by "def" pointer. */
lua_rawgetp(L, -1, def);
/* Stack is now: cache, cached value. */
if (lua_isnil(L, -1)) {
/* Create new wrapper. */
lupb_wrapper *w = lupb_newuserdata(L, sizeof(*w), 1, type);
w->def = def;
lua_replace(L, -2); /* Replace nil */
/* Set symtab as userval. */
lua_pushvalue(L, narg);
lua_setiuservalue(L, -2, LUPB_SYMTAB_INDEX);
/* Add wrapper to the the cache. */
lua_pushvalue(L, -1);
lua_rawsetp(L, -3, def);
}
lua_replace(L, -2); /* Remove cache, leaving only the wrapper. */
}
/* upb_symtab_new()
*
* Handles:
* upb.SymbolTable() -> <new instance>
*/
static int lupb_symtab_new(lua_State *L) {
lupb_symtab *lsymtab = lua_newuserdata(L, sizeof(*lsymtab));
lupb_symtab *lsymtab = lupb_newuserdata(L, sizeof(*lsymtab), 1, LUPB_SYMTAB);
lsymtab->symtab = upb_symtab_new();
luaL_getmetatable(L, LUPB_SYMTAB);
/* Create our object cache. */
lua_newtable(L);
/* Cache metatable: specifies that values are weak. */
lua_createtable(L, 0, 1);
lua_pushstring(L, "v");
lua_setfield(L, -2, "__mode");
lua_setmetatable(L, -2);
/* Set the cache as our userval. */
lua_setiuservalue(L, -2, LUPB_CACHE_INDEX);
return 1;
}
@ -625,20 +725,40 @@ static int lupb_symtab_gc(lua_State *L) {
return 0;
}
/* TODO(haberman): perhaps this should take a message object instead of a
* serialized string once we have a good story for vending compiled-in
* messages. */
static int lupb_symtab_add(lua_State *L) {
upb_arena *arena;
static int lupb_symtab_addfile(lua_State *L) {
size_t len;
upb_symtab *s = lupb_symtab_check(L, 1);
const char *str = luaL_checklstring(L, 2, &len);
upb_arena *arena = lupb_arena_pushnew(L);;
const google_protobuf_FileDescriptorProto *file;
const upb_filedef *file_def;
upb_status status;
upb_status_clear(&status);
file = google_protobuf_FileDescriptorProto_parse(str, len, arena);
if (!file) {
luaL_argerror(L, 2, "failed to parse descriptor");
}
file_def = upb_symtab_addfile(s, file, &status);
lupb_checkstatus(L, &status);
lupb_symtab_pushwrapper(L, 1, file_def, LUPB_FILEDEF);
return 1;
}
static int lupb_symtab_addset(lua_State *L) {
size_t i, n, len;
const google_protobuf_FileDescriptorProto *const *files;
google_protobuf_FileDescriptorSet *set;
upb_symtab *s = lupb_symtab_check(L, 1);
const char *str = luaL_checklstring(L, 2, &len);
upb_arena *arena = lupb_arena_pushnew(L);;
upb_status status;
lupb_arena_new(L);
arena = lupb_arena_check(L, -1);
upb_status_clear(&status);
set = google_protobuf_FileDescriptorSet_parse(str, len, arena);
if (!set) {
@ -647,7 +767,8 @@ static int lupb_symtab_add(lua_State *L) {
files = google_protobuf_FileDescriptorSet_file(set, &n);
for (i = 0; i < n; i++) {
CHK(upb_symtab_addfile(s, files[i], &status));
upb_symtab_addfile(s, files[i], &status);
lupb_checkstatus(L, &status);
}
return 0;
@ -656,19 +777,27 @@ static int lupb_symtab_add(lua_State *L) {
static int lupb_symtab_lookupmsg(lua_State *L) {
const upb_symtab *s = lupb_symtab_check(L, 1);
const upb_msgdef *m = upb_symtab_lookupmsg(s, luaL_checkstring(L, 2));
lupb_msgdef_pushwrapper(L, m);
lupb_symtab_pushwrapper(L, 1, m, LUPB_MSGDEF);
return 1;
}
static int lupb_symtab_lookupenum(lua_State *L) {
const upb_symtab *s = lupb_symtab_check(L, 1);
const upb_enumdef *e = upb_symtab_lookupenum(s, luaL_checkstring(L, 2));
lupb_enumdef_pushwrapper(L, e);
lupb_symtab_pushwrapper(L, 1, e, LUPB_ENUMDEF);
return 1;
}
static int lupb_symtab_tostring(lua_State *L) {
const upb_symtab *s = lupb_symtab_check(L, 1);
lua_pushfstring(L, "<upb.SymbolTable file_count=%d>",
(int)upb_symtab_filecount(s));
return 1;
}
static const struct luaL_Reg lupb_symtab_m[] = {
{"add", lupb_symtab_add},
{"add_file", lupb_symtab_addfile},
{"add_set", lupb_symtab_addset},
{"lookup_msg", lupb_symtab_lookupmsg},
{"lookup_enum", lupb_symtab_lookupenum},
{NULL, NULL}
@ -676,6 +805,7 @@ static const struct luaL_Reg lupb_symtab_m[] = {
static const struct luaL_Reg lupb_symtab_mm[] = {
{"__gc", lupb_symtab_gc},
{"__tostring", lupb_symtab_tostring},
{NULL, NULL}
};
@ -694,7 +824,7 @@ static const struct luaL_Reg lupbdef_toplevel_m[] = {
void lupb_def_registertypes(lua_State *L) {
lupb_setfuncs(L, lupbdef_toplevel_m);
/* Refcounted types. */
/* Register types. */
lupb_register_type(L, LUPB_ENUMDEF, lupb_enumdef_m, lupb_enumdef_mm);
lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, NULL);
lupb_register_type(L, LUPB_FILEDEF, lupb_filedef_m, NULL);
@ -702,14 +832,6 @@ void lupb_def_registertypes(lua_State *L) {
lupb_register_type(L, LUPB_ONEOFDEF, lupb_oneofdef_m, lupb_oneofdef_mm);
lupb_register_type(L, LUPB_SYMTAB, lupb_symtab_m, lupb_symtab_mm);
/* Create our object cache. */
lua_newtable(L);
lua_createtable(L, 0, 1); /* Cache metatable. */
lua_pushstring(L, "v"); /* Values are weak. */
lua_setfield(L, -2, "__mode");
lua_setmetatable(L, -2);
lua_setfield(L, LUA_REGISTRYINDEX, LUPB_OBJCACHE);
/* Register constants. */
lupb_setfieldi(L, "LABEL_OPTIONAL", UPB_LABEL_OPTIONAL);
lupb_setfieldi(L, "LABEL_REQUIRED", UPB_LABEL_REQUIRED);
@ -746,21 +868,6 @@ void lupb_def_registertypes(lua_State *L) {
lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT32", UPB_DESCRIPTOR_TYPE_SINT32);
lupb_setfieldi(L, "DESCRIPTOR_TYPE_SINT64", UPB_DESCRIPTOR_TYPE_SINT64);
lupb_setfieldi(L, "HANDLER_INT32", UPB_HANDLER_INT32);
lupb_setfieldi(L, "HANDLER_INT64", UPB_HANDLER_INT64);
lupb_setfieldi(L, "HANDLER_UINT32", UPB_HANDLER_UINT32);
lupb_setfieldi(L, "HANDLER_UINT64", UPB_HANDLER_UINT64);
lupb_setfieldi(L, "HANDLER_FLOAT", UPB_HANDLER_FLOAT);
lupb_setfieldi(L, "HANDLER_DOUBLE", UPB_HANDLER_DOUBLE);
lupb_setfieldi(L, "HANDLER_BOOL", UPB_HANDLER_BOOL);
lupb_setfieldi(L, "HANDLER_STARTSTR", UPB_HANDLER_STARTSTR);
lupb_setfieldi(L, "HANDLER_STRING", UPB_HANDLER_STRING);
lupb_setfieldi(L, "HANDLER_ENDSTR", UPB_HANDLER_ENDSTR);
lupb_setfieldi(L, "HANDLER_STARTSUBMSG", UPB_HANDLER_STARTSUBMSG);
lupb_setfieldi(L, "HANDLER_ENDSUBMSG", UPB_HANDLER_ENDSUBMSG);
lupb_setfieldi(L, "HANDLER_STARTSEQ", UPB_HANDLER_STARTSEQ);
lupb_setfieldi(L, "HANDLER_ENDSEQ", UPB_HANDLER_ENDSEQ);
lupb_setfieldi(L, "SYNTAX_PROTO2", UPB_SYNTAX_PROTO2);
lupb_setfieldi(L, "SYNTAX_PROTO3", UPB_SYNTAX_PROTO3);
}

@ -0,0 +1,109 @@
load("@bazel_skylib//lib:paths.bzl", "paths")
# Generic support code #########################################################
_is_bazel = not hasattr(native, "genmpm")
def _get_real_short_path(file):
# For some reason, files from other archives have short paths that look like:
# ../com_google_protobuf/google/protobuf/descriptor.proto
short_path = file.short_path
if short_path.startswith("../"):
second_slash = short_path.index("/", 3)
short_path = short_path[second_slash + 1:]
# Sometimes it has another few prefixes like:
# _virtual_imports/any_proto/google/protobuf/any.proto
# We want just google/protobuf/any.proto.
if short_path.startswith("_virtual_imports"):
short_path = short_path.split("/", 2)[-1]
return short_path
def _get_real_root(file):
real_short_path = _get_real_short_path(file)
return file.path[:-len(real_short_path) - 1]
def _generate_output_file(ctx, src, extension):
real_short_path = _get_real_short_path(src)
real_short_path = paths.relativize(real_short_path, ctx.label.package)
output_filename = paths.replace_extension(real_short_path, extension)
ret = ctx.actions.declare_file(output_filename)
return ret
# upb_proto_library / upb_proto_reflection_library shared code #################
_LuaFiles = provider(fields = ["files"])
def _compile_upb_protos(ctx, proto_info, proto_sources):
files = [_generate_output_file(ctx, name, "_pb.lua") for name in proto_sources]
transitive_sets = proto_info.transitive_descriptor_sets.to_list()
ctx.actions.run(
inputs = depset(
direct = [proto_info.direct_descriptor_set],
transitive = [proto_info.transitive_descriptor_sets],
),
tools = [ctx.executable._upbc],
outputs = files,
executable = ctx.executable._protoc,
arguments = [
"--lua_out=" + _get_real_root(files[0]),
"--plugin=protoc-gen-lua=" + ctx.executable._upbc.path,
"--descriptor_set_in=" + ctx.configuration.host_path_separator.join([f.path for f in transitive_sets]),
] +
[_get_real_short_path(file) for file in proto_sources],
progress_message = "Generating Lua protos for :" + ctx.label.name,
)
return files
def _lua_proto_rule_impl(ctx):
if len(ctx.attr.deps) != 1:
fail("only one deps dependency allowed.")
dep = ctx.attr.deps[0]
if _LuaFiles not in dep:
fail("proto_library rule must generate _LuaFiles (aspect should have handled this).")
files = dep[_LuaFiles].files
return [
DefaultInfo(
files = files,
data_runfiles = ctx.runfiles(files = files.to_list())),
]
def _lua_proto_library_aspect_impl(target, ctx):
proto_info = target[ProtoInfo]
files = _compile_upb_protos(ctx, proto_info, proto_info.direct_sources)
deps = ctx.rule.attr.deps
transitive = [dep[_LuaFiles].files for dep in deps if _LuaFiles in dep]
return [_LuaFiles(files = depset(direct = files, transitive = transitive))]
# lua_proto_library() ##########################################################
_lua_proto_library_aspect = aspect(
attrs = {
"_upbc": attr.label(
executable = True,
cfg = "host",
default = "//:protoc-gen-lua",
),
"_protoc": attr.label(
executable = True,
cfg = "host",
default = "@com_google_protobuf//:protoc",
),
},
implementation = _lua_proto_library_aspect_impl,
provides = [_LuaFiles],
attr_aspects = ["deps"],
fragments = ["cpp"],
)
lua_proto_library = rule(
output_to_genfiles = True,
implementation = _lua_proto_rule_impl,
attrs = {
"deps": attr.label_list(
aspects = [_lua_proto_library_aspect],
allow_rules = ["proto_library"],
providers = [ProtoInfo],
),
},
)

File diff suppressed because it is too large Load Diff

@ -20,103 +20,91 @@
** domain of [u]int64 values.
*/
#include "upb/bindings/lua/upb.h"
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "upb/bindings/lua/upb.h"
#include "upb/handlers.h"
#include "upb/msg.h"
/* Lua compatibility code *****************************************************/
/* Lua 5.1 and Lua 5.2 have slightly incompatible APIs. A little bit of
* compatibility code can help hide the difference. Not too many people still
* use Lua 5.1 but LuaJIT uses the Lua 5.1 API in some ways. */
/* Shims for upcoming Lua 5.3 functionality. */
static bool lua_isinteger(lua_State *L, int argn) {
LUPB_UNUSED(L);
LUPB_UNUSED(argn);
return false;
}
#if LUA_VERSION_NUM == 501
/* taken from lua 5.2's source. */
void *luaL_testudata(lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
return p;
}
/* Utility functions **********************************************************/
void lupb_checkstatus(lua_State *L, upb_status *s) {
if (!upb_ok(s)) {
lua_pushstring(L, upb_status_errmsg(s));
lua_error(L);
}
return NULL; /* value is not a userdata with a metatable */
}
static void lupb_newlib(lua_State *L, const char *name, const luaL_Reg *funcs) {
luaL_register(L, name, funcs);
}
/* Pushes a new userdata with the given metatable. */
void *lupb_newuserdata(lua_State *L, size_t size, int n, const char *type) {
#if LUA_VERSION_NUM >= 504
void *ret = lua_newuserdatauv(L, size, n);
#else
void *ret = lua_newuserdata(L, size);
lua_createtable(L, 0, n);
lua_setuservalue(L, -2);
#endif
#elif LUA_VERSION_NUM == 502
/* Set metatable. */
luaL_getmetatable(L, type);
assert(!lua_isnil(L, -1)); /* Should have been created by luaopen_upb. */
lua_setmetatable(L, -2);
int luaL_typerror(lua_State *L, int narg, const char *tname) {
const char *msg = lua_pushfstring(L, "%s expected, got %s",
tname, luaL_typename(L, narg));
return luaL_argerror(L, narg, msg);
return ret;
}
static void lupb_newlib(lua_State *L, const char *name, const luaL_Reg *funcs) {
/* Lua 5.2 modules are not expected to set a global variable, so "name" is
* unused. */
UPB_UNUSED(name);
/* Can't use luaL_newlib(), because funcs is not the actual array.
* Could (micro-)optimize this a bit to count funcs for initial table size. */
lua_createtable(L, 0, 8);
luaL_setfuncs(L, funcs, 0);
#if LUA_VERSION_NUM < 504
int lua_setiuservalue(lua_State *L, int index, int n) {
lua_getuservalue(L, index);
lua_insert(L, -2);
lua_rawseti(L, -2, n);
lua_pop(L, 1);
return 1;
}
#else
#error Only Lua 5.1 and 5.2 are supported
#endif
/* Shims for upcoming Lua 5.3 functionality. */
bool lua_isinteger(lua_State *L, int argn) {
UPB_UNUSED(L);
UPB_UNUSED(argn);
return false;
int lua_getiuservalue(lua_State *L, int index, int n) {
lua_getuservalue(L, index);
lua_rawgeti(L, -1, n);
lua_replace(L, -2);
return 1;
}
#endif
void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
const luaL_Reg *mm) {
luaL_newmetatable(L, name);
/* Utility functions **********************************************************/
/* We store our module table in the registry, keyed by ptr.
* For more info about the motivation/rationale, see this thread:
* http://thread.gmane.org/gmane.comp.lang.lua.general/110632 */
bool lupb_openlib(lua_State *L, void *ptr, const char *name,
const luaL_Reg *funcs) {
/* Lookup cached module table. */
lua_pushlightuserdata(L, ptr);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_isnil(L, -1)) {
return true;
if (mm) {
lupb_setfuncs(L, mm);
}
lupb_newlib(L, name, funcs);
/* Save module table in cache. */
lua_pushlightuserdata(L, ptr);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);
return false;
}
if (m) {
/* Methods go in the mt's __index method. This implies that you can'
* implement __index and also have methods. */
lua_getfield(L, -1, "__index");
lupb_assert(L, lua_isnil(L, -1));
lua_pop(L, 1);
void lupb_checkstatus(lua_State *L, upb_status *s) {
if (!upb_ok(s)) {
lua_pushstring(L, upb_status_errmsg(s));
lua_error(L);
lua_createtable(L, 0, 0);
lupb_setfuncs(L, m);
lua_setfield(L, -2, "__index");
}
lua_pop(L, 1); /* The mt. */
}
/* Scalar type mapping ********************************************************/
@ -204,42 +192,16 @@ void lupb_pushfloat(lua_State *L, float d) {
lua_pushnumber(L, d);
}
/* Library entry point ********************************************************/
static const struct luaL_Reg lupb_toplevel_m[] = {
{NULL, NULL}
};
void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
const luaL_Reg *mm) {
luaL_newmetatable(L, name);
if (mm) {
lupb_setfuncs(L, mm);
}
if (m) {
/* Methods go in the mt's __index method. This implies that you can'
* implement __index and also have methods. */
lua_getfield(L, -1, "__index");
lupb_assert(L, lua_isnil(L, -1));
lua_pop(L, 1);
lua_createtable(L, 0, 0);
lupb_setfuncs(L, m);
lua_setfield(L, -2, "__index");
}
lua_pop(L, 1); /* The mt. */
}
int luaopen_upb_c(lua_State *L) {
static char module_key;
if (lupb_openlib(L, &module_key, "upb_c", lupb_toplevel_m)) {
return 1;
}
int luaopen_lupb(lua_State *L) {
#if LUA_VERSION_NUM == 501
const struct luaL_Reg funcs[] = {{NULL, NULL}};
luaL_register(L, "upb_c", funcs);
#else
lua_createtable(L, 0, 8);
#endif
lupb_def_registertypes(L);
lupb_msg_registertypes(L);
return 1; /* Return package table. */
}

@ -7,65 +7,46 @@
#include "lauxlib.h"
#include "upb/def.h"
#include "upb/handlers.h"
#include "upb/msg.h"
#include "upb/msgfactory.h"
/* Lua 5.1/5.2 compatibility code. */
#if LUA_VERSION_NUM == 501
/* Lua changes its API in incompatible ways in every minor release.
* This is some shim code to paper over the differences. */
#if LUA_VERSION_NUM == 501
#define lua_rawlen lua_objlen
/* Lua >= 5.2's getuservalue/setuservalue functions do not exist in prior
* versions but the older function lua_getfenv() can provide 100% of its
* capabilities (the reverse is not true). */
#define lua_getuservalue(L, index) lua_getfenv(L, index)
#define lua_setuservalue(L, index) lua_setfenv(L, index)
void *luaL_testudata(lua_State *L, int ud, const char *tname);
#define lua_setuservalue(L, idx) lua_setfenv(L, idx)
#define lua_getuservalue(L, idx) lua_getfenv(L, idx)
#define lupb_setfuncs(L, l) luaL_register(L, NULL, l)
#elif LUA_VERSION_NUM >= 502 && LUA_VERSION_NUM <= 504
#define lupb_setfuncs(L, l) luaL_setfuncs(L, l, 0)
#else
#error Only Lua 5.1-5.4 are supported
#endif
#elif LUA_VERSION_NUM == 502
/* Create a new userdata with the given type and |n| uservals, which are popped
* from the stack to initialize the userdata. */
void *lupb_newuserdata(lua_State *L, size_t size, int n, const char *type);
int luaL_typerror(lua_State *L, int narg, const char *tname);
#if LUA_VERSION_NUM < 504
/* Polyfills for this Lua 5.4 function. Pushes userval |n| for the userdata at
* |index|. */
int lua_setiuservalue(lua_State *L, int index, int n);
int lua_getiuservalue(lua_State *L, int index, int n);
#endif
#define lupb_setfuncs(L, l) luaL_setfuncs(L, l, 0)
/* Registers a type with the given name, methods, and metamethods. */
void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
const luaL_Reg *mm);
#else
#error Only Lua 5.1 and 5.2 are supported
#endif
/* Checks the given upb_status and throws a Lua error if it is not ok. */
void lupb_checkstatus(lua_State *L, upb_status *s);
#define lupb_assert(L, predicate) \
if (!(predicate)) \
luaL_error(L, "internal error: %s, %s:%d ", #predicate, __FILE__, __LINE__);
int luaopen_lupb(lua_State *L);
/* Function for initializing the core library. This function is idempotent,
* and should be called at least once before calling any of the functions that
* construct core upb types. */
int luaopen_upb(lua_State *L);
/* Gets or creates a package table for a C module that is uniquely identified by
* "ptr". The easiest way to supply a unique "ptr" is to pass the address of a
* static variable private in the module's .c file.
*
* If this module has already been registered in this lua_State, pushes it and
* returns true.
*
* Otherwise, creates a new module table for this module with the given name,
* pushes it, and registers the given top-level functions in it. It also sets
* it as a global variable, but only if the current version of Lua expects that
* (ie Lua 5.1/LuaJIT).
*
* If "false" is returned, the caller is guaranteed that this lib has not been
* registered in this Lua state before (regardless of any funny business the
* user might have done to the global state), so the caller can safely perform
* one-time initialization. */
bool lupb_openlib(lua_State *L, void *ptr, const char *name,
const luaL_Reg *funcs);
/* C <-> Lua value conversions. ***********************************************/
/* Custom check/push functions. Unlike the Lua equivalents, they are pinned to
* specific types (instead of lua_Number, etc), and do not allow any implicit
* specific C types (instead of lua_Number, etc), and do not allow any implicit
* conversion or data loss. */
int64_t lupb_checkint64(lua_State *L, int narg);
int32_t lupb_checkint32(lua_State *L, int narg);
@ -81,47 +62,35 @@ void lupb_pushint64(lua_State *L, int64_t val);
void lupb_pushint32(lua_State *L, int32_t val);
void lupb_pushuint64(lua_State *L, uint64_t val);
void lupb_pushuint32(lua_State *L, uint32_t val);
void lupb_pushdouble(lua_State *L, double val);
void lupb_pushfloat(lua_State *L, float val);
/* Registers a type with the given name, methods, and metamethods. */
void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
const luaL_Reg *mm);
/* Checks the given upb_status and throws a Lua error if it is not ok. */
void lupb_checkstatus(lua_State *L, upb_status *s);
/** From def.c. ***************************************************************/
upb_fieldtype_t lupb_checkfieldtype(lua_State *L, int narg);
const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg);
const upb_enumdef *lupb_enumdef_check(lua_State *L, int narg);
const upb_fielddef *lupb_fielddef_check(lua_State *L, int narg);
upb_symtab *lupb_symtab_check(lua_State *L, int narg);
void lupb_msgdef_pushsubmsgdef(lua_State *L, const upb_fielddef *f);
void lupb_def_registertypes(lua_State *L);
/** From msg.c. ***************************************************************/
struct lupb_msgclass;
typedef struct lupb_msgclass lupb_msgclass;
upb_arena *lupb_arena_check(lua_State *L, int narg);
int lupb_arena_new(lua_State *L);
upb_arena *lupb_arena_get(lua_State *L);
int lupb_msg_pushref(lua_State *L, int msgclass, void *msg);
const upb_msg *lupb_msg_checkmsg(lua_State *L, int narg,
const lupb_msgclass *lmsgclass);
upb_msg *lupb_msg_checkmsg2(lua_State *L, int narg,
const upb_msglayout **layout);
const lupb_msgclass *lupb_msgclass_check(lua_State *L, int narg);
const upb_msglayout *lupb_msgclass_getlayout(lua_State *L, int narg);
const upb_msgdef *lupb_msgclass_getmsgdef(const lupb_msgclass *lmsgclass);
upb_msgfactory *lupb_msgclass_getfactory(const lupb_msgclass *lmsgclass);
int lupb_msg_pushnew(lua_State *L);
upb_arena *lupb_arena_pushnew(lua_State *L);
void lupb_msg_registertypes(lua_State *L);
#define lupb_assert(L, predicate) \
if (!(predicate)) \
luaL_error(L, "internal error: %s, %s:%d ", #predicate, __FILE__, __LINE__);
#define LUPB_UNUSED(var) (void)var
#if defined(__GNUC__) || defined(__clang__)
#define LUPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
#else
#define LUPB_UNREACHABLE() do { assert(0); } while(0)
#endif
#endif /* UPB_LUA_UPB_H_ */

@ -1,172 +1,30 @@
-- Before calling require on "upb_c", we need to load the same library
-- as RTLD_GLOBAL, for the benefit of other C extensions that depend on
-- C functions in the core.
--
-- This has to happen *before* the require call, because if the module
-- is loaded RTLD_LOCAL first, a subsequent load as RTLD_GLOBAL won't
-- have the proper effect, at least on some platforms.
local so = package.searchpath and package.searchpath("upb_c", package.cpath)
if so then
package.loadlib(so, "*")
end
local upb = require("upb_c")
-- A convenience function for building/linking/freezing defs
-- while maintaining their original order.
--
-- Sample usage:
-- local m1, m2 = upb.build_defs{
-- upb.MessageDef{full_name = "M1", fields = {
-- upb.FieldDef{
-- name = "m2",
-- number = 1,
-- type = upb.TYPE_MESSAGE,
-- subdef_name = ".M2"
-- },
-- }
-- },
-- upb.MessageDef{full_name = "M2"}
-- }
upb.build_defs = function(defs)
upb.SymbolTable(defs)
-- Lua 5.2 puts unpack in the table library.
return (unpack or table.unpack)(defs)
end
local upb = require("lupb")
local ipairs_iter = function(array, last_index)
local next_index = last_index + 1
if next_index > #array then
return nil
end
return next_index, array[next_index]
end
upb.generated_pool = upb.SymbolTable()
-- For iterating over the indexes and values of a upb.Array.
--
-- for i, val in upb.ipairs(array) do
-- -- ...
-- end
upb.ipairs = function(array)
return ipairs_iter, array, 0
end
local set_named = function(obj, init)
for k, v in pairs(init) do
local func = obj["set_" .. k]
if not func then
error("Cannot set member: " .. k)
local module_metatable = {
__index = function(t, k)
local package = t._filedef:package()
if package then
k = package .. "." .. k
end
func(obj, v)
end
end
-- Capture references to the functions we're wrapping.
local RealFieldDef = upb.FieldDef
local RealEnumDef = upb.EnumDef
local RealMessageDef = upb.MessageDef
local RealOneofDef = upb.OneofDef
local RealSymbolTable = upb.SymbolTable
-- FieldDef constructor; a wrapper around the real constructor that can
-- set initial properties.
--
-- User can specify initialization values like so:
-- upb.FieldDef{label=upb.LABEL_REQUIRED, name="my_field", number=5,
-- type=upb.TYPE_INT32, default_value=12, type_name="Foo"}
upb.FieldDef = function(init)
local f = RealFieldDef()
if init then
-- Other members are often dependent on type, so set that first.
if init.type then
f:set_type(init.type)
init.type = nil
end
set_named(f, init)
end
return f
end
-- MessageDef constructor; a wrapper around the real constructor that can
-- set initial properties.
--
-- User can specify initialization values like so:
-- upb.MessageDef{full_name="MyMessage", extstart=8000, fields={...}}
upb.MessageDef = function(init)
local m = RealMessageDef()
if init then
for _, f in pairs(init.fields or {}) do
m:add(f)
local pool = upb.generated_pool
local def = pool:lookup_msg(k) or pool:lookup_enum(k)
local v = nil
if def and def:file():name() == t._filedef:name() then
v = def
t[k] = v
end
init.fields = nil
set_named(m, init)
end
return m
end
-- EnumDef constructor; a wrapper around the real constructor that can
-- set initial properties.
--
-- User can specify initialization values like so:
-- upb.EnumDef{full_name="MyEnum",
-- values={
-- {"FOO_VALUE_1", 1},
-- {"FOO_VALUE_2", 2}
-- }
-- }
upb.EnumDef = function(init)
local e = RealEnumDef()
if init then
for _, val in pairs(init.values or {}) do
e:add(val[1], val[2])
end
init.values = nil
set_named(e, init)
end
return e
end
-- OneofDef constructor; a wrapper around the real constructor that can
-- set initial properties.
--
-- User can specify initialization values like so:
-- upb.OneofDef{name="foo", fields={...}}
upb.OneofDef = function(init)
local o = RealOneofDef()
if init then
for _, val in pairs(init.fields or {}) do
o:add(val)
end
init.fields = nil
set_named(o, init)
end
return o
end
-- SymbolTable constructor; a wrapper around the real constructor that can
-- add an initial set of defs.
upb.SymbolTable = function(defs)
local s = RealSymbolTable()
if defs then
s:add(defs)
return v
end
}
return s
function upb._generated_module(desc_string)
local file = upb.generated_pool:add_file(desc_string)
local module = {_filedef = file}
setmetatable(module, module_metatable)
return module
end
return upb

@ -1,56 +0,0 @@
/*
** require("upb.pb") -- A Lua extension for upb.pb.
**
** Exposes all the types defined in upb/pb/{*}.h
** Also defines a few convenience functions on top.
*/
#include "upb/bindings/lua/upb.h"
#include "upb/decode.h"
#include "upb/encode.h"
#define LUPB_PBDECODERMETHOD "lupb.pb.decodermethod"
static int lupb_pb_decode(lua_State *L) {
size_t len;
const upb_msglayout *layout;
upb_msg *msg = lupb_msg_checkmsg2(L, 1, &layout);
const char *pb = lua_tolstring(L, 2, &len);
upb_decode(pb, len, msg, layout, lupb_arena_get(L));
/* TODO(haberman): check for error. */
return 0;
}
static int lupb_pb_encode(lua_State *L) {
const upb_msglayout *layout;
const upb_msg *msg = lupb_msg_checkmsg2(L, 1, &layout);
upb_arena *arena = upb_arena_new();
size_t size;
char *result;
result = upb_encode(msg, (const void*)layout, arena, &size);
/* Free resources before we potentially bail on error. */
lua_pushlstring(L, result, size);
upb_arena_free(arena);
/* TODO(haberman): check for error. */
return 1;
}
static const struct luaL_Reg toplevel_m[] = {
{"decode", lupb_pb_decode},
{"encode", lupb_pb_encode},
{NULL, NULL}
};
int luaopen_upb_pb_c(lua_State *L) {
static char module_key;
if (lupb_openlib(L, &module_key, "upb.pb_c", toplevel_m)) {
return 1;
}
return 1;
}

@ -1,3 +0,0 @@
require "upb"
return require "upb.pb_c"

@ -0,0 +1,112 @@
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "absl/strings/str_replace.h"
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/io/printer.h>
namespace protoc = ::google::protobuf::compiler;
namespace protobuf = ::google::protobuf;
class LuaGenerator : public protoc::CodeGenerator {
bool Generate(const protobuf::FileDescriptor* file,
const std::string& parameter, protoc::GeneratorContext* context,
std::string* error) const override;
};
static std::string StripExtension(absl::string_view fname) {
size_t lastdot = fname.find_last_of(".");
if (lastdot == std::string::npos) {
return std::string(fname);
}
return std::string(fname.substr(0, lastdot));
}
static std::string Filename(const protobuf::FileDescriptor* file) {
return StripExtension(file->name()) + "_pb.lua";
}
static std::string ModuleName(const protobuf::FileDescriptor* file) {
std::string ret = StripExtension(file->name()) + "_pb";
return absl::StrReplaceAll(ret, {{"/", "."}});
}
static void PrintHexDigit(char digit, protobuf::io::Printer* printer) {
char text;
if (digit < 10) {
text = '0' + digit;
} else {
text = 'A' + (digit - 10);
}
printer->WriteRaw(&text, 1);
}
static void PrintString(int max_cols, absl::string_view* str,
protobuf::io::Printer* printer) {
printer->Print("\'");
while (max_cols > 0 && !str->empty()) {
char ch = (*str)[0];
if (ch == '\\') {
printer->PrintRaw("\\\\");
max_cols--;
} else if (ch == '\'') {
printer->PrintRaw("\\'");
max_cols--;
} else if (isprint(ch)) {
printer->WriteRaw(&ch, 1);
max_cols--;
} else {
unsigned char byte = ch;
printer->PrintRaw("\\x");
PrintHexDigit(byte >> 4, printer);
PrintHexDigit(byte & 15, printer);
max_cols -= 4;
}
str->remove_prefix(1);
}
printer->Print("\'");
}
bool LuaGenerator::Generate(
const protobuf::FileDescriptor* file,
const std::string& parameter,
protoc::GeneratorContext* context,
std::string* error) const {
std::string filename = Filename(file);
protobuf::io::ZeroCopyOutputStream* out = context->Open(filename);
protobuf::io::Printer printer(out, '$');
for (int i = 0; i < file->dependency_count(); i++) {
const protobuf::FileDescriptor* dep = file->dependency(i);
printer.Print("require('$name$')\n", "name", ModuleName(dep));
}
printer.Print("local upb = require('upb')\n");
protobuf::FileDescriptorProto file_proto;
file->CopyTo(&file_proto);
std::string file_data;
file_proto.SerializeToString(&file_data);
printer.Print("local descriptor = table.concat({\n");
absl::string_view data(file_data);
while (!data.empty()) {
printer.Print(" ");
PrintString(72, &data, &printer);
printer.Print(",\n");
}
printer.Print("})\n");
printer.Print("return upb._generated_module(descriptor)\n");
return true;
}
int main(int argc, char** argv) {
LuaGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}

@ -6,8 +6,8 @@
#include "upb/port_def.inc"
/* Maps descriptor type -> upb field type. */
const uint8_t upb_desctype_to_fieldtype[] = {
UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
static const uint8_t desctype_to_fieldtype[] = {
-1, /* invalid descriptor type */
UPB_TYPE_DOUBLE, /* DOUBLE */
UPB_TYPE_FLOAT, /* FLOAT */
UPB_TYPE_INT64, /* INT64 */
@ -28,9 +28,31 @@ const uint8_t upb_desctype_to_fieldtype[] = {
UPB_TYPE_INT64, /* SINT64 */
};
/* Maps descriptor type -> upb map size. */
static const uint8_t desctype_to_mapsize[] = {
-1, /* invalid descriptor type */
8, /* DOUBLE */
4, /* FLOAT */
8, /* INT64 */
8, /* UINT64 */
4, /* INT32 */
8, /* FIXED64 */
4, /* FIXED32 */
1, /* BOOL */
UPB_MAPTYPE_STRING, /* STRING */
sizeof(void*), /* GROUP */
sizeof(void*), /* MESSAGE */
UPB_MAPTYPE_STRING, /* BYTES */
4, /* UINT32 */
4, /* ENUM */
4, /* SFIXED32 */
8, /* SFIXED64 */
4, /* SINT32 */
8, /* SINT64 */
};
/* Data pertaining to the parse. */
typedef struct {
const char *ptr; /* Current parsing position. */
const char *field_start; /* Start of this field. */
const char *limit; /* End of delimited region or end of buffer. */
upb_arena *arena;
@ -38,60 +60,50 @@ typedef struct {
uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */
} upb_decstate;
/* Data passed by value to each parsing function. */
typedef struct {
char *msg;
const upb_msglayout *layout;
upb_decstate *state;
} upb_decframe;
#define CHK(x) if (!(x)) { return 0; }
#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs)
static bool upb_skip_unknowngroup(upb_decstate *d, int field_number);
static bool upb_decode_message(upb_decstate *d, char *msg,
const upb_msglayout *l);
static const char *upb_decode_message(const char *ptr, const upb_msglayout *l,
upb_msg *msg, upb_decstate *d);
static bool upb_decode_varint(const char **ptr, const char *limit,
uint64_t *val) {
static const char *upb_decode_varint(const char *ptr, const char *limit,
uint64_t *val) {
uint8_t byte;
int bitpos = 0;
const char *p = *ptr;
*val = 0;
do {
CHK(bitpos < 70 && p < limit);
byte = *p;
CHK(bitpos < 70 && ptr < limit);
byte = *ptr;
*val |= (uint64_t)(byte & 0x7F) << bitpos;
p++;
ptr++;
bitpos += 7;
} while (byte & 0x80);
*ptr = p;
return true;
return ptr;
}
static bool upb_decode_varint32(const char **ptr, const char *limit,
uint32_t *val) {
static const char *upb_decode_varint32(const char *ptr, const char *limit,
uint32_t *val) {
uint64_t u64;
CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX);
CHK(ptr = upb_decode_varint(ptr, limit, &u64))
CHK(u64 <= UINT32_MAX);
*val = (uint32_t)u64;
return true;
return ptr;
}
static bool upb_decode_64bit(const char **ptr, const char *limit,
uint64_t *val) {
CHK(limit - *ptr >= 8);
memcpy(val, *ptr, 8);
*ptr += 8;
return true;
static const char *upb_decode_64bit(const char *ptr, const char *limit,
uint64_t *val) {
CHK(limit - ptr >= 8);
memcpy(val, ptr, 8);
return ptr + 8;
}
static bool upb_decode_32bit(const char **ptr, const char *limit,
uint32_t *val) {
CHK(limit - *ptr >= 4);
memcpy(val, *ptr, 4);
*ptr += 4;
return true;
static const char *upb_decode_32bit(const char *ptr, const char *limit,
uint32_t *val) {
CHK(limit - ptr >= 4);
memcpy(val, ptr, 4);
return ptr + 4;
}
static int32_t upb_zzdecode_32(uint32_t n) {
@ -102,99 +114,72 @@ static int64_t upb_zzdecode_64(uint64_t n) {
return (n >> 1) ^ -(int64_t)(n & 1);
}
static bool upb_decode_string(const char **ptr, const char *limit,
int *outlen) {
static const char *upb_decode_string(const char *ptr, const char *limit,
int *outlen) {
uint32_t len;
CHK(upb_decode_varint32(ptr, limit, &len) &&
len < INT32_MAX &&
limit - *ptr >= (int32_t)len);
CHK(ptr = upb_decode_varint32(ptr, limit, &len));
CHK(len < INT32_MAX);
CHK(limit - ptr >= (int32_t)len);
*outlen = len;
return true;
return ptr;
}
static void upb_set32(void *msg, size_t ofs, uint32_t val) {
memcpy((char*)msg + ofs, &val, sizeof(val));
}
static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame) {
upb_msg_addunknown(frame->msg, d->field_start, d->ptr - d->field_start,
d->arena);
return true;
static const char *upb_append_unknown(const char *ptr, upb_msg *msg,
upb_decstate *d) {
upb_msg_addunknown(msg, d->field_start, ptr - d->field_start, d->arena);
return ptr;
}
static bool upb_skip_unknownfielddata(upb_decstate *d, uint32_t tag,
uint32_t group_fieldnum) {
static const char *upb_skip_unknownfielddata(const char *ptr, upb_decstate *d,
uint32_t tag) {
switch (tag & 7) {
case UPB_WIRE_TYPE_VARINT: {
uint64_t val;
return upb_decode_varint(&d->ptr, d->limit, &val);
return upb_decode_varint(ptr, d->limit, &val);
}
case UPB_WIRE_TYPE_32BIT: {
uint32_t val;
return upb_decode_32bit(&d->ptr, d->limit, &val);
return upb_decode_32bit(ptr, d->limit, &val);
}
case UPB_WIRE_TYPE_64BIT: {
uint64_t val;
return upb_decode_64bit(&d->ptr, d->limit, &val);
return upb_decode_64bit(ptr, d->limit, &val);
}
case UPB_WIRE_TYPE_DELIMITED: {
int len;
CHK(upb_decode_string(&d->ptr, d->limit, &len));
d->ptr += len;
return true;
CHK(ptr = upb_decode_string(ptr, d->limit, &len));
return ptr + len;
}
case UPB_WIRE_TYPE_START_GROUP: {
uint32_t field_number = tag >> 3;
while (ptr < d->limit && d->end_group == 0) {
uint32_t tag = 0;
CHK(ptr = upb_decode_varint32(ptr, d->limit, &tag));
CHK(ptr = upb_skip_unknownfielddata(ptr, d, tag));
}
CHK(d->end_group == field_number);
d->end_group = 0;
return ptr;
}
case UPB_WIRE_TYPE_START_GROUP:
return upb_skip_unknowngroup(d, tag >> 3);
case UPB_WIRE_TYPE_END_GROUP:
return (tag >> 3) == group_fieldnum;
d->end_group = tag >> 3;
return ptr;
}
return false;
}
static bool upb_skip_unknowngroup(upb_decstate *d, int field_number) {
while (d->ptr < d->limit && d->end_group == 0) {
uint32_t tag = 0;
CHK(upb_decode_varint32(&d->ptr, d->limit, &tag));
CHK(upb_skip_unknownfielddata(d, tag, field_number));
}
CHK(d->end_group == field_number);
d->end_group = 0;
return true;
}
static bool upb_array_grow(upb_array *arr, size_t elements, size_t elem_size,
upb_arena *arena) {
size_t needed = arr->len + elements;
size_t new_size = UPB_MAX(arr->size, 8);
size_t new_bytes;
size_t old_bytes;
void *new_data;
upb_alloc *alloc = upb_arena_alloc(arena);
while (new_size < needed) {
new_size *= 2;
}
old_bytes = arr->len * elem_size;
new_bytes = new_size * elem_size;
new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes);
CHK(new_data);
arr->data = new_data;
arr->size = new_size;
return true;
}
static void *upb_array_reserve(upb_array *arr, size_t elements,
size_t elem_size, upb_arena *arena) {
if (arr->size - arr->len < elements) {
CHK(upb_array_grow(arr, elements, elem_size, arena));
CHK(_upb_array_realloc(arr, arr->len + elements, arena));
}
return (char*)arr->data + (arr->len * elem_size);
return (char*)_upb_array_ptr(arr) + (arr->len * elem_size);
}
bool upb_array_add(upb_array *arr, size_t elements, size_t elem_size,
@ -208,82 +193,80 @@ bool upb_array_add(upb_array *arr, size_t elements, size_t elem_size,
return true;
}
static upb_array *upb_getarr(upb_decframe *frame,
const upb_msglayout_field *field) {
static upb_array *upb_getarr(upb_msg *msg, const upb_msglayout_field *field) {
UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
return *(upb_array**)&frame->msg[field->offset];
return *PTR_AT(msg, field->offset, upb_array*);
}
static upb_array *upb_getorcreatearr(upb_decframe *frame,
const upb_msglayout_field *field) {
upb_array *arr = upb_getarr(frame, field);
static upb_array *upb_getorcreatearr(upb_msg *msg,
const upb_msglayout_field *field,
upb_decstate *d) {
upb_array *arr = upb_getarr(msg, field);
if (!arr) {
arr = upb_array_new(frame->state->arena);
upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype];
arr = _upb_array_new(d->arena, type);
CHK(arr);
*(upb_array**)&frame->msg[field->offset] = arr;
*PTR_AT(msg, field->offset, upb_array*) = arr;
}
return arr;
}
static upb_msg *upb_getorcreatemsg(upb_decframe *frame,
static upb_msg *upb_getorcreatemsg(upb_msg *msg,
const upb_msglayout_field *field,
const upb_msglayout **subm) {
upb_msg **submsg = (void*)(frame->msg + field->offset);
*subm = frame->layout->submsgs[field->submsg_index];
const upb_msglayout *layout,
upb_decstate *d) {
upb_msg **submsg = PTR_AT(msg, field->offset, upb_msg*);
UPB_ASSERT(field->label != UPB_LABEL_REPEATED);
if (!*submsg) {
*submsg = upb_msg_new(*subm, frame->state->arena);
*submsg = _upb_msg_new(layout, d->arena);
CHK(*submsg);
}
return *submsg;
}
static upb_msg *upb_addmsg(upb_decframe *frame,
static upb_msg *upb_addmsg(upb_msg *msg,
const upb_msglayout_field *field,
const upb_msglayout **subm) {
const upb_msglayout *layout,
upb_decstate *d) {
upb_msg *submsg;
upb_array *arr = upb_getorcreatearr(frame, field);
upb_array *arr = upb_getorcreatearr(msg, field, d);
UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
*subm = frame->layout->submsgs[field->submsg_index];
submsg = upb_msg_new(*subm, frame->state->arena);
submsg = _upb_msg_new(layout, d->arena);
CHK(submsg);
upb_array_add(arr, 1, sizeof(submsg), &submsg, frame->state->arena);
upb_array_add(arr, 1, sizeof(submsg), &submsg, d->arena);
return submsg;
}
static void upb_sethasbit(upb_decframe *frame,
const upb_msglayout_field *field) {
static void upb_sethasbit(upb_msg *msg, const upb_msglayout_field *field) {
int32_t hasbit = field->presence;
UPB_ASSERT(field->presence > 0);
frame->msg[hasbit / 8] |= (1 << (hasbit % 8));
*PTR_AT(msg, hasbit / 8, char) |= (1 << (hasbit % 8));
}
static void upb_setoneofcase(upb_decframe *frame,
const upb_msglayout_field *field) {
static void upb_setoneofcase(upb_msg *msg, const upb_msglayout_field *field) {
UPB_ASSERT(field->presence < 0);
upb_set32(frame->msg, ~field->presence, field->number);
upb_set32(msg, ~field->presence, field->number);
}
static bool upb_decode_addval(upb_decframe *frame,
const upb_msglayout_field *field, void *val,
size_t size) {
char *field_mem = frame->msg + field->offset;
static bool upb_decode_addval(upb_msg *msg, const upb_msglayout_field *field,
void *val, size_t size, upb_decstate *d) {
char *field_mem = PTR_AT(msg, field->offset, char);
upb_array *arr;
if (field->label == UPB_LABEL_REPEATED) {
arr = upb_getorcreatearr(frame, field);
arr = upb_getorcreatearr(msg, field, d);
CHK(arr);
field_mem = upb_array_reserve(arr, 1, size, frame->state->arena);
field_mem = upb_array_reserve(arr, 1, size, d->arena);
CHK(field_mem);
}
@ -291,142 +274,147 @@ static bool upb_decode_addval(upb_decframe *frame,
return true;
}
static void upb_decode_setpresent(upb_decframe *frame,
static void upb_decode_setpresent(upb_msg *msg,
const upb_msglayout_field *field) {
if (field->label == UPB_LABEL_REPEATED) {
upb_array *arr = upb_getarr(frame, field);
upb_array *arr = upb_getarr(msg, field);
UPB_ASSERT(arr->len < arr->size);
arr->len++;
} else if (field->presence < 0) {
upb_setoneofcase(frame, field);
upb_setoneofcase(msg, field);
} else if (field->presence > 0) {
upb_sethasbit(frame, field);
upb_sethasbit(msg, field);
}
}
static bool upb_decode_msgfield(upb_decstate *d, upb_msg *msg,
const upb_msglayout *layout, int limit) {
static const char *upb_decode_msgfield(const char *ptr,
const upb_msglayout *layout, int limit,
upb_msg *msg, upb_decstate *d) {
const char* saved_limit = d->limit;
d->limit = d->ptr + limit;
d->limit = ptr + limit;
CHK(--d->depth >= 0);
upb_decode_message(d, msg, layout);
ptr = upb_decode_message(ptr, layout, msg, d);
d->depth++;
d->limit = saved_limit;
CHK(d->end_group == 0);
return true;
return ptr;
}
static bool upb_decode_groupfield(upb_decstate *d, upb_msg *msg,
const upb_msglayout *layout,
int field_number) {
static const char *upb_decode_groupfield(const char *ptr,
const upb_msglayout *layout,
int field_number, upb_msg *msg,
upb_decstate *d) {
CHK(--d->depth >= 0);
upb_decode_message(d, msg, layout);
ptr = upb_decode_message(ptr, layout, msg, d);
d->depth++;
CHK(d->end_group == field_number);
d->end_group = 0;
return true;
return ptr;
}
static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field) {
static const char *upb_decode_varintfield(const char *ptr, upb_msg *msg,
const upb_msglayout_field *field,
upb_decstate *d) {
uint64_t val;
CHK(upb_decode_varint(&d->ptr, d->limit, &val));
CHK(ptr = upb_decode_varint(ptr, d->limit, &val));
switch (field->descriptortype) {
case UPB_DESCRIPTOR_TYPE_INT64:
case UPB_DESCRIPTOR_TYPE_UINT64:
CHK(upb_decode_addval(frame, field, &val, sizeof(val)));
CHK(upb_decode_addval(msg, field, &val, sizeof(val), d));
break;
case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_DESCRIPTOR_TYPE_UINT32:
case UPB_DESCRIPTOR_TYPE_ENUM: {
uint32_t val32 = (uint32_t)val;
CHK(upb_decode_addval(frame, field, &val32, sizeof(val32)));
CHK(upb_decode_addval(msg, field, &val32, sizeof(val32), d));
break;
}
case UPB_DESCRIPTOR_TYPE_BOOL: {
bool valbool = val != 0;
CHK(upb_decode_addval(frame, field, &valbool, sizeof(valbool)));
CHK(upb_decode_addval(msg, field, &valbool, sizeof(valbool), d));
break;
}
case UPB_DESCRIPTOR_TYPE_SINT32: {
int32_t decoded = upb_zzdecode_32((uint32_t)val);
CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded)));
CHK(upb_decode_addval(msg, field, &decoded, sizeof(decoded), d));
break;
}
case UPB_DESCRIPTOR_TYPE_SINT64: {
int64_t decoded = upb_zzdecode_64(val);
CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded)));
CHK(upb_decode_addval(msg, field, &decoded, sizeof(decoded), d));
break;
}
default:
return upb_append_unknown(d, frame);
return upb_append_unknown(ptr, msg, d);
}
upb_decode_setpresent(frame, field);
return true;
upb_decode_setpresent(msg, field);
return ptr;
}
static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field) {
static const char *upb_decode_64bitfield(const char *ptr,
const upb_msglayout_field *field,
upb_msg *msg, upb_decstate *d) {
uint64_t val;
CHK(upb_decode_64bit(&d->ptr, d->limit, &val));
CHK(ptr = upb_decode_64bit(ptr, d->limit, &val));
switch (field->descriptortype) {
case UPB_DESCRIPTOR_TYPE_DOUBLE:
case UPB_DESCRIPTOR_TYPE_FIXED64:
case UPB_DESCRIPTOR_TYPE_SFIXED64:
CHK(upb_decode_addval(frame, field, &val, sizeof(val)));
CHK(upb_decode_addval(msg, field, &val, sizeof(val), d));
break;
default:
return upb_append_unknown(d, frame);
return upb_append_unknown(ptr, msg, d);
}
upb_decode_setpresent(frame, field);
return true;
upb_decode_setpresent(msg, field);
return ptr;
}
static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field) {
static const char *upb_decode_32bitfield(const char *ptr,
const upb_msglayout_field *field,
upb_msg *msg, upb_decstate *d) {
uint32_t val;
CHK(upb_decode_32bit(&d->ptr, d->limit, &val));
CHK(ptr = upb_decode_32bit(ptr, d->limit, &val));
switch (field->descriptortype) {
case UPB_DESCRIPTOR_TYPE_FLOAT:
case UPB_DESCRIPTOR_TYPE_FIXED32:
case UPB_DESCRIPTOR_TYPE_SFIXED32:
CHK(upb_decode_addval(frame, field, &val, sizeof(val)));
CHK(upb_decode_addval(msg, field, &val, sizeof(val), d));
break;
default:
return upb_append_unknown(d, frame);
return upb_append_unknown(ptr, msg, d);
}
upb_decode_setpresent(frame, field);
return true;
upb_decode_setpresent(msg, field);
return ptr;
}
static bool upb_decode_fixedpacked(upb_decstate *d, upb_array *arr,
uint32_t len, int elem_size) {
static const char *upb_decode_fixedpacked(const char *ptr, upb_decstate *d,
upb_array *arr, uint32_t len,
int elem_size) {
size_t elements = len / elem_size;
CHK((size_t)(elements * elem_size) == len);
CHK(upb_array_add(arr, elements, elem_size, d->ptr, d->arena));
d->ptr += len;
return true;
CHK(upb_array_add(arr, elements, elem_size, ptr, d->arena));
return ptr + len;
}
static upb_strview upb_decode_strfield(upb_decstate *d, uint32_t len) {
upb_strview ret;
ret.data = d->ptr;
ret.size = len;
d->ptr += len;
return ret;
static const char *upb_decode_strfield(const char *ptr, upb_decstate *d,
uint32_t len, upb_strview *str) {
str->data = ptr;
str->size = len;
return ptr + len;
}
static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field, int len) {
upb_array *arr = upb_getorcreatearr(frame, field);
static const char *upb_decode_toarray(const char *ptr,
const upb_msglayout *layout,
const upb_msglayout_field *field, int len,
upb_msg *msg, upb_decstate *d) {
upb_array *arr = upb_getorcreatearr(msg, field, d);
CHK(arr);
#define VARINT_CASE(ctype, decode) \
@ -434,33 +422,33 @@ static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
#define VARINT_CASE_EX(ctype, decode, dtype) \
{ \
const char *ptr = d->ptr; \
const char *limit = ptr + len; \
while (ptr < limit) { \
uint64_t val; \
ctype decoded; \
CHK(upb_decode_varint(&ptr, limit, &val)); \
CHK(ptr = upb_decode_varint(ptr, limit, &val)); \
decoded = (decode)((dtype)val); \
CHK(upb_array_add(arr, 1, sizeof(decoded), &decoded, d->arena)); \
} \
d->ptr = ptr; \
return true; \
return ptr; \
}
switch (field->descriptortype) {
case UPB_DESCRIPTOR_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES: {
upb_strview str = upb_decode_strfield(d, len);
return upb_array_add(arr, 1, sizeof(str), &str, d->arena);
upb_strview str;
ptr = upb_decode_strfield(ptr, d, len, &str);
CHK(upb_array_add(arr, 1, sizeof(str), &str, d->arena));
return ptr;
}
case UPB_DESCRIPTOR_TYPE_FLOAT:
case UPB_DESCRIPTOR_TYPE_FIXED32:
case UPB_DESCRIPTOR_TYPE_SFIXED32:
return upb_decode_fixedpacked(d, arr, len, sizeof(int32_t));
return upb_decode_fixedpacked(ptr, d, arr, len, sizeof(int32_t));
case UPB_DESCRIPTOR_TYPE_DOUBLE:
case UPB_DESCRIPTOR_TYPE_FIXED64:
case UPB_DESCRIPTOR_TYPE_SFIXED64:
return upb_decode_fixedpacked(d, arr, len, sizeof(int64_t));
return upb_decode_fixedpacked(ptr, d, arr, len, sizeof(int64_t));
case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_DESCRIPTOR_TYPE_UINT32:
case UPB_DESCRIPTOR_TYPE_ENUM:
@ -475,48 +463,83 @@ static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
case UPB_DESCRIPTOR_TYPE_SINT64:
VARINT_CASE_EX(int64_t, upb_zzdecode_64, uint64_t);
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
const upb_msglayout *subm;
upb_msg *submsg = upb_addmsg(frame, field, &subm);
const upb_msglayout *subl = layout->submsgs[field->submsg_index];
upb_msg *submsg = upb_addmsg(msg, field, subl, d);
CHK(submsg);
return upb_decode_msgfield(d, submsg, subm, len);
return upb_decode_msgfield(ptr, subl, len, submsg, d);
}
case UPB_DESCRIPTOR_TYPE_GROUP:
return upb_append_unknown(d, frame);
return upb_append_unknown(ptr, msg, d);
}
#undef VARINT_CASE
UPB_UNREACHABLE();
}
static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field) {
static const char *upb_decode_mapfield(const char *ptr,
const upb_msglayout *layout,
const upb_msglayout_field *field,
int len, upb_msg *msg, upb_decstate *d) {
upb_map *map = *PTR_AT(msg, field->offset, upb_map*);
const upb_msglayout *entry = layout->submsgs[field->submsg_index];
upb_map_entry ent;
if (!map) {
/* Lazily create map. */
const upb_msglayout_field *key_field = &entry->fields[0];
const upb_msglayout_field *val_field = &entry->fields[1];
char key_size = desctype_to_mapsize[key_field->descriptortype];
char val_size = desctype_to_mapsize[val_field->descriptortype];
UPB_ASSERT(key_field->number == 1);
UPB_ASSERT(val_field->number == 2);
UPB_ASSERT(key_field->offset == 0);
UPB_ASSERT(val_field->offset == sizeof(upb_strview));
map = _upb_map_new(d->arena, key_size, val_size);
*PTR_AT(msg, field->offset, upb_map*) = map;
}
/* Parse map entry. */
memset(&ent, 0, sizeof(ent));
CHK(ptr = upb_decode_msgfield(ptr, entry, len, &ent.k, d));
/* Insert into map. */
_upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena);
return ptr;
}
static const char *upb_decode_delimitedfield(const char *ptr,
const upb_msglayout *layout,
const upb_msglayout_field *field,
upb_msg *msg, upb_decstate *d) {
int len;
CHK(upb_decode_string(&d->ptr, d->limit, &len));
CHK(ptr = upb_decode_string(ptr, d->limit, &len));
if (field->label == UPB_LABEL_REPEATED) {
return upb_decode_toarray(d, frame, field, len);
return upb_decode_toarray(ptr, layout, field, len, msg, d);
} else if (field->label == UPB_LABEL_MAP) {
return upb_decode_mapfield(ptr, layout, field, len, msg, d);
} else {
switch (field->descriptortype) {
case UPB_DESCRIPTOR_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES: {
upb_strview str = upb_decode_strfield(d, len);
CHK(upb_decode_addval(frame, field, &str, sizeof(str)));
upb_strview str;
ptr = upb_decode_strfield(ptr, d, len, &str);
CHK(upb_decode_addval(msg, field, &str, sizeof(str), d));
break;
}
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
const upb_msglayout *subm;
upb_msg *submsg = upb_getorcreatemsg(frame, field, &subm);
const upb_msglayout *subl = layout->submsgs[field->submsg_index];
upb_msg *submsg = upb_getorcreatemsg(msg, field, subl, d);
CHK(submsg);
CHK(upb_decode_msgfield(d, submsg, subm, len));
CHK(ptr = upb_decode_msgfield(ptr, subl, len, submsg, d));
break;
}
default:
/* TODO(haberman): should we accept the last element of a packed? */
d->ptr += len;
return upb_append_unknown(d, frame);
return upb_append_unknown(ptr + len, msg, d);
}
upb_decode_setpresent(frame, field);
return true;
upb_decode_setpresent(msg, field);
return ptr;
}
}
@ -533,77 +556,75 @@ static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
return NULL; /* Unknown field. */
}
static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) {
static const char *upb_decode_field(const char *ptr,
const upb_msglayout *layout, upb_msg *msg,
upb_decstate *d) {
uint32_t tag;
const upb_msglayout_field *field;
int field_number;
d->field_start = d->ptr;
CHK(upb_decode_varint32(&d->ptr, d->limit, &tag));
d->field_start = ptr;
CHK(ptr = upb_decode_varint32(ptr, d->limit, &tag));
field_number = tag >> 3;
field = upb_find_field(frame->layout, field_number);
field = upb_find_field(layout, field_number);
if (field) {
switch (tag & 7) {
case UPB_WIRE_TYPE_VARINT:
return upb_decode_varintfield(d, frame, field);
return upb_decode_varintfield(ptr, msg, field, d);
case UPB_WIRE_TYPE_32BIT:
return upb_decode_32bitfield(d, frame, field);
return upb_decode_32bitfield(ptr, field, msg, d);
case UPB_WIRE_TYPE_64BIT:
return upb_decode_64bitfield(d, frame, field);
return upb_decode_64bitfield(ptr, field, msg, d);
case UPB_WIRE_TYPE_DELIMITED:
return upb_decode_delimitedfield(d, frame, field);
return upb_decode_delimitedfield(ptr, layout, field, msg, d);
case UPB_WIRE_TYPE_START_GROUP: {
const upb_msglayout *layout;
const upb_msglayout *subl = layout->submsgs[field->submsg_index];
upb_msg *group;
if (field->label == UPB_LABEL_REPEATED) {
group = upb_addmsg(frame, field, &layout);
group = upb_addmsg(msg, field, subl, d);
} else {
group = upb_getorcreatemsg(frame, field, &layout);
group = upb_getorcreatemsg(msg, field, subl, d);
}
return upb_decode_groupfield(d, group, layout, field_number);
return upb_decode_groupfield(ptr, subl, field_number, group, d);
}
case UPB_WIRE_TYPE_END_GROUP:
d->end_group = field_number;
return true;
return ptr;
default:
CHK(false);
}
} else {
CHK(field_number != 0);
CHK(upb_skip_unknownfielddata(d, tag, -1));
CHK(upb_append_unknown(d, frame));
return true;
CHK(ptr = upb_skip_unknownfielddata(ptr, d, tag));
CHK(ptr = upb_append_unknown(ptr, msg, d));
return ptr;
}
UPB_UNREACHABLE();
}
static bool upb_decode_message(upb_decstate *d, char *msg, const upb_msglayout *l) {
upb_decframe frame;
frame.msg = msg;
frame.layout = l;
frame.state = d;
while (d->ptr < d->limit) {
CHK(upb_decode_field(d, &frame));
static const char *upb_decode_message(const char *ptr, const upb_msglayout *l,
upb_msg *msg, upb_decstate *d) {
while (ptr < d->limit) {
CHK(ptr = upb_decode_field(ptr, l, msg, d));
}
return true;
return ptr;
}
bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
upb_arena *arena) {
upb_decstate state;
state.ptr = buf;
state.limit = buf + size;
state.arena = arena;
state.depth = 64;
state.end_group = 0;
CHK(upb_decode_message(&state, msg, l));
CHK(upb_decode_message(buf, l, msg, &state));
return state.end_group == 0;
}
#undef CHK
#undef PTR_AT

@ -42,7 +42,8 @@ struct upb_fielddef {
const google_protobuf_FieldDescriptorProto *unresolved;
} sub;
uint32_t number_;
uint32_t index_;
uint16_t index_;
uint16_t layout_index;
uint32_t selector_base; /* Used to index into a upb::Handlers table. */
bool is_extension_;
bool lazy_;
@ -52,6 +53,7 @@ struct upb_fielddef {
};
struct upb_msgdef {
const upb_msglayout *layout;
const upb_filedef *file;
const char *full_name;
uint32_t selector_count;
@ -379,7 +381,7 @@ const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
}
const char *upb_enum_iter_name(upb_enum_iter *iter) {
return upb_strtable_iter_key(iter);
return upb_strtable_iter_key(iter).data;
}
int32_t upb_enum_iter_number(upb_enum_iter *iter) {
@ -575,6 +577,10 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
return f->sub.enumdef;
}
const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) {
return &f->msgdef->layout->fields[f->layout_index];
}
bool upb_fielddef_issubmsg(const upb_fielddef *f) {
return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
}
@ -604,6 +610,7 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f) {
bool upb_fielddef_haspresence(const upb_fielddef *f) {
if (upb_fielddef_isseq(f)) return false;
if (upb_fielddef_issubmsg(f)) return true;
if (upb_fielddef_containingoneof(f)) return true;
return f->file->syntax == UPB_SYNTAX_PROTO2;
}
@ -697,6 +704,15 @@ int upb_msgdef_numoneofs(const upb_msgdef *m) {
return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof);
}
const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) {
return m->layout;
}
const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i) {
if (i >= m->field_count) return NULL;
return &m->fields[i];
}
bool upb_msgdef_mapentry(const upb_msgdef *m) {
return m->map_entry;
}
@ -819,6 +835,194 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
upb_inttable_iter_setdone(iter);
}
/* Dynamic Layout Generation. *************************************************/
static bool is_power_of_two(size_t val) {
return (val & (val - 1)) == 0;
}
/* Align up to the given power of 2. */
static size_t align_up(size_t val, size_t align) {
UPB_ASSERT(is_power_of_two(align));
return (val + align - 1) & ~(align - 1);
}
static size_t div_round_up(size_t n, size_t d) {
return (n + d - 1) / d;
}
static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
switch (type) {
case UPB_TYPE_DOUBLE:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
return 8;
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_FLOAT:
return 4;
case UPB_TYPE_BOOL:
return 1;
case UPB_TYPE_MESSAGE:
return sizeof(void*);
case UPB_TYPE_BYTES:
case UPB_TYPE_STRING:
return sizeof(upb_strview);
}
UPB_UNREACHABLE();
}
static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) {
upb_map_entry ent;
UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v));
return sizeof(ent.k);
} else if (upb_fielddef_isseq(f)) {
return sizeof(void*);
} else {
return upb_msgval_sizeof(upb_fielddef_type(f));
}
}
static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
size_t ret;
l->size = align_up(l->size, size);
ret = l->size;
l->size += size;
return ret;
}
/* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
* It computes a dynamic layout for all of the fields in |m|. */
static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
upb_msglayout *l = (upb_msglayout*)m->layout;
upb_msg_field_iter it;
upb_msg_oneof_iter oit;
size_t hasbit;
size_t submsg_count = m->submsg_field_count;
const upb_msglayout **submsgs;
upb_msglayout_field *fields;
upb_alloc *alloc = upb_arena_alloc(symtab->arena);
memset(l, 0, sizeof(*l));
fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields));
submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs));
if ((!fields && upb_msgdef_numfields(m)) ||
(!submsgs && submsg_count)) {
/* OOM. */
return false;
}
l->field_count = upb_msgdef_numfields(m);
l->fields = fields;
l->submsgs = submsgs;
/* Allocate data offsets in three stages:
*
* 1. hasbits.
* 2. regular fields.
* 3. oneof fields.
*
* OPT: There is a lot of room for optimization here to minimize the size.
*/
/* Allocate hasbits and set basic field attributes. */
submsg_count = 0;
for (upb_msg_field_begin(&it, m), hasbit = 0;
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
upb_fielddef* f = upb_msg_iter_field(&it);
upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
field->number = upb_fielddef_number(f);
field->descriptortype = upb_fielddef_descriptortype(f);
field->label = upb_fielddef_label(f);
if (upb_fielddef_ismap(f)) {
field->label = UPB_LABEL_MAP;
}
/* TODO: we probably should sort the fields by field number to match the
* output of upbc, and to improve search speed for the table parser. */
f->layout_index = f->index_;
if (upb_fielddef_issubmsg(f)) {
const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
field->submsg_index = submsg_count++;
submsgs[field->submsg_index] = subm->layout;
}
if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
/* We don't use hasbit 0, so that 0 can indicate "no presence" in the
* table. This wastes one hasbit, but we don't worry about it for now. */
field->presence = ++hasbit;
} else {
field->presence = 0;
}
}
/* Account for space used by hasbits. */
l->size = div_round_up(hasbit, 8);
/* Allocate non-oneof fields. */
for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
size_t field_size = upb_msg_fielddefsize(f);
size_t index = upb_fielddef_index(f);
if (upb_fielddef_containingoneof(f)) {
/* Oneofs are handled separately below. */
continue;
}
fields[index].offset = upb_msglayout_place(l, field_size);
}
/* Allocate oneof fields. Each oneof field consists of a uint32 for the case
* and space for the actual data. */
for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
upb_msg_oneof_next(&oit)) {
const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
upb_oneof_iter fit;
size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
size_t field_size = 0;
uint32_t case_offset;
uint32_t data_offset;
/* Calculate field size: the max of all field sizes. */
for (upb_oneof_begin(&fit, o);
!upb_oneof_done(&fit);
upb_oneof_next(&fit)) {
const upb_fielddef* f = upb_oneof_iter_field(&fit);
field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
}
/* Align and allocate case offset. */
case_offset = upb_msglayout_place(l, case_size);
data_offset = upb_msglayout_place(l, field_size);
for (upb_oneof_begin(&fit, o);
!upb_oneof_done(&fit);
upb_oneof_next(&fit)) {
const upb_fielddef* f = upb_oneof_iter_field(&fit);
fields[upb_fielddef_index(f)].offset = data_offset;
fields[upb_fielddef_index(f)].presence = ~case_offset;
}
}
/* Size of the entire structure should be a multiple of its greatest
* alignment. TODO: track overall alignment for real? */
l->size = align_up(l->size, 8);
return true;
}
/* Code to build defs from descriptor protos. *********************************/
/* There is a question of how much validation to do here. It will be difficult
@ -831,11 +1035,12 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
typedef struct {
const upb_symtab *symtab;
upb_filedef *file; /* File we are building. */
upb_alloc *alloc; /* Allocate defs here. */
upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */
upb_strtable *addtab; /* full_name -> packed def ptr for new defs. */
upb_status *status; /* Record errors here. */
upb_filedef *file; /* File we are building. */
upb_alloc *alloc; /* Allocate defs here. */
upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */
upb_strtable *addtab; /* full_name -> packed def ptr for new defs */
const upb_msglayout **layouts; /* NULL if we should build layouts. */
upb_status *status; /* Record errors here. */
} symtab_addctx;
static char* strviewdup(const symtab_addctx *ctx, upb_strview view) {
@ -990,7 +1195,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
}
case UPB_TYPE_INT64: {
/* XXX: Need to write our own strtoll, since it's not available in c89. */
long long val = strtol(str, &end, 0);
int64_t val = strtol(str, &end, 0);
CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end);
f->defaultval.sint = val;
break;
@ -1003,7 +1208,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
}
case UPB_TYPE_UINT64: {
/* XXX: Need to write our own strtoull, since it's not available in c89. */
unsigned long long val = strtoul(str, &end, 0);
uint64_t val = strtoul(str, &end, 0);
CHK(val <= UINT64_MAX && errno != ERANGE && !*end);
f->defaultval.uint = val;
break;
@ -1121,6 +1326,21 @@ static bool create_fielddef(
field_number);
return false;
}
if (ctx->layouts) {
const upb_msglayout_field *fields = m->layout->fields;
int count = m->layout->field_count;
bool found = false;
int i;
for (i = 0; i < count; i++) {
if (fields[i].number == field_number) {
f->layout_index = i;
found = true;
break;
}
}
UPB_ASSERT(found);
}
} else {
/* extension field. */
f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count];
@ -1257,7 +1477,7 @@ static bool create_enumdef(
return true;
}
static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
const google_protobuf_DescriptorProto *msg_proto) {
upb_msgdef *m;
const google_protobuf_MessageOptions *options;
@ -1287,6 +1507,14 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix,
m->map_entry = google_protobuf_MessageOptions_map_entry(options);
}
if (ctx->layouts) {
m->layout = *ctx->layouts;
ctx->layouts++;
} else {
/* Allocate now (to allow cross-linking), populate later. */
m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout));
}
oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n);
m->oneof_count = 0;
m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n);
@ -1433,7 +1661,7 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
}
static bool build_filedef(
const symtab_addctx *ctx, upb_filedef *file,
symtab_addctx *ctx, upb_filedef *file,
const google_protobuf_FileDescriptorProto *file_proto) {
upb_alloc *alloc = ctx->alloc;
const google_protobuf_FileOptions *file_options_proto;
@ -1547,7 +1775,7 @@ static bool build_filedef(
CHK(create_fielddef(ctx, file->package, NULL, exts[i]));
}
/* Now that all names are in the table, resolve references. */
/* Now that all names are in the table, build layouts and resolve refs. */
for (i = 0; i < file->ext_count; i++) {
CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]));
}
@ -1560,6 +1788,13 @@ static bool build_filedef(
}
}
if (!ctx->layouts) {
for (i = 0; i < file->msg_count; i++) {
const upb_msgdef *m = &file->msgs[i];
make_layout(ctx->symtab, m);
}
}
return true;
}
@ -1574,10 +1809,9 @@ static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx,
upb_strtable_begin(&iter, ctx->addtab);
for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
const char *key = upb_strtable_iter_key(&iter);
size_t keylen = upb_strtable_iter_keylength(&iter);
upb_strview key = upb_strtable_iter_key(&iter);
upb_value value = upb_strtable_iter_value(&iter);
CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc));
CHK_OOM(upb_strtable_insert3(&s->syms, key.data, key.size, value, alloc));
}
return true;
@ -1679,9 +1913,13 @@ const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name)
: NULL;
}
const upb_filedef *upb_symtab_addfile(
int upb_symtab_filecount(const upb_symtab *s) {
return upb_strtable_count(&s->files);
}
static const upb_filedef *_upb_symtab_addfile(
upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
upb_status *status) {
const upb_msglayout **layouts, upb_status *status) {
upb_arena *tmparena = upb_arena_new();
upb_strtable addtab;
upb_alloc *alloc = upb_arena_alloc(s->arena);
@ -1694,6 +1932,7 @@ const upb_filedef *upb_symtab_addfile(
ctx.alloc = alloc;
ctx.tmp = upb_arena_alloc(tmparena);
ctx.addtab = &addtab;
ctx.layouts = layouts;
ctx.status = status;
ok = file &&
@ -1705,6 +1944,12 @@ const upb_filedef *upb_symtab_addfile(
return ok ? file : NULL;
}
const upb_filedef *upb_symtab_addfile(
upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
upb_status *status) {
return _upb_symtab_addfile(s, file_proto, NULL, status);
}
/* Include here since we want most of this file to be stdio-free. */
#include <stdio.h>
@ -1740,7 +1985,7 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
goto err;
}
if (!upb_symtab_addfile(s, file, &status)) goto err;
if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err;
upb_arena_free(arena);
return true;

@ -123,6 +123,7 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f);
bool upb_fielddef_haspresence(const upb_fielddef *f);
const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f);
const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f);
const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f);
/* Internal only. */
uint32_t upb_fielddef_selectorbase(const upb_fielddef *f);
@ -425,6 +426,8 @@ const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
size_t len);
int upb_msgdef_numfields(const upb_msgdef *m);
int upb_msgdef_numoneofs(const upb_msgdef *m);
const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m);
const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i);
UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m,
const char *name) {
@ -851,9 +854,10 @@ const upb_filedef *upb_symtab_addfile(
/* For generated code only: loads a generated descriptor. */
typedef struct upb_def_init {
struct upb_def_init **deps;
struct upb_def_init **deps; /* Dependencies of this file. */
const upb_msglayout **layouts; /* Pre-order layouts of all messages. */
const char *filename;
upb_strview descriptor;
upb_strview descriptor; /* Serialized descriptor. */
} upb_def_init;
bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init);

@ -70,6 +70,7 @@ static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
/* Writes the given bytes to the buffer, handling reserve/advance. */
static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
if (len == 0) return true;
CHK(upb_encode_reserve(e, len));
memcpy(e->ptr, data, len);
return true;
@ -130,12 +131,89 @@ static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
size_t size) {
size_t bytes = arr->len * size;
return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes);
const void* data = _upb_array_constptr(arr);
return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes);
}
bool upb_encode_message(upb_encstate *e, const char *msg,
const upb_msglayout *m, size_t *size);
static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem,
const upb_msglayout *m,
const upb_msglayout_field *f,
bool skip_zero_value) {
const char *field_mem = _field_mem;
#define CASE(ctype, type, wire_type, encodeval) do { \
ctype val = *(ctype*)field_mem; \
if (skip_zero_value && val == 0) { \
return true; \
} \
return upb_put_ ## type(e, encodeval) && \
upb_put_tag(e, f->number, wire_type); \
} while(0)
switch (f->descriptortype) {
case UPB_DESCRIPTOR_TYPE_DOUBLE:
CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
case UPB_DESCRIPTOR_TYPE_FLOAT:
CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
case UPB_DESCRIPTOR_TYPE_INT64:
case UPB_DESCRIPTOR_TYPE_UINT64:
CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
case UPB_DESCRIPTOR_TYPE_UINT32:
CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_DESCRIPTOR_TYPE_ENUM:
CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
case UPB_DESCRIPTOR_TYPE_SFIXED64:
case UPB_DESCRIPTOR_TYPE_FIXED64:
CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
case UPB_DESCRIPTOR_TYPE_FIXED32:
case UPB_DESCRIPTOR_TYPE_SFIXED32:
CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
case UPB_DESCRIPTOR_TYPE_BOOL:
CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
case UPB_DESCRIPTOR_TYPE_SINT32:
CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
case UPB_DESCRIPTOR_TYPE_SINT64:
CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
case UPB_DESCRIPTOR_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES: {
upb_strview view = *(upb_strview*)field_mem;
if (skip_zero_value && view.size == 0) {
return true;
}
return upb_put_bytes(e, view.data, view.size) &&
upb_put_varint(e, view.size) &&
upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
}
case UPB_DESCRIPTOR_TYPE_GROUP: {
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
if (submsg == NULL) {
return true;
}
return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
upb_encode_message(e, submsg, subm, &size) &&
upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
}
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
if (submsg == NULL) {
return true;
}
return upb_encode_message(e, submsg, subm, &size) &&
upb_put_varint(e, size) &&
upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
}
}
#undef CASE
UPB_UNREACHABLE();
}
static bool upb_encode_array(upb_encstate *e, const char *field_mem,
const upb_msglayout *m,
const upb_msglayout_field *f) {
@ -146,8 +224,8 @@ static bool upb_encode_array(upb_encstate *e, const char *field_mem,
}
#define VARINT_CASE(ctype, encode) { \
ctype *start = arr->data; \
ctype *ptr = start + arr->len; \
const ctype *start = _upb_array_constptr(arr); \
const ctype *ptr = start + arr->len; \
size_t pre_len = e->limit - e->ptr; \
do { \
ptr--; \
@ -189,8 +267,8 @@ do { ; } while(0)
VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
case UPB_DESCRIPTOR_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES: {
upb_strview *start = arr->data;
upb_strview *ptr = start + arr->len;
const upb_strview *start = _upb_array_constptr(arr);
const upb_strview *ptr = start + arr->len;
do {
ptr--;
CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
@ -200,8 +278,8 @@ do { ; } while(0)
return true;
}
case UPB_DESCRIPTOR_TYPE_GROUP: {
void **start = arr->data;
void **ptr = start + arr->len;
const void *const*start = _upb_array_constptr(arr);
const void *const*ptr = start + arr->len;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
do {
size_t size;
@ -213,8 +291,8 @@ do { ; } while(0)
return true;
}
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
void **start = arr->data;
void **ptr = start + arr->len;
const void *const*start = _upb_array_constptr(arr);
const void *const*ptr = start + arr->len;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
do {
size_t size;
@ -234,81 +312,40 @@ do { ; } while(0)
return true;
}
static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
const upb_msglayout *m,
const upb_msglayout_field *f,
bool skip_zero_value) {
#define CASE(ctype, type, wire_type, encodeval) do { \
ctype val = *(ctype*)field_mem; \
if (skip_zero_value && val == 0) { \
return true; \
} \
return upb_put_ ## type(e, encodeval) && \
upb_put_tag(e, f->number, wire_type); \
} while(0)
static bool upb_encode_map(upb_encstate *e, const char *field_mem,
const upb_msglayout *m,
const upb_msglayout_field *f) {
const upb_map *map = *(const upb_map**)field_mem;
const upb_msglayout *entry = m->submsgs[f->submsg_index];
const upb_msglayout_field *key_field = &entry->fields[0];
const upb_msglayout_field *val_field = &entry->fields[1];
upb_strtable_iter i;
if (map == NULL) {
return true;
}
switch (f->descriptortype) {
case UPB_DESCRIPTOR_TYPE_DOUBLE:
CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
case UPB_DESCRIPTOR_TYPE_FLOAT:
CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
case UPB_DESCRIPTOR_TYPE_INT64:
case UPB_DESCRIPTOR_TYPE_UINT64:
CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
case UPB_DESCRIPTOR_TYPE_UINT32:
CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
case UPB_DESCRIPTOR_TYPE_INT32:
case UPB_DESCRIPTOR_TYPE_ENUM:
CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
case UPB_DESCRIPTOR_TYPE_SFIXED64:
case UPB_DESCRIPTOR_TYPE_FIXED64:
CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
case UPB_DESCRIPTOR_TYPE_FIXED32:
case UPB_DESCRIPTOR_TYPE_SFIXED32:
CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
case UPB_DESCRIPTOR_TYPE_BOOL:
CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
case UPB_DESCRIPTOR_TYPE_SINT32:
CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
case UPB_DESCRIPTOR_TYPE_SINT64:
CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
case UPB_DESCRIPTOR_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES: {
upb_strview view = *(upb_strview*)field_mem;
if (skip_zero_value && view.size == 0) {
return true;
}
return upb_put_bytes(e, view.data, view.size) &&
upb_put_varint(e, view.size) &&
upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
}
case UPB_DESCRIPTOR_TYPE_GROUP: {
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
if (submsg == NULL) {
return true;
}
return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
upb_encode_message(e, submsg, subm, &size) &&
upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
}
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
if (submsg == NULL) {
return true;
}
return upb_encode_message(e, submsg, subm, &size) &&
upb_put_varint(e, size) &&
upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
}
upb_strtable_begin(&i, &map->table);
for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
size_t pre_len = e->limit - e->ptr;
size_t size;
upb_strview key = upb_strtable_iter_key(&i);
const upb_value val = upb_strtable_iter_value(&i);
const void *keyp =
map->key_size == UPB_MAPTYPE_STRING ? (void *)&key : key.data;
const void *valp =
map->val_size == UPB_MAPTYPE_STRING ? upb_value_getptr(val) : &val;
CHK(upb_encode_scalarfield(e, valp, entry, val_field, false));
CHK(upb_encode_scalarfield(e, keyp, entry, key_field, false));
size = (e->limit - e->ptr) - pre_len;
CHK(upb_put_varint(e, size));
CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
}
#undef CASE
UPB_UNREACHABLE();
return true;
}
bool upb_encode_message(upb_encstate *e, const char *msg,
const upb_msglayout *m, size_t *size) {
int i;
@ -316,11 +353,19 @@ bool upb_encode_message(upb_encstate *e, const char *msg,
const char *unknown;
size_t unknown_size;
unknown = upb_msg_getunknown(msg, &unknown_size);
if (unknown) {
upb_put_bytes(e, unknown, unknown_size);
}
for (i = m->field_count - 1; i >= 0; i--) {
const upb_msglayout_field *f = &m->fields[i];
if (f->label == UPB_LABEL_REPEATED) {
CHK(upb_encode_array(e, msg + f->offset, m, f));
} else if (f->label == UPB_LABEL_MAP) {
CHK(upb_encode_map(e, msg + f->offset, m, f));
} else {
bool skip_empty = false;
if (f->presence == 0) {
@ -341,12 +386,6 @@ bool upb_encode_message(upb_encstate *e, const char *msg,
}
}
unknown = upb_msg_getunknown(msg, &unknown_size);
if (unknown) {
upb_put_bytes(e, unknown, unknown_size);
}
*size = (e->limit - e->ptr) - pre_len;
return true;
}

@ -1,105 +0,0 @@
/*
** Functions for use by generated code. These are not public and users must
** not call them directly.
*/
#ifndef UPB_GENERATED_UTIL_H_
#define UPB_GENERATED_UTIL_H_
#include <stdint.h>
#include "upb/msg.h"
#include "upb/port_def.inc"
#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs)
UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs,
size_t *size) {
const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*);
if (arr) {
if (size) *size = arr->len;
return arr->data;
} else {
if (size) *size = 0;
return NULL;
}
}
UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs,
size_t *size) {
upb_array *arr = *PTR_AT(msg, ofs, upb_array*);
if (arr) {
if (size) *size = arr->len;
return arr->data;
} else {
if (size) *size = 0;
return NULL;
}
}
/* TODO(haberman): this is a mess. It will improve when upb_array no longer
* carries reflective state (type, elem_size). */
UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size,
size_t elem_size,
upb_fieldtype_t type,
upb_arena *arena) {
upb_array *arr = *PTR_AT(msg, ofs, upb_array*);
if (!arr) {
arr = upb_array_new(arena);
if (!arr) return NULL;
*PTR_AT(msg, ofs, upb_array*) = arr;
}
if (size > arr->size) {
size_t new_size = UPB_MAX(arr->size, 4);
size_t old_bytes = arr->size * elem_size;
size_t new_bytes;
while (new_size < size) new_size *= 2;
new_bytes = new_size * elem_size;
arr->data = upb_arena_realloc(arena, arr->data, old_bytes, new_bytes);
if (!arr->data) {
return NULL;
}
arr->size = new_size;
}
arr->len = size;
return arr->data;
}
UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs,
size_t elem_size,
upb_fieldtype_t type,
const void *value,
upb_arena *arena) {
upb_array *arr = *PTR_AT(msg, ofs, upb_array*);
size_t i = arr ? arr->len : 0;
void *data =
_upb_array_resize_accessor(msg, ofs, i + 1, elem_size, type, arena);
if (!data) return false;
memcpy(PTR_AT(data, i * elem_size, char), value, elem_size);
return true;
}
UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) {
return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0;
}
UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) {
return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8));
}
UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) {
return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8)));
}
UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) {
return *PTR_AT(msg, case_ofs, int32_t) == num;
}
#undef PTR_AT
#include "upb/port_undef.inc"
#endif /* UPB_GENERATED_UTIL_H_ */

@ -389,7 +389,7 @@ static upb_selector_t getsel_for_handlertype(upb_json_parser *p,
upb_handlertype_t type) {
upb_selector_t sel;
bool ok = upb_handlers_getselector(p->top->f, type, &sel);
UPB_ASSERT(ok);
UPB_ASSUME(ok);
return sel;
}
@ -414,7 +414,7 @@ static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) {
const upb_json_parsermethod *method;
ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v);
UPB_ASSERT(ok);
UPB_ASSUME(ok);
method = upb_value_getconstptr(v);
frame->name_table = &method->name_table;
@ -2019,7 +2019,7 @@ static void end_member(upb_json_parser *p) {
/* send ENDSUBMSG in repeated-field-of-mapentries frame. */
p->top--;
ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel);
UPB_ASSERT(ok);
UPB_ASSUME(ok);
upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel);
}

@ -6,6 +6,7 @@
#include "upb/json/printer.h"
#include <ctype.h>
#include <inttypes.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
@ -208,28 +209,26 @@ static size_t fmt_bool(bool val, char* buf, size_t length) {
return n;
}
static size_t fmt_int64_as_number(long long val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "%lld", val);
static size_t fmt_int64_as_number(int64_t val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "%" PRId64, val);
CHKLENGTH(n > 0 && n < length);
return n;
}
static size_t fmt_uint64_as_number(
unsigned long long val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "%llu", val);
static size_t fmt_uint64_as_number(uint64_t val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "%" PRIu64, val);
CHKLENGTH(n > 0 && n < length);
return n;
}
static size_t fmt_int64_as_string(long long val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "\"%lld\"", val);
static size_t fmt_int64_as_string(int64_t val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "\"%" PRId64 "\"", val);
CHKLENGTH(n > 0 && n < length);
return n;
}
static size_t fmt_uint64_as_string(
unsigned long long val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "\"%llu\"", val);
static size_t fmt_uint64_as_string(uint64_t val, char* buf, size_t length) {
size_t n = _upb_snprintf(buf, length, "\"%" PRIu64 "\"", val);
CHKLENGTH(n > 0 && n < length);
return n;
}

@ -1,399 +0,0 @@
#include "upb/legacy_msg_reflection.h"
#include <string.h>
#include "upb/table.int.h"
#include "upb/msg.h"
#include "upb/port_def.inc"
bool upb_fieldtype_mapkeyok(upb_fieldtype_t type) {
return type == UPB_TYPE_BOOL || type == UPB_TYPE_INT32 ||
type == UPB_TYPE_UINT32 || type == UPB_TYPE_INT64 ||
type == UPB_TYPE_UINT64 || type == UPB_TYPE_STRING;
}
#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
#define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
#define ENCODE_MAX_NESTING 64
#define CHECK_TRUE(x) if (!(x)) { return false; }
/** upb_msgval ****************************************************************/
/* These functions will generate real memcpy() calls on ARM sadly, because
* the compiler assumes they might not be aligned. */
static upb_msgval upb_msgval_read(const void *p, size_t ofs,
uint8_t size) {
upb_msgval val;
p = (char*)p + ofs;
memcpy(&val, p, size);
return val;
}
static void upb_msgval_write(void *p, size_t ofs, upb_msgval val,
uint8_t size) {
p = (char*)p + ofs;
memcpy(p, &val, size);
}
static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
switch (type) {
case UPB_TYPE_DOUBLE:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
return 8;
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_FLOAT:
return 4;
case UPB_TYPE_BOOL:
return 1;
case UPB_TYPE_MESSAGE:
return sizeof(void*);
case UPB_TYPE_BYTES:
case UPB_TYPE_STRING:
return sizeof(upb_strview);
}
UPB_UNREACHABLE();
}
static uint8_t upb_msg_fieldsize(const upb_msglayout_field *field) {
if (field->label == UPB_LABEL_REPEATED) {
return sizeof(void*);
} else {
return upb_msgval_sizeof(upb_desctype_to_fieldtype[field->descriptortype]);
}
}
/* TODO(haberman): this is broken right now because upb_msgval can contain
* a char* / size_t pair, which is too big for a upb_value. To fix this
* we'll probably need to dynamically allocate a upb_msgval and store a
* pointer to that in the tables for extensions/maps. */
static upb_value upb_toval(upb_msgval val) {
upb_value ret;
UPB_UNUSED(val);
memset(&ret, 0, sizeof(upb_value)); /* XXX */
return ret;
}
static upb_msgval upb_msgval_fromval(upb_value val) {
upb_msgval ret;
UPB_UNUSED(val);
memset(&ret, 0, sizeof(upb_msgval)); /* XXX */
return ret;
}
static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type) {
switch (type) {
case UPB_TYPE_FLOAT: return UPB_CTYPE_FLOAT;
case UPB_TYPE_DOUBLE: return UPB_CTYPE_DOUBLE;
case UPB_TYPE_BOOL: return UPB_CTYPE_BOOL;
case UPB_TYPE_BYTES:
case UPB_TYPE_MESSAGE:
case UPB_TYPE_STRING: return UPB_CTYPE_CONSTPTR;
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32: return UPB_CTYPE_INT32;
case UPB_TYPE_UINT32: return UPB_CTYPE_UINT32;
case UPB_TYPE_INT64: return UPB_CTYPE_INT64;
case UPB_TYPE_UINT64: return UPB_CTYPE_UINT64;
default: UPB_ASSERT(false); return 0;
}
}
/** upb_msg *******************************************************************/
/* If we always read/write as a consistent type to each address, this shouldn't
* violate aliasing.
*/
#define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
static const upb_msglayout_field *upb_msg_checkfield(int field_index,
const upb_msglayout *l) {
UPB_ASSERT(field_index >= 0 && field_index < l->field_count);
return &l->fields[field_index];
}
static bool upb_msg_inoneof(const upb_msglayout_field *field) {
return field->presence < 0;
}
static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
const upb_msglayout *l) {
const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
UPB_ASSERT(upb_msg_inoneof(field));
return PTR_AT(msg, ~field->presence, uint32_t);
}
bool upb_msg_has(const upb_msg *msg,
int field_index,
const upb_msglayout *l) {
const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
UPB_ASSERT(field->presence);
if (upb_msg_inoneof(field)) {
/* Oneofs are set when the oneof number is set to this field. */
return *upb_msg_oneofcase(msg, field_index, l) == field->number;
} else {
/* Other fields are set when their hasbit is set. */
uint32_t hasbit = field->presence;
return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
}
}
upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
const upb_msglayout *l) {
const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
int size = upb_msg_fieldsize(field);
return upb_msgval_read(msg, field->offset, size);
}
void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
const upb_msglayout *l) {
const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
int size = upb_msg_fieldsize(field);
upb_msgval_write(msg, field->offset, val, size);
}
/** upb_array *****************************************************************/
#define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
size_t upb_array_size(const upb_array *arr) {
return arr->len;
}
upb_msgval upb_array_get(const upb_array *arr, upb_fieldtype_t type, size_t i) {
size_t element_size = upb_msgval_sizeof(type);
UPB_ASSERT(i < arr->len);
return upb_msgval_read(arr->data, i * element_size, element_size);
}
bool upb_array_set(upb_array *arr, upb_fieldtype_t type, size_t i,
upb_msgval val, upb_arena *arena) {
size_t element_size = upb_msgval_sizeof(type);
UPB_ASSERT(i <= arr->len);
if (i == arr->len) {
/* Extending the array. */
if (i == arr->size) {
/* Need to reallocate. */
size_t new_size = UPB_MAX(arr->size * 2, 8);
size_t new_bytes = new_size * element_size;
size_t old_bytes = arr->size * element_size;
upb_alloc *alloc = upb_arena_alloc(arena);
upb_msgval *new_data =
upb_realloc(alloc, arr->data, old_bytes, new_bytes);
if (!new_data) {
return false;
}
arr->data = new_data;
arr->size = new_size;
}
arr->len = i + 1;
}
upb_msgval_write(arr->data, i * element_size, val, element_size);
return true;
}
/** upb_map *******************************************************************/
struct upb_map {
upb_fieldtype_t key_type;
upb_fieldtype_t val_type;
/* We may want to optimize this to use inttable where possible, for greater
* efficiency and lower memory footprint. */
upb_strtable strtab;
upb_arena *arena;
};
static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
const char **out_key, size_t *out_len) {
switch (type) {
case UPB_TYPE_STRING:
/* Point to string data of the input key. */
*out_key = key->str.data;
*out_len = key->str.size;
return;
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
/* Point to the key itself. XXX: big-endian. */
*out_key = (const char*)key;
*out_len = upb_msgval_sizeof(type);
return;
case UPB_TYPE_BYTES:
case UPB_TYPE_DOUBLE:
case UPB_TYPE_ENUM:
case UPB_TYPE_FLOAT:
case UPB_TYPE_MESSAGE:
break; /* Cannot be a map key. */
}
UPB_UNREACHABLE();
}
static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
size_t len) {
switch (type) {
case UPB_TYPE_STRING:
return upb_msgval_makestr(key, len);
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
return upb_msgval_read(key, 0, upb_msgval_sizeof(type));
case UPB_TYPE_BYTES:
case UPB_TYPE_DOUBLE:
case UPB_TYPE_ENUM:
case UPB_TYPE_FLOAT:
case UPB_TYPE_MESSAGE:
break; /* Cannot be a map key. */
}
UPB_UNREACHABLE();
}
upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype,
upb_arena *a) {
upb_ctype_t vtabtype = upb_fieldtotabtype(vtype);
upb_alloc *alloc = upb_arena_alloc(a);
upb_map *map = upb_malloc(alloc, sizeof(upb_map));
if (!map) {
return NULL;
}
UPB_ASSERT(upb_fieldtype_mapkeyok(ktype));
map->key_type = ktype;
map->val_type = vtype;
map->arena = a;
if (!upb_strtable_init2(&map->strtab, vtabtype, alloc)) {
return NULL;
}
return map;
}
size_t upb_map_size(const upb_map *map) {
return upb_strtable_count(&map->strtab);
}
upb_fieldtype_t upb_map_keytype(const upb_map *map) {
return map->key_type;
}
upb_fieldtype_t upb_map_valuetype(const upb_map *map) {
return map->val_type;
}
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
upb_value tabval;
const char *key_str;
size_t key_len;
bool ret;
upb_map_tokey(map->key_type, &key, &key_str, &key_len);
ret = upb_strtable_lookup2(&map->strtab, key_str, key_len, &tabval);
if (ret) {
memcpy(val, &tabval, sizeof(tabval));
}
return ret;
}
bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
upb_msgval *removed) {
const char *key_str;
size_t key_len;
upb_value tabval = upb_toval(val);
upb_value removedtabval;
upb_alloc *a = upb_arena_alloc(map->arena);
upb_map_tokey(map->key_type, &key, &key_str, &key_len);
/* TODO(haberman): add overwrite operation to minimize number of lookups. */
if (upb_strtable_lookup2(&map->strtab, key_str, key_len, NULL)) {
upb_strtable_remove3(&map->strtab, key_str, key_len, &removedtabval, a);
memcpy(&removed, &removedtabval, sizeof(removed));
}
return upb_strtable_insert3(&map->strtab, key_str, key_len, tabval, a);
}
bool upb_map_del(upb_map *map, upb_msgval key) {
const char *key_str;
size_t key_len;
upb_alloc *a = upb_arena_alloc(map->arena);
upb_map_tokey(map->key_type, &key, &key_str, &key_len);
return upb_strtable_remove3(&map->strtab, key_str, key_len, NULL, a);
}
/** upb_mapiter ***************************************************************/
struct upb_mapiter {
upb_strtable_iter iter;
upb_fieldtype_t key_type;
};
size_t upb_mapiter_sizeof(void) {
return sizeof(upb_mapiter);
}
void upb_mapiter_begin(upb_mapiter *i, const upb_map *map) {
upb_strtable_begin(&i->iter, &map->strtab);
i->key_type = map->key_type;
}
upb_mapiter *upb_mapiter_new(const upb_map *t, upb_alloc *a) {
upb_mapiter *ret = upb_malloc(a, upb_mapiter_sizeof());
if (!ret) {
return NULL;
}
upb_mapiter_begin(ret, t);
return ret;
}
void upb_mapiter_free(upb_mapiter *i, upb_alloc *a) {
upb_free(a, i);
}
void upb_mapiter_next(upb_mapiter *i) {
upb_strtable_next(&i->iter);
}
bool upb_mapiter_done(const upb_mapiter *i) {
return upb_strtable_done(&i->iter);
}
upb_msgval upb_mapiter_key(const upb_mapiter *i) {
return upb_map_fromkey(i->key_type, upb_strtable_iter_key(&i->iter),
upb_strtable_iter_keylength(&i->iter));
}
upb_msgval upb_mapiter_value(const upb_mapiter *i) {
return upb_msgval_fromval(upb_strtable_iter_value(&i->iter));
}
void upb_mapiter_setdone(upb_mapiter *i) {
upb_strtable_iter_setdone(&i->iter);
}
bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2) {
return upb_strtable_iter_isequal(&i1->iter, &i2->iter);
}

@ -1,191 +0,0 @@
#ifndef UPB_LEGACY_MSG_REFLECTION_H_
#define UPB_LEGACY_MSG_REFLECTION_H_
#include "upb/upb.h"
#include "upb/msg.h"
#include "upb/port_def.inc"
struct upb_map;
typedef struct upb_map upb_map;
struct upb_mapiter;
typedef struct upb_mapiter upb_mapiter;
/** upb_msgval ****************************************************************/
/* A union representing all possible protobuf values. Used for generic get/set
* operations. */
typedef union {
bool b;
float flt;
double dbl;
int32_t i32;
int64_t i64;
uint32_t u32;
uint64_t u64;
const upb_map* map;
const upb_msg* msg;
const upb_array* arr;
const void* ptr;
upb_strview str;
} upb_msgval;
#define ACCESSORS(name, membername, ctype) \
UPB_INLINE ctype upb_msgval_get ## name(upb_msgval v) { \
return v.membername; \
} \
UPB_INLINE void upb_msgval_set ## name(upb_msgval *v, ctype cval) { \
v->membername = cval; \
} \
UPB_INLINE upb_msgval upb_msgval_ ## name(ctype v) { \
upb_msgval ret; \
ret.membername = v; \
return ret; \
}
ACCESSORS(bool, b, bool)
ACCESSORS(float, flt, float)
ACCESSORS(double, dbl, double)
ACCESSORS(int32, i32, int32_t)
ACCESSORS(int64, i64, int64_t)
ACCESSORS(uint32, u32, uint32_t)
ACCESSORS(uint64, u64, uint64_t)
ACCESSORS(map, map, const upb_map*)
ACCESSORS(msg, msg, const upb_msg*)
ACCESSORS(ptr, ptr, const void*)
ACCESSORS(arr, arr, const upb_array*)
ACCESSORS(str, str, upb_strview)
#undef ACCESSORS
UPB_INLINE upb_msgval upb_msgval_makestr(const char *data, size_t size) {
return upb_msgval_str(upb_strview_make(data, size));
}
/** upb_msg *******************************************************************/
/* A upb_msg represents a protobuf message. It always corresponds to a specific
* upb_msglayout, which describes how it is laid out in memory. */
/* Read-only message API. Can be safely called by anyone. */
/* Returns the value associated with this field:
* - for scalar fields (including strings), the value directly.
* - return upb_msg*, or upb_map* for msg/map.
* If the field is unset for these field types, returns NULL.
*
* TODO(haberman): should we let users store cached array/map/msg
* pointers here for fields that are unset? Could be useful for the
* strongly-owned submessage model (ie. generated C API that doesn't use
* arenas).
*/
upb_msgval upb_msg_get(const upb_msg *msg,
int field_index,
const upb_msglayout *l);
/* May only be called for fields where upb_fielddef_haspresence(f) == true. */
bool upb_msg_has(const upb_msg *msg,
int field_index,
const upb_msglayout *l);
/* Mutable message API. May only be called by the owner of the message who
* knows its ownership scheme and how to keep it consistent. */
/* Sets the given field to the given value. Does not perform any memory
* management: if you overwrite a pointer to a msg/array/map/string without
* cleaning it up (or using an arena) it will leak.
*/
void upb_msg_set(upb_msg *msg,
int field_index,
upb_msgval val,
const upb_msglayout *l);
/* For a primitive field, set it back to its default. For repeated, string, and
* submessage fields set it back to NULL. This could involve releasing some
* internal memory (for example, from an extension dictionary), but it is not
* recursive in any way and will not recover any memory that may be used by
* arrays/maps/strings/msgs that this field may have pointed to.
*/
bool upb_msg_clearfield(upb_msg *msg,
int field_index,
const upb_msglayout *l);
/* TODO(haberman): copyfrom()/mergefrom()? */
/** upb_array *****************************************************************/
/* A upb_array stores data for a repeated field. The memory management
* semantics are the same as upb_msg. A upb_array allocates dynamic
* memory internally for the array elements. */
upb_fieldtype_t upb_array_type(const upb_array *arr);
/* Read-only interface. Safe for anyone to call. */
size_t upb_array_size(const upb_array *arr);
upb_msgval upb_array_get(const upb_array *arr, upb_fieldtype_t type, size_t i);
/* Write interface. May only be called by the message's owner who can enforce
* its memory management invariants. */
bool upb_array_set(upb_array *arr, upb_fieldtype_t type, size_t i,
upb_msgval val, upb_arena *arena);
/** upb_map *******************************************************************/
/* A upb_map stores data for a map field. The memory management semantics are
* the same as upb_msg, with one notable exception. upb_map will internally
* store a copy of all string keys, but *not* any string values or submessages.
* So you must ensure that any string or message values outlive the map, and you
* must delete them manually when they are no longer required. */
upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype,
upb_arena *a);
/* Read-only interface. Safe for anyone to call. */
size_t upb_map_size(const upb_map *map);
upb_fieldtype_t upb_map_keytype(const upb_map *map);
upb_fieldtype_t upb_map_valuetype(const upb_map *map);
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val);
/* Write interface. May only be called by the message's owner who can enforce
* its memory management invariants. */
/* Sets or overwrites an entry in the map. Return value indicates whether
* the operation succeeded or failed with OOM, and also whether an existing
* key was replaced or not. */
bool upb_map_set(upb_map *map,
upb_msgval key, upb_msgval val,
upb_msgval *valremoved);
/* Deletes an entry in the map. Returns true if the key was present. */
bool upb_map_del(upb_map *map, upb_msgval key);
/** upb_mapiter ***************************************************************/
/* For iterating over a map. Map iterators are invalidated by mutations to the
* map, but an invalidated iterator will never return junk or crash the process.
* An invalidated iterator may return entries that were already returned though,
* and if you keep invalidating the iterator during iteration, the program may
* enter an infinite loop. */
size_t upb_mapiter_sizeof(void);
void upb_mapiter_begin(upb_mapiter *i, const upb_map *t);
upb_mapiter *upb_mapiter_new(const upb_map *t, upb_alloc *a);
void upb_mapiter_free(upb_mapiter *i, upb_alloc *a);
void upb_mapiter_next(upb_mapiter *i);
bool upb_mapiter_done(const upb_mapiter *i);
upb_msgval upb_mapiter_key(const upb_mapiter *i);
upb_msgval upb_mapiter_value(const upb_mapiter *i);
void upb_mapiter_setdone(upb_mapiter *i);
bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2);
#include "upb/port_undef.inc"
#endif /* UPB_LEGACY_MSG_REFLECTION_H_ */

@ -7,22 +7,27 @@
#define VOIDPTR_AT(msg, ofs) (void*)((char*)msg + (int)ofs)
/* Internal members of a upb_msg. We can change this without breaking binary
* compatibility. We put these before the user's data. The user's upb_msg*
* points after the upb_msg_internal. */
/* Used when a message is not extendable. */
typedef struct {
char *unknown;
size_t unknown_len;
size_t unknown_size;
} upb_msg_internal;
/* Used when a message is extendable. */
typedef struct {
upb_inttable *extdict;
upb_msg_internal base;
} upb_msg_internal_withext;
/** upb_msg *******************************************************************/
static char _upb_fieldtype_to_sizelg2[12] = {
0,
0, /* UPB_TYPE_BOOL */
2, /* UPB_TYPE_FLOAT */
2, /* UPB_TYPE_INT32 */
2, /* UPB_TYPE_UINT32 */
2, /* UPB_TYPE_ENUM */
UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */
3, /* UPB_TYPE_DOUBLE */
3, /* UPB_TYPE_INT64 */
3, /* UPB_TYPE_UINT64 */
UPB_SIZE(3, 4), /* UPB_TYPE_STRING */
UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */
};
static uintptr_t tag_arrptr(void* ptr, int elem_size_lg2) {
UPB_ASSERT(elem_size_lg2 <= 4);
return (uintptr_t)ptr | elem_size_lg2;
}
static int upb_msg_internalsize(const upb_msglayout *l) {
return sizeof(upb_msg_internal) - l->extendable * sizeof(void *);
@ -46,7 +51,7 @@ static upb_msg_internal_withext *upb_msg_getinternalwithext(
return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
}
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) {
upb_alloc *alloc = upb_arena_alloc(a);
void *mem = upb_malloc(alloc, upb_msg_sizeof(l));
upb_msg_internal *in;
@ -74,20 +79,6 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
return msg;
}
upb_array *upb_array_new(upb_arena *a) {
upb_array *ret = upb_arena_malloc(a, sizeof(upb_array));
if (!ret) {
return NULL;
}
ret->data = NULL;
ret->len = 0;
ret->size = 0;
return ret;
}
void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
upb_arena *arena) {
upb_msg_internal *in = upb_msg_getinternal(msg);
@ -103,9 +94,103 @@ void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
}
const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
const upb_msg_internal* in = upb_msg_getinternal_const(msg);
const upb_msg_internal *in = upb_msg_getinternal_const(msg);
*len = in->unknown_len;
return in->unknown;
}
/** upb_array *****************************************************************/
upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type) {
upb_array *arr = upb_arena_malloc(a, sizeof(upb_array));
if (!arr) {
return NULL;
}
arr->data = tag_arrptr(NULL, _upb_fieldtype_to_sizelg2[type]);
arr->len = 0;
arr->size = 0;
return arr;
}
bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
size_t new_size = UPB_MAX(arr->size, 4);
int elem_size_lg2 = arr->data & 7;
size_t old_bytes = arr->size << elem_size_lg2;
size_t new_bytes;
void* ptr = _upb_array_ptr(arr);
/* Log2 ceiling of size. */
while (new_size < min_size) new_size *= 2;
new_bytes = new_size << elem_size_lg2;
ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes);
if (!ptr) {
return false;
}
arr->data = tag_arrptr(ptr, elem_size_lg2);
arr->size = new_size;
return true;
}
static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type,
upb_arena *arena) {
upb_array *arr = *arr_ptr;
if (!arr) {
arr = _upb_array_new(arena, type);
if (!arr) return NULL;
*arr_ptr = arr;
}
return arr;
}
static bool resize_array(upb_array *arr, size_t size, upb_arena *arena) {
if (size > arr->size && !_upb_array_realloc(arr, size, arena)) {
return false;
}
arr->len = size;
return true;
}
void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
upb_fieldtype_t type, upb_arena *arena) {
upb_array *arr = getorcreate_array(arr_ptr, type, arena);
return arr && resize_array(arr, size, arena) ? _upb_array_ptr(arr) : NULL;
}
bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
upb_fieldtype_t type, upb_arena *arena) {
upb_array *arr = getorcreate_array(arr_ptr, type, arena);
size_t elem = arr->len;
int lg2 = _upb_fieldtype_to_sizelg2[type];
char *data;
if (!arr || !resize_array(arr, elem + 1, arena)) return false;
data = _upb_array_ptr(arr);
memcpy(data + (elem << lg2), value, 1 << lg2);
return true;
}
/** upb_map *******************************************************************/
upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
upb_map *map = upb_arena_malloc(a, sizeof(upb_map));
if (!map) {
return NULL;
}
upb_strtable_init2(&map->table, UPB_CTYPE_INT32, upb_arena_alloc(a));
map->key_size = key_size;
map->val_size = value_size;
return map;
}
#undef VOIDPTR_AT

@ -1,7 +1,6 @@
/*
** Data structures for message tables, used for parsing and serialization.
** This are much lighter-weight than full reflection, but they are do not
** have enough information to convert to text format, JSON, etc.
** Our memory representation for parsing tables and messages themselves.
** Functions in this file are used by generated code and possibly reflection.
**
** The definitions in this file are internal to upb.
**/
@ -11,12 +10,18 @@
#include <stdint.h>
#include <string.h>
#include "upb/table.int.h"
#include "upb/upb.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs)
typedef void upb_msg;
/** upb_msglayout *************************************************************/
@ -25,6 +30,12 @@ typedef void upb_msg;
* members are public so generated code can initialize them, but users MUST NOT
* read or write any of its members. */
/* This isn't a real label according to descriptor.proto, but in the table we
* use this for map fields instead of UPB_LABEL_REPEATED. */
enum {
UPB_LABEL_MAP = 4
};
typedef struct {
uint32_t number;
uint16_t offset;
@ -44,26 +55,344 @@ typedef struct upb_msglayout {
bool extendable;
} upb_msglayout;
/** Message internal representation *******************************************/
/** upb_msg *******************************************************************/
/* Our internal representation for repeated fields. */
/* Internal members of a upb_msg. We can change this without breaking binary
* compatibility. We put these before the user's data. The user's upb_msg*
* points after the upb_msg_internal. */
/* Used when a message is not extendable. */
typedef struct {
void *data; /* Each element is element_size. */
size_t len; /* Measured in elements. */
size_t size; /* Measured in elements. */
} upb_array;
char *unknown;
size_t unknown_len;
size_t unknown_size;
} upb_msg_internal;
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
/* Used when a message is extendable. */
typedef struct {
upb_inttable *extdict;
upb_msg_internal base;
} upb_msg_internal_withext;
/* Maps upb_fieldtype_t -> memory size. */
extern char _upb_fieldtype_to_size[12];
/* Creates a new messages with the given layout on the given arena. */
upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a);
/* Adds unknown data (serialized protobuf data) to the given message. The data
* is copied into the message instance. */
void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
upb_arena *arena);
/* Returns a reference to the message's unknown data. */
const char *upb_msg_getunknown(const upb_msg *msg, size_t *len);
upb_array *upb_array_new(upb_arena *a);
UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) {
return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0;
}
UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) {
return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8));
}
UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) {
return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8)));
}
UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) {
return *PTR_AT(msg, case_ofs, int32_t) == num;
}
/** upb_array *****************************************************************/
/* Our internal representation for repeated fields. */
typedef struct {
uintptr_t data; /* Tagged ptr: low 2 bits of ptr are lg2(elem size). */
size_t len; /* Measured in elements. */
size_t size; /* Measured in elements. */
} upb_array;
UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) {
return (void*)((uintptr_t)arr->data & ~7UL);
}
UPB_INLINE void *_upb_array_ptr(upb_array *arr) {
return (void*)_upb_array_constptr(arr);
}
/* Creates a new array on the given arena. */
upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type);
/* Resizes the capacity of the array to be at least min_size. */
bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena);
/* Fallback functions for when the accessors require a resize. */
void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
upb_fieldtype_t type, upb_arena *arena);
bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
upb_fieldtype_t type, upb_arena *arena);
UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs,
size_t *size) {
const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*);
if (arr) {
if (size) *size = arr->len;
return _upb_array_constptr(arr);
} else {
if (size) *size = 0;
return NULL;
}
}
UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs,
size_t *size) {
upb_array *arr = *PTR_AT(msg, ofs, upb_array*);
if (arr) {
if (size) *size = arr->len;
return _upb_array_ptr(arr);
} else {
if (size) *size = 0;
return NULL;
}
}
UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size,
upb_fieldtype_t type,
upb_arena *arena) {
upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*);
upb_array *arr = *arr_ptr;
if (!arr || arr->size < size) {
return _upb_array_resize_fallback(arr_ptr, size, type, arena);
}
arr->len = size;
return _upb_array_ptr(arr);
}
UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs,
size_t elem_size,
upb_fieldtype_t type,
const void *value,
upb_arena *arena) {
upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*);
upb_array *arr = *arr_ptr;
void* ptr;
if (!arr || arr->len == arr->size) {
return _upb_array_append_fallback(arr_ptr, value, type, arena);
}
ptr = _upb_array_ptr(arr);
memcpy(PTR_AT(ptr, arr->len * elem_size, char), value, elem_size);
arr->len++;
return true;
}
/** upb_map *******************************************************************/
/* Right now we use strmaps for everything. We'll likely want to use
* integer-specific maps for integer-keyed maps.*/
typedef struct {
/* Size of key and val, based on the map type. Strings are represented as '0'
* because they must be handled specially. */
char key_size;
char val_size;
upb_strtable table;
} upb_map;
/* Map entries aren't actually stored, they are only used during parsing. For
* parsing, it helps a lot if all map entry messages have the same layout.
* The compiler and def.c must ensure that all map entries have this layout. */
typedef struct {
upb_msg_internal internal;
union {
upb_strview str; /* For str/bytes. */
upb_value val; /* For all other types. */
} k;
union {
upb_strview str; /* For str/bytes. */
upb_value val; /* For all other types. */
} v;
} upb_map_entry;
/* Creates a new map on the given arena with this key/value type. */
upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size);
/* Converting between internal table representation and user values.
*
* _upb_map_tokey() and _upb_map_fromkey() are inverses.
* _upb_map_tovalue() and _upb_map_fromvalue() are inverses.
*
* These functions account for the fact that strings are treated differently
* from other types when stored in a map.
*/
UPB_INLINE upb_strview _upb_map_tokey(const void *key, size_t size) {
if (size == UPB_MAPTYPE_STRING) {
return *(upb_strview*)key;
} else {
return upb_strview_make((const char*)key, size);
}
}
UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) {
if (size == UPB_MAPTYPE_STRING) {
memcpy(out, &key, sizeof(key));
} else {
memcpy(out, key.data, size);
}
}
UPB_INLINE upb_value _upb_map_tovalue(const void *val, size_t size,
upb_arena *a) {
upb_value ret = {0};
if (size == UPB_MAPTYPE_STRING) {
upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp));
*strp = *(upb_strview*)val;
memcpy(&ret, &strp, sizeof(strp));
} else {
memcpy(&ret, val, size);
}
return ret;
}
UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) {
if (size == UPB_MAPTYPE_STRING) {
const upb_strview *strp = (const upb_strview*)upb_value_getptr(val);
memcpy(out, strp, sizeof(upb_strview));
} else {
memcpy(out, &val, size);
}
}
/* Map operations, shared by reflection and generated code. */
UPB_INLINE size_t _upb_map_size(const upb_map *map) {
return map->table.t.count;
}
UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key,
size_t key_size, void *val, size_t val_size) {
upb_value tabval;
upb_strview k = _upb_map_tokey(key, key_size);
bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval);
if (ret) {
_upb_map_fromvalue(tabval, val, val_size);
}
return ret;
}
UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) {
upb_strtable_iter it;
it.t = &map->table;
it.index = *iter;
upb_strtable_next(&it);
if (upb_strtable_done(&it)) return NULL;
*iter = it.index;
return (void*)str_tabent(&it);
}
UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size,
void *val, size_t val_size, upb_arena *arena) {
upb_strview strkey = _upb_map_tokey(key, key_size);
upb_value tabval = _upb_map_tovalue(val, val_size, arena);
upb_alloc *a = upb_arena_alloc(arena);
/* TODO(haberman): add overwrite operation to minimize number of lookups. */
upb_strtable_remove3(&map->table, strkey.data, strkey.size, NULL, a);
return upb_strtable_insert3(&map->table, strkey.data, strkey.size, tabval, a);
}
UPB_INLINE bool _upb_map_delete(upb_map *map, const void *key, size_t key_size) {
upb_strview k = _upb_map_tokey(key, key_size);
return upb_strtable_remove3(&map->table, k.data, k.size, NULL, NULL);
}
UPB_INLINE void _upb_map_clear(upb_map *map) {
upb_strtable_clear(&map->table);
}
/* Message map operations, these get the map from the message first. */
UPB_INLINE size_t _upb_msg_map_size(const upb_msg *msg, size_t ofs) {
upb_map *map = UPB_FIELD_AT(msg, upb_map *, ofs);
return map ? _upb_map_size(map) : 0;
}
UPB_INLINE bool _upb_msg_map_get(const upb_msg *msg, size_t ofs,
const void *key, size_t key_size, void *val,
size_t val_size) {
upb_map *map = UPB_FIELD_AT(msg, upb_map *, ofs);
if (!map) return false;
return _upb_map_get(map, key, key_size, val, val_size);
}
UPB_INLINE void *_upb_msg_map_next(const upb_msg *msg, size_t ofs,
size_t *iter) {
upb_map *map = UPB_FIELD_AT(msg, upb_map *, ofs);
if (!map) return NULL;
return _upb_map_next(map, iter);
}
UPB_INLINE bool _upb_msg_map_set(upb_msg *msg, size_t ofs, const void *key,
size_t key_size, void *val, size_t val_size,
upb_arena *arena) {
upb_map **map = PTR_AT(msg, ofs, upb_map *);
if (!*map) {
*map = _upb_map_new(arena, key_size, val_size);
}
return _upb_map_set(*map, key, key_size, val, val_size, arena);
}
UPB_INLINE bool _upb_msg_map_delete(upb_msg *msg, size_t ofs, const void *key,
size_t key_size) {
upb_map *map = UPB_FIELD_AT(msg, upb_map *, ofs);
if (!map) return false;
return _upb_map_delete(map, key, key_size);
}
UPB_INLINE void _upb_msg_map_clear(upb_msg *msg, size_t ofs) {
upb_map *map = UPB_FIELD_AT(msg, upb_map *, ofs);
if (!map) return;
_upb_map_clear(map);
}
/* Accessing map key/value from a pointer, used by generated code only. */
UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) {
const upb_tabent *ent = (const upb_tabent*)msg;
uint32_t u32len;
upb_strview k;
k.data = upb_tabstr(ent->key, &u32len);
k.size = u32len;
_upb_map_fromkey(k, key, size);
}
UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) {
const upb_tabent *ent = (const upb_tabent*)msg;
upb_value v;
_upb_value_setval(&v, ent->val.val);
_upb_map_fromvalue(v, val, size);
}
UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, size_t size) {
upb_tabent *ent = (upb_tabent*)msg;
/* This is like _upb_map_tovalue() except the entry already exists so we can
* reuse the allocated upb_strview for string fields. */
if (size == UPB_MAPTYPE_STRING) {
upb_strview *strp = (upb_strview*)ent->val.val;
memcpy(strp, val, sizeof(*strp));
} else {
memcpy(&ent->val.val, val, size);
}
}
#undef PTR_AT
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* UPB_MSG_H_ */

@ -1,248 +0,0 @@
#include "upb/msgfactory.h"
#include "upb/port_def.inc"
static bool is_power_of_two(size_t val) {
return (val & (val - 1)) == 0;
}
/* Align up to the given power of 2. */
static size_t align_up(size_t val, size_t align) {
UPB_ASSERT(is_power_of_two(align));
return (val + align - 1) & ~(align - 1);
}
static size_t div_round_up(size_t n, size_t d) {
return (n + d - 1) / d;
}
static size_t upb_msgval_sizeof2(upb_fieldtype_t type) {
switch (type) {
case UPB_TYPE_DOUBLE:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT64:
return 8;
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
case UPB_TYPE_FLOAT:
return 4;
case UPB_TYPE_BOOL:
return 1;
case UPB_TYPE_MESSAGE:
return sizeof(void*);
case UPB_TYPE_BYTES:
case UPB_TYPE_STRING:
return sizeof(upb_strview);
}
UPB_UNREACHABLE();
}
static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
if (upb_fielddef_isseq(f)) {
return sizeof(void*);
} else {
return upb_msgval_sizeof2(upb_fielddef_type(f));
}
}
/** upb_msglayout *************************************************************/
static void upb_msglayout_free(upb_msglayout *l) {
upb_gfree(l);
}
static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
size_t ret;
l->size = align_up(l->size, size);
ret = l->size;
l->size += size;
return ret;
}
static bool upb_msglayout_init(const upb_msgdef *m,
upb_msglayout *l,
upb_msgfactory *factory) {
upb_msg_field_iter it;
upb_msg_oneof_iter oit;
size_t hasbit;
size_t submsg_count = 0;
const upb_msglayout **submsgs;
upb_msglayout_field *fields;
for (upb_msg_field_begin(&it, m);
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
if (upb_fielddef_issubmsg(f)) {
submsg_count++;
}
}
memset(l, 0, sizeof(*l));
fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
if ((!fields && upb_msgdef_numfields(m)) ||
(!submsgs && submsg_count)) {
/* OOM. */
upb_gfree(fields);
upb_gfree(submsgs);
return false;
}
l->field_count = upb_msgdef_numfields(m);
l->fields = fields;
l->submsgs = submsgs;
/* Allocate data offsets in three stages:
*
* 1. hasbits.
* 2. regular fields.
* 3. oneof fields.
*
* OPT: There is a lot of room for optimization here to minimize the size.
*/
/* Allocate hasbits and set basic field attributes. */
submsg_count = 0;
for (upb_msg_field_begin(&it, m), hasbit = 0;
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
field->number = upb_fielddef_number(f);
field->descriptortype = upb_fielddef_descriptortype(f);
field->label = upb_fielddef_label(f);
if (upb_fielddef_issubmsg(f)) {
const upb_msglayout *sub_layout =
upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f));
field->submsg_index = submsg_count++;
submsgs[field->submsg_index] = sub_layout;
}
if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
field->presence = (hasbit++);
} else {
field->presence = 0;
}
}
/* Account for space used by hasbits. */
l->size = div_round_up(hasbit, 8);
/* Allocate non-oneof fields. */
for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
size_t field_size = upb_msg_fielddefsize(f);
size_t index = upb_fielddef_index(f);
if (upb_fielddef_containingoneof(f)) {
/* Oneofs are handled separately below. */
continue;
}
fields[index].offset = upb_msglayout_place(l, field_size);
}
/* Allocate oneof fields. Each oneof field consists of a uint32 for the case
* and space for the actual data. */
for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
upb_msg_oneof_next(&oit)) {
const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
upb_oneof_iter fit;
size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
size_t field_size = 0;
uint32_t case_offset;
uint32_t data_offset;
/* Calculate field size: the max of all field sizes. */
for (upb_oneof_begin(&fit, o);
!upb_oneof_done(&fit);
upb_oneof_next(&fit)) {
const upb_fielddef* f = upb_oneof_iter_field(&fit);
field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
}
/* Align and allocate case offset. */
case_offset = upb_msglayout_place(l, case_size);
data_offset = upb_msglayout_place(l, field_size);
for (upb_oneof_begin(&fit, o);
!upb_oneof_done(&fit);
upb_oneof_next(&fit)) {
const upb_fielddef* f = upb_oneof_iter_field(&fit);
fields[upb_fielddef_index(f)].offset = data_offset;
fields[upb_fielddef_index(f)].presence = ~case_offset;
}
}
/* Size of the entire structure should be a multiple of its greatest
* alignment. TODO: track overall alignment for real? */
l->size = align_up(l->size, 8);
return true;
}
/** upb_msgfactory ************************************************************/
struct upb_msgfactory {
const upb_symtab *symtab; /* We own a ref. */
upb_inttable layouts;
};
upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) {
upb_msgfactory *ret = upb_gmalloc(sizeof(*ret));
ret->symtab = symtab;
upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR);
return ret;
}
void upb_msgfactory_free(upb_msgfactory *f) {
upb_inttable_iter i;
upb_inttable_begin(&i, &f->layouts);
for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i));
upb_msglayout_free(l);
}
upb_inttable_uninit(&f->layouts);
upb_gfree(f);
}
const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) {
return f->symtab;
}
const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
const upb_msgdef *m) {
upb_value v;
UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m);
UPB_ASSERT(!upb_msgdef_mapentry(m));
if (upb_inttable_lookupptr(&f->layouts, m, &v)) {
UPB_ASSERT(upb_value_getptr(v));
return upb_value_getptr(v);
} else {
/* In case of circular dependency, layout has to be inserted first. */
upb_msglayout *l = upb_gmalloc(sizeof(*l));
upb_msgfactory *mutable_f = (void*)f;
upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
UPB_ASSERT(l);
if (!upb_msglayout_init(m, l, f)) {
upb_msglayout_free(l);
}
return l;
}
}

@ -1,48 +0,0 @@
#include "upb/def.h"
#include "upb/msg.h"
#ifndef UPB_MSGFACTORY_H_
#define UPB_MSGFACTORY_H_
/** upb_msgfactory ************************************************************/
struct upb_msgfactory;
typedef struct upb_msgfactory upb_msgfactory;
#ifdef __cplusplus
extern "C" {
#endif
/* A upb_msgfactory contains a cache of upb_msglayout, upb_handlers, and
* upb_visitorplan objects. These are the objects necessary to represent,
* populate, and and visit upb_msg objects.
*
* These caches are all populated by upb_msgdef, and lazily created on demand.
*/
/* Creates and destroys a msgfactory, respectively. The messages for this
* msgfactory must come from |symtab| (which should outlive the msgfactory). */
upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab);
void upb_msgfactory_free(upb_msgfactory *f);
const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f);
/* The functions to get cached objects, lazily creating them on demand. These
* all require:
*
* - m is in upb_msgfactory_symtab(f)
* - upb_msgdef_mapentry(m) == false (since map messages can't have layouts).
*
* The returned objects will live for as long as the msgfactory does.
*
* TODO(haberman): consider making this thread-safe and take a const
* upb_msgfactory. */
const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
const upb_msgdef *m);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MSGFACTORY_H_ */

@ -910,10 +910,10 @@ const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c,
} else {
g = mgroup_new(h, c->lazy);
ok = upb_inttable_insertptr(&c->groups, md, upb_value_constptr(g));
UPB_ASSERT(ok);
UPB_ASSUME(ok);
}
ok = upb_inttable_lookupptr(&g->methods, h, &v);
UPB_ASSERT(ok);
UPB_ASSUME(ok);
return upb_value_getptr(v);
}

@ -26,16 +26,16 @@ extern "C" {
* descriptor type (upb_descriptortype_t). */
extern const uint8_t upb_pb_native_wire_types[];
UPB_INLINE uint64_t byteswap64(uint64_t val)
{
return ((((val) & 0xff00000000000000ull) >> 56)
| (((val) & 0x00ff000000000000ull) >> 40)
| (((val) & 0x0000ff0000000000ull) >> 24)
| (((val) & 0x000000ff00000000ull) >> 8)
| (((val) & 0x00000000ff000000ull) << 8)
| (((val) & 0x0000000000ff0000ull) << 24)
| (((val) & 0x000000000000ff00ull) << 40)
| (((val) & 0x00000000000000ffull) << 56));
UPB_INLINE uint64_t byteswap64(uint64_t val) {
uint64_t byte = 0xff;
return (val & (byte << 56) >> 56)
| (val & (byte << 48) >> 40)
| (val & (byte << 40) >> 24)
| (val & (byte << 32) >> 8)
| (val & (byte << 24) << 8)
| (val & (byte << 16) << 24)
| (val & (byte << 8) << 40)
| (val & (byte << 0) << 56);
}
/* Zig-zag encoding/decoding **************************************************/

@ -28,6 +28,9 @@
#define UPB_SIZE(size32, size64) size64
#endif
/* These macros aren't really "port", they are helper macros that we don't want
* to leak.
*/
#define UPB_FIELD_AT(msg, fieldtype, offset) \
*(fieldtype*)((const char*)(msg) + offset)
@ -40,6 +43,8 @@
UPB_FIELD_AT(msg, int, case_offset) = case_val; \
UPB_FIELD_AT(msg, fieldtype, offset) = value;
#define UPB_MAPTYPE_STRING 0
/* UPB_INLINE: inline if possible, emit standalone code if required. */
#ifdef __cplusplus
#define UPB_INLINE inline
@ -123,6 +128,18 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
#define UPB_UNUSED(var) (void)var
/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true.
*/
#ifdef NDEBUG
#ifdef __GNUC__
#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable()
#else
#define UPB_ASSUME(expr) do {} if (false && (expr))
#endif
#else
#define UPB_ASSUME(expr) assert(expr)
#endif
/* UPB_ASSERT(): in release mode, we use the expression without letting it be
* evaluated. This prevents "unused variable" warnings. */
#ifdef NDEBUG

@ -1,5 +1,6 @@
/* See port_def.inc. This should #undef all macros #defined there. */
#undef UPB_MAPTYPE_STRING
#undef UPB_SIZE
#undef UPB_FIELD_AT
#undef UPB_READ_ONEOF
@ -11,6 +12,7 @@
#undef UPB_MAX
#undef UPB_MIN
#undef UPB_UNUSED
#undef UPB_ASSUME
#undef UPB_ASSERT
#undef UPB_ASSERT_DEBUGVAR
#undef UPB_UNREACHABLE

@ -0,0 +1,289 @@
#include "upb/reflection.h"
#include <string.h>
#include "upb/table.int.h"
#include "upb/msg.h"
#include "upb/port_def.inc"
static char field_size[] = {
0,/* 0 */
8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */
4, /* UPB_DESCRIPTOR_TYPE_FLOAT */
8, /* UPB_DESCRIPTOR_TYPE_INT64 */
8, /* UPB_DESCRIPTOR_TYPE_UINT64 */
4, /* UPB_DESCRIPTOR_TYPE_INT32 */
8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */
4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */
1, /* UPB_DESCRIPTOR_TYPE_BOOL */
sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */
sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */
sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */
sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */
4, /* UPB_DESCRIPTOR_TYPE_UINT32 */
4, /* UPB_DESCRIPTOR_TYPE_ENUM */
4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */
8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */
4, /* UPB_DESCRIPTOR_TYPE_SINT32 */
8, /* UPB_DESCRIPTOR_TYPE_SINT64 */
};
/* Strings/bytes are special-cased in maps. */
static char _upb_fieldtype_to_mapsize[12] = {
0,
1, /* UPB_TYPE_BOOL */
4, /* UPB_TYPE_FLOAT */
4, /* UPB_TYPE_INT32 */
4, /* UPB_TYPE_UINT32 */
4, /* UPB_TYPE_ENUM */
sizeof(void*), /* UPB_TYPE_MESSAGE */
8, /* UPB_TYPE_DOUBLE */
8, /* UPB_TYPE_INT64 */
8, /* UPB_TYPE_UINT64 */
0, /* UPB_TYPE_STRING */
0, /* UPB_TYPE_BYTES */
};
/** upb_msg *******************************************************************/
/* If we always read/write as a consistent type to each address, this shouldn't
* violate aliasing.
*/
#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) {
return _upb_msg_new(upb_msgdef_layout(m), a);
}
static bool in_oneof(const upb_msglayout_field *field) {
return field->presence < 0;
}
static uint32_t *oneofcase(const upb_msg *msg,
const upb_msglayout_field *field) {
UPB_ASSERT(in_oneof(field));
return PTR_AT(msg, ~field->presence, uint32_t);
}
static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
const char *mem = PTR_AT(msg, field->offset, char);
upb_msgval val = {0};
int size = upb_fielddef_isseq(f) ? sizeof(void *)
: field_size[field->descriptortype];
memcpy(&val, mem, size);
return val;
}
bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
if (in_oneof(field)) {
return *oneofcase(msg, field) == field->number;
} else if (field->presence > 0) {
uint32_t hasbit = field->presence;
return *PTR_AT(msg, hasbit / 8, char) | (1 << (hasbit % 8));
} else {
UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
return _upb_msg_getraw(msg, f).msg_val != NULL;
}
}
upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
return _upb_msg_getraw(msg, f);
} else {
/* TODO(haberman): change upb_fielddef to not require this switch(). */
upb_msgval val = {0};
switch (upb_fielddef_type(f)) {
case UPB_TYPE_INT32:
case UPB_TYPE_ENUM:
val.int32_val = upb_fielddef_defaultint32(f);
break;
case UPB_TYPE_INT64:
val.int64_val = upb_fielddef_defaultint64(f);
break;
case UPB_TYPE_UINT32:
val.uint32_val = upb_fielddef_defaultuint32(f);
break;
case UPB_TYPE_UINT64:
val.uint64_val = upb_fielddef_defaultuint64(f);
break;
case UPB_TYPE_FLOAT:
val.float_val = upb_fielddef_defaultfloat(f);
break;
case UPB_TYPE_DOUBLE:
val.double_val = upb_fielddef_defaultdouble(f);
break;
case UPB_TYPE_BOOL:
val.double_val = upb_fielddef_defaultbool(f);
break;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES:
val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size);
break;
case UPB_TYPE_MESSAGE:
val.msg_val = NULL;
break;
}
return val;
}
}
upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f,
upb_arena *a) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
upb_mutmsgval ret;
char *mem = PTR_AT(msg, field->offset, char);
memcpy(&ret, mem, sizeof(void*));
if (a && !ret.msg) {
if (upb_fielddef_ismap(f)) {
const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);
ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value));
} else if (upb_fielddef_isseq(f)) {
ret.array = upb_array_new(a, upb_fielddef_type(f));
} else {
UPB_ASSERT(upb_fielddef_issubmsg(f));
ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a);
}
memcpy(mem, &ret, sizeof(void*));
}
return ret;
}
void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
upb_arena *a) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
char *mem = PTR_AT(msg, field->offset, char);
int size = upb_fielddef_isseq(f) ? sizeof(void *)
: field_size[field->descriptortype];
memcpy(mem, &val, size);
if (in_oneof(field)) {
*oneofcase(msg, field) = field->number;
}
}
bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
const upb_symtab *ext_pool, const upb_fielddef **out_f,
upb_msgval *out_val, size_t *iter) {
int i = *iter;
const upb_msgval zero = {0};
const upb_fielddef *f;
while ((f = _upb_msgdef_field(m, ++i)) != NULL) {
upb_msgval val = _upb_msg_getraw(msg, f);
/* Skip field if unset or empty. */
if (upb_fielddef_haspresence(f)) {
if (!upb_msg_has(msg, f)) continue;
} else {
upb_msgval test = val;
if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) {
/* Clear string pointer, only size matters (ptr could be non-NULL). */
test.str_val.data = NULL;
}
/* Continue if NULL or 0. */
if (memcmp(&test, &zero, sizeof(test)) == 0) continue;
}
*out_val = val;
*out_f = f;
*iter = i;
return true;
}
*iter = i;
return false;
}
/** upb_array *****************************************************************/
upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) {
return _upb_array_new(a, type);
}
size_t upb_array_size(const upb_array *arr) {
return arr->len;
}
upb_msgval upb_array_get(const upb_array *arr, size_t i) {
upb_msgval ret;
const char* data = _upb_array_constptr(arr);
int lg2 = arr->data & 7;
UPB_ASSERT(i < arr->len);
memcpy(&ret, data + (i << lg2), 1 << lg2);
return ret;
}
void upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
char* data = _upb_array_ptr(arr);
int lg2 = arr->data & 7;
UPB_ASSERT(i < arr->len);
memcpy(data + (i << lg2), &val, 1 << lg2);
}
bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) {
if (!_upb_array_realloc(arr, arr->len + 1, arena)) {
return false;
}
arr->len++;
upb_array_set(arr, arr->len - 1, val);
return true;
}
/* Resizes the array to the given size, reallocating if necessary, and returns a
* pointer to the new array elements. */
bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) {
return _upb_array_realloc(arr, size, arena);
}
/** upb_map *******************************************************************/
upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type,
upb_fieldtype_t value_type) {
return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type],
_upb_fieldtype_to_mapsize[value_type]);
}
size_t upb_map_size(const upb_map *map) {
return _upb_map_size(map);
}
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
return _upb_map_get(map, &key, map->key_size, val, map->val_size);
}
bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
upb_arena *arena) {
return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena);
}
bool upb_map_delete(upb_map *map, upb_msgval key) {
return _upb_map_delete(map, &key, map->key_size);
}
bool upb_mapiter_next(const upb_map *map, size_t *iter) {
return _upb_map_next(map, iter);
}
/* Returns the key and value for this entry of the map. */
upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) {
upb_strtable_iter i;
upb_msgval ret;
i.t = &map->table;
i.index = iter;
_upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size);
return ret;
}
upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) {
upb_strtable_iter i;
upb_msgval ret;
i.t = &map->table;
i.index = iter;
_upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size);
return ret;
}
/* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */

@ -0,0 +1,153 @@
#ifndef UPB_REFLECTION_H_
#define UPB_REFLECTION_H_
#include "upb/def.h"
#include "upb/msg.h"
#include "upb/upb.h"
#include "upb/port_def.inc"
typedef union {
bool bool_val;
float float_val;
double double_val;
int32_t int32_val;
int64_t int64_val;
uint32_t uint32_val;
uint64_t uint64_val;
const upb_map* map_val;
const upb_msg* msg_val;
const upb_array* array_val;
upb_strview str_val;
} upb_msgval;
typedef union {
upb_map* map;
upb_msg* msg;
upb_array* array;
} upb_mutmsgval;
/** upb_msg *******************************************************************/
/* Creates a new message of the given type in the given arena. */
upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a);
/* Returns the value associated with this field. */
upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f);
/* Returns a mutable pointer to a map, array, or submessage value. If the given
* arena is non-NULL this will construct a new object if it was not previously
* present. May not be called for primitive fields. */
upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, upb_arena *a);
/* May only be called for fields where upb_fielddef_haspresence(f) == true. */
bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f);
/* Sets the given field to the given value. For a msg/array/map/string, the
* value must be in the same arena. */
void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
upb_arena *a);
/* Clears any field presence and sets the value back to its default. */
void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f);
/* Iterate over present fields.
*
* size_t iter = UPB_MSG_BEGIN;
* const upb_fielddef *f;
* upb_msgval val;
* while (upb_msg_next(msg, m, ext_pool, &f, &val, &iter)) {
* process_field(f, val);
* }
*
* If ext_pool is NULL, no extensions will be returned. If the given symtab
* returns extensions that don't match what is in this message, those extensions
* will be skipped.
*/
#define UPB_MSG_BEGIN -1
bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
const upb_symtab *ext_pool, const upb_fielddef **f,
upb_msgval *val, size_t *iter);
/* Adds unknown data (serialized protobuf data) to the given message. The data
* is copied into the message instance. */
void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
upb_arena *arena);
/* Returns a reference to the message's unknown data. */
const char *upb_msg_getunknown(const upb_msg *msg, size_t *len);
/** upb_array *****************************************************************/
/* Creates a new array on the given arena that holds elements of this type. */
upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type);
/* Returns the size of the array. */
size_t upb_array_size(const upb_array *arr);
/* Returns the given element, which must be within the array's current size. */
upb_msgval upb_array_get(const upb_array *arr, size_t i);
/* Sets the given element, which must be within the array's current size. */
void upb_array_set(upb_array *arr, size_t i, upb_msgval val);
/* Appends an element to the array. Returns false on allocation failure. */
bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena);
/* Changes the size of a vector. New elements are initialized to empty/0.
* Returns false on allocation failure. */
bool upb_array_resize(upb_array *array, size_t size, upb_arena *arena);
/** upb_map *******************************************************************/
/* Creates a new map on the given arena with the given key/value size. */
upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type,
upb_fieldtype_t value_type);
/* Returns the number of entries in the map. */
size_t upb_map_size(const upb_map *map);
/* Stores a value for the given key into |*val| (or the zero value if the key is
* not present). Returns whether the key was present. The |val| pointer may be
* NULL, in which case the function tests whether the given key is present. */
bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val);
/* Removes all entries in the map. */
void upb_map_clear(upb_map *map);
/* Sets the given key to the given value. Returns true if this was a new key in
* the map, or false if an existing key was replaced. */
bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
upb_arena *arena);
/* Deletes this key from the table. Returns true if the key was present. */
bool upb_map_delete(upb_map *map, upb_msgval key);
/* Map iteration:
*
* size_t iter = UPB_MAP_BEGIN;
* while (upb_mapiter_next(map, &iter)) {
* upb_msgval key = upb_mapiter_key(map, iter);
* upb_msgval val = upb_mapiter_value(map, iter);
*
* // If mutating is desired.
* upb_mapiter_setvalue(map, iter, value2);
* }
*/
/* Advances to the next entry. Returns false if no more entries are present. */
bool upb_mapiter_next(const upb_map *map, size_t *iter);
/* Returns the key and value for this entry of the map. */
upb_msgval upb_mapiter_key(const upb_map *map, size_t iter);
upb_msgval upb_mapiter_value(const upb_map *map, size_t iter);
/* Sets the value for this entry. The iterator must not be done, and the
* iterator must not have been initialized const. */
void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value);
#include "upb/port_undef.inc"
#endif /* UPB_REFLECTION_H_ */

@ -16,12 +16,6 @@
#define ARRAY_SIZE(x) \
((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
static void upb_check_alloc(upb_table *t, upb_alloc *a) {
UPB_UNUSED(t);
UPB_UNUSED(a);
UPB_ASSERT_DEBUGVAR(t->alloc == a);
}
static const double MAX_LOAD = 0.85;
/* The minimum utilization of the array part of a mixed hash/array table. This
@ -100,17 +94,12 @@ static bool isfull(upb_table *t) {
}
}
static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
upb_alloc *a) {
static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
size_t bytes;
t->count = 0;
t->ctype = ctype;
t->size_lg2 = size_lg2;
t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
#ifndef NDEBUG
t->alloc = a;
#endif
bytes = upb_table_size(t) * sizeof(upb_tabent);
if (bytes > 0) {
t->entries = upb_malloc(a, bytes);
@ -123,7 +112,6 @@ static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
}
static void uninit(upb_table *t, upb_alloc *a) {
upb_check_alloc(t, a);
upb_free(a, mutable_entries(t));
}
@ -159,7 +147,7 @@ static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
const upb_tabent *e = findentry(t, key, hash, eql);
if (e) {
if (v) {
_upb_value_setval(v, e->val.val, t->ctype);
_upb_value_setval(v, e->val.val);
}
return true;
} else {
@ -175,7 +163,6 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
upb_tabent *our_e;
UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype);
t->count++;
mainpos_e = getentry_mutable(t, hash);
@ -221,7 +208,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
if (eql(chain->key, key)) {
/* Element to remove is at the head of its chain. */
t->count--;
if (val) _upb_value_setval(val, chain->val.val, t->ctype);
if (val) _upb_value_setval(val, chain->val.val);
if (removed) *removed = chain->key;
if (chain->next) {
upb_tabent *move = (upb_tabent*)chain->next;
@ -241,7 +228,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
/* Found element to remove. */
upb_tabent *rm = (upb_tabent*)chain->next;
t->count--;
if (val) _upb_value_setval(val, chain->next->val.val, t->ctype);
if (val) _upb_value_setval(val, chain->next->val.val);
if (removed) *removed = rm->key;
rm->key = 0; /* Make the slot empty. */
chain->next = rm->next;
@ -294,7 +281,13 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) {
}
bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) {
return init(&t->t, ctype, 2, a);
return init(&t->t, 2, a);
}
void upb_strtable_clear(upb_strtable *t) {
size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
t->t.count = 0;
memset((char*)t->t.entries, 0, bytes);
}
void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
@ -308,18 +301,14 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
upb_strtable new_table;
upb_strtable_iter i;
upb_check_alloc(&t->t, a);
if (!init(&new_table.t, t->t.ctype, size_lg2, a))
if (!init(&new_table.t, size_lg2, a))
return false;
upb_strtable_begin(&i, t);
for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
upb_strview key = upb_strtable_iter_key(&i);
upb_strtable_insert3(
&new_table,
upb_strtable_iter_key(&i),
upb_strtable_iter_keylength(&i),
upb_strtable_iter_value(&i),
a);
&new_table, key.data, key.size,
upb_strtable_iter_value(&i), a);
}
upb_strtable_uninit2(t, a);
*t = new_table;
@ -332,8 +321,6 @@ bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
upb_tabkey tabkey;
uint32_t hash;
upb_check_alloc(&t->t, a);
if (isfull(&t->t)) {
/* Need to resize. New table of double the size, add old elements to it. */
if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
@ -361,7 +348,10 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
uint32_t hash = upb_murmur_hash2(key, len, 0);
upb_tabkey tabkey;
if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
upb_free(alloc, (void*)tabkey);
if (alloc) {
/* Arena-based allocs don't need to free and won't pass this. */
upb_free(alloc, (void*)tabkey);
}
return true;
} else {
return false;
@ -370,10 +360,6 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
/* Iteration */
static const upb_tabent *str_tabent(const upb_strtable_iter *i) {
return &i->t->t.entries[i->index];
}
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
i->t = t;
i->index = begin(&t->t);
@ -389,21 +375,18 @@ bool upb_strtable_done(const upb_strtable_iter *i) {
upb_tabent_isempty(str_tabent(i));
}
const char *upb_strtable_iter_key(const upb_strtable_iter *i) {
UPB_ASSERT(!upb_strtable_done(i));
return upb_tabstr(str_tabent(i)->key, NULL);
}
size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) {
upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) {
upb_strview key;
uint32_t len;
UPB_ASSERT(!upb_strtable_done(i));
upb_tabstr(str_tabent(i)->key, &len);
return len;
key.data = upb_tabstr(str_tabent(i)->key, &len);
key.size = len;
return key;
}
upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
UPB_ASSERT(!upb_strtable_done(i));
return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype);
return _upb_value_val(str_tabent(i)->val.val);
}
void upb_strtable_iter_setdone(upb_strtable_iter *i) {
@ -469,11 +452,11 @@ static void check(upb_inttable *t) {
#endif
}
bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
size_t asize, int hsize_lg2, upb_alloc *a) {
bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
upb_alloc *a) {
size_t array_bytes;
if (!init(&t->t, ctype, hsize_lg2, a)) return false;
if (!init(&t->t, hsize_lg2, a)) return false;
/* Always make the array part at least 1 long, so that we know key 0
* won't be in the hash part, which simplifies things. */
t->array_size = UPB_MAX(1, asize);
@ -490,7 +473,7 @@ bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
}
bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
return upb_inttable_sizedinit(t, ctype, 0, 4, a);
return upb_inttable_sizedinit(t, 0, 4, a);
}
void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
@ -504,8 +487,6 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
tabval.val = val.val;
UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
upb_check_alloc(&t->t, a);
if (key < t->array_size) {
UPB_ASSERT(!upb_arrhas(t->array[key]));
t->array_count++;
@ -516,7 +497,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
size_t i;
upb_table new_table;
if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) {
if (!init(&new_table, t->t.size_lg2 + 1, a)) {
return false;
}
@ -525,7 +506,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
uint32_t hash;
upb_value v;
_upb_value_setval(&v, e->val.val, t->t.ctype);
_upb_value_setval(&v, e->val.val);
hash = upb_inthash(e->key);
insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
}
@ -544,7 +525,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
const upb_tabval *table_v = inttable_val_const(t, key);
if (!table_v) return false;
if (v) _upb_value_setval(v, table_v->val, t->t.ctype);
if (v) _upb_value_setval(v, table_v->val);
return true;
}
@ -562,7 +543,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
t->array_count--;
if (val) {
_upb_value_setval(val, t->array[key].val, t->t.ctype);
_upb_value_setval(val, t->array[key].val);
}
mutable_array(t)[key] = empty;
success = true;
@ -577,7 +558,6 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
}
bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) {
upb_check_alloc(&t->t, a);
return upb_inttable_insert2(t, upb_inttable_count(t), val, a);
}
@ -590,7 +570,6 @@ upb_value upb_inttable_pop(upb_inttable *t) {
bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
upb_alloc *a) {
upb_check_alloc(&t->t, a);
return upb_inttable_insert2(t, (uintptr_t)key, val, a);
}
@ -615,8 +594,6 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
int size_lg2;
upb_inttable new_t;
upb_check_alloc(&t->t, a);
upb_inttable_begin(&i, t);
for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
uintptr_t key = upb_inttable_iter_key(&i);
@ -649,7 +626,7 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
int hashsize_lg2 = log2ceil(hash_size);
upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a);
upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a);
upb_inttable_begin(&i, t);
for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
uintptr_t k = upb_inttable_iter_key(&i);
@ -715,8 +692,7 @@ uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
UPB_ASSERT(!upb_inttable_done(i));
return _upb_value_val(
i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val,
i->t->t.ctype);
i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val);
}
void upb_inttable_iter_setdone(upb_inttable_iter *i) {

@ -52,19 +52,8 @@ typedef enum {
typedef struct {
uint64_t val;
#ifndef NDEBUG
/* In debug mode we carry the value type around also so we can check accesses
* to be sure the right member is being read. */
upb_ctype_t ctype;
#endif
} upb_value;
#ifdef NDEBUG
#define SET_TYPE(dest, val) UPB_UNUSED(val)
#else
#define SET_TYPE(dest, val) dest = val
#endif
/* Like strdup(), which isn't always available since it's not ANSI C. */
char *upb_strdup(const char *s, upb_alloc *a);
/* Variant that works with a length-delimited rather than NULL-delimited string,
@ -75,15 +64,13 @@ UPB_INLINE char *upb_gstrdup(const char *s) {
return upb_strdup(s, &upb_alloc_global);
}
UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val,
upb_ctype_t ctype) {
UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) {
v->val = val;
SET_TYPE(v->ctype, ctype);
}
UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) {
UPB_INLINE upb_value _upb_value_val(uint64_t val) {
upb_value ret;
_upb_value_setval(&ret, val, ctype);
_upb_value_setval(&ret, val);
return ret;
}
@ -98,7 +85,6 @@ UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) {
#define FUNCS(name, membername, type_t, converter, proto_type) \
UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \
val->val = (converter)cval; \
SET_TYPE(val->ctype, proto_type); \
} \
UPB_INLINE upb_value upb_value_ ## name(type_t val) { \
upb_value ret; \
@ -106,7 +92,6 @@ UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) {
return ret; \
} \
UPB_INLINE type_t upb_value_get ## name(upb_value val) { \
UPB_ASSERT_DEBUGVAR(val.ctype == proto_type); \
return (type_t)(converter)val.val; \
}
@ -124,12 +109,10 @@ FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR)
UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) {
memcpy(&val->val, &cval, sizeof(cval));
SET_TYPE(val->ctype, UPB_CTYPE_FLOAT);
}
UPB_INLINE void upb_value_setdouble(upb_value *val, double cval) {
memcpy(&val->val, &cval, sizeof(cval));
SET_TYPE(val->ctype, UPB_CTYPE_DOUBLE);
}
UPB_INLINE upb_value upb_value_float(float cval) {
@ -173,7 +156,6 @@ typedef struct {
#define UPB_TABVALUE_EMPTY_INIT {-1}
/* upb_table ******************************************************************/
typedef struct _upb_tabent {
@ -190,7 +172,6 @@ typedef struct _upb_tabent {
typedef struct {
size_t count; /* Number of entries in the hash part. */
size_t mask; /* Mask to turn hash value -> bucket. */
upb_ctype_t ctype; /* Type of all values. */
uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */
/* Hash table entries.
@ -200,17 +181,6 @@ typedef struct {
* initialize const hash tables. Then we cast away const when we have to.
*/
const upb_tabent *entries;
#ifndef NDEBUG
/* This table's allocator. We make the user pass it in to every relevant
* function and only use this to check it in debug mode. We do this solely
* to keep upb_table as small as possible. This might seem slightly paranoid
* but the plan is to use upb_table for all map fields and extension sets in
* a forthcoming message representation, so there could be a lot of these.
* If this turns out to be too annoying later, we can change it (since this
* is an internal-only header file). */
upb_alloc *alloc;
#endif
} upb_table;
typedef struct {
@ -224,12 +194,6 @@ typedef struct {
size_t array_count; /* Array part number of elements. */
} upb_inttable;
#define UPB_INTTABLE_INIT(count, mask, ctype, size_lg2, ent, a, asize, acount) \
{UPB_TABLE_INIT(count, mask, ctype, size_lg2, ent), a, asize, acount}
#define UPB_EMPTY_INTTABLE_INIT(ctype) \
UPB_INTTABLE_INIT(0, 0, ctype, 0, NULL, NULL, 0, 0)
#define UPB_ARRAY_EMPTYENT -1
UPB_INLINE size_t upb_table_size(const upb_table *t) {
@ -298,6 +262,7 @@ upb_inttable *upb_inttable_pack(const upb_inttable *t, void *p, size_t *ofs,
size_t size);
upb_strtable *upb_strtable_pack(const upb_strtable *t, void *p, size_t *ofs,
size_t size);
void upb_strtable_clear(upb_strtable *t);
/* Inserts the given key into the hashtable with the given value. The key must
* not already exist in the hash table. For string tables, the key must be
@ -399,7 +364,7 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key,
if (key < t->array_size) {
upb_tabval arrval = t->array[key];
if (upb_arrhas(arrval)) {
_upb_value_setval(v, arrval.val, t->t.ctype);
_upb_value_setval(v, arrval.val);
return true;
} else {
return false;
@ -409,7 +374,7 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key,
if (t->t.entries == NULL) return false;
for (e = upb_getentry(&t->t, upb_inthash(key)); true; e = e->next) {
if ((uint32_t)e->key == key) {
_upb_value_setval(v, e->val.val, t->t.ctype);
_upb_value_setval(v, e->val.val);
return true;
}
if (e->next == NULL) return false;
@ -463,8 +428,7 @@ typedef struct {
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
void upb_strtable_next(upb_strtable_iter *i);
bool upb_strtable_done(const upb_strtable_iter *i);
const char *upb_strtable_iter_key(const upb_strtable_iter *i);
size_t upb_strtable_iter_keylength(const upb_strtable_iter *i);
upb_strview upb_strtable_iter_key(const upb_strtable_iter *i);
upb_value upb_strtable_iter_value(const upb_strtable_iter *i);
void upb_strtable_iter_setdone(upb_strtable_iter *i);
bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
@ -488,6 +452,10 @@ typedef struct {
bool array_part;
} upb_inttable_iter;
UPB_INLINE const upb_tabent *str_tabent(const upb_strtable_iter *i) {
return &i->t->t.entries[i->index];
}
void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t);
void upb_inttable_next(upb_inttable_iter *i);
bool upb_inttable_done(const upb_inttable_iter *i);

@ -0,0 +1,393 @@
#include "upb/textencode.h"
#include <ctype.h>
#include <float.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "upb/reflection.h"
#include "upb/port_def.inc"
typedef struct {
char *buf, *ptr, *end;
size_t overflow;
int indent_depth;
int options;
const upb_symtab *ext_pool;
} txtenc;
static void txtenc_msg(txtenc *e, const upb_msg *msg, const upb_msgdef *m);
#define CHK(x) do { if (!(x)) { return false; } } while(0)
static void txtenc_putbytes(txtenc *e, const void *data, size_t len) {
size_t have = e->end - e->ptr;
if (UPB_LIKELY(have >= len)) {
memcpy(e->ptr, data, len);
e->ptr += len;
} else {
memcpy(e->ptr, data, have);
e->ptr += have;
e->overflow += (len - have);
}
}
static void txtenc_putstr(txtenc *e, const char *str) {
txtenc_putbytes(e, str, strlen(str));
}
static void txtenc_printf(txtenc *e, const char *fmt, ...) {
size_t n;
size_t have = e->end - e->ptr;
va_list args;
va_start(args, fmt);
n = _upb_vsnprintf(e->ptr, have, fmt, args);
va_end(args);
if (UPB_LIKELY(have > n)) {
e->ptr += n;
} else {
e->ptr += have;
e->overflow += (n - have);
}
}
static void txtenc_indent(txtenc *e) {
if ((e->options & UPB_TXTENC_SINGLELINE) == 0) {
int i = e->indent_depth;
while (i-- > 0) {
txtenc_putstr(e, " ");
}
}
}
static void txtenc_endfield(txtenc *e) {
if (e->options & UPB_TXTENC_SINGLELINE) {
txtenc_putstr(e, " ");
} else {
txtenc_putstr(e, "\n");
}
}
static void txtenc_enum(int32_t val, const upb_fielddef *f, txtenc *e) {
const upb_enumdef *e_def = upb_fielddef_enumsubdef(f);
const char *name = upb_enumdef_iton(e_def, val);
if (name) {
txtenc_printf(e, "%s", name);
} else {
txtenc_printf(e, "%" PRId32, val);
}
}
static void txtenc_string(txtenc *e, upb_strview str, bool bytes) {
const char *ptr = str.data;
const char *end = ptr + str.size;
txtenc_putstr(e, "\"");
while (ptr < end) {
switch (*ptr) {
case '\n':
txtenc_putstr(e, "\\n");
break;
case '\r':
txtenc_putstr(e, "\\r");
break;
case '\t':
txtenc_putstr(e, "\\t");
break;
case '\"':
txtenc_putstr(e, "\\\"");
break;
case '\'':
txtenc_putstr(e, "\\'");
break;
case '\\':
txtenc_putstr(e, "\\\\");
break;
default:
if ((bytes || (uint8_t)*ptr < 0x80) && !isprint(*ptr)) {
txtenc_printf(e, "\\%03o", (int)(uint8_t)*ptr);
} else {
txtenc_putbytes(e, ptr, 1);
}
}
ptr++;
}
txtenc_putstr(e, "\"");
}
static void txtenc_field(txtenc *e, upb_msgval val, const upb_fielddef *f) {
txtenc_indent(e);
txtenc_printf(e, "%s: ", upb_fielddef_name(f));
switch (upb_fielddef_type(f)) {
case UPB_TYPE_BOOL:
txtenc_putstr(e, val.bool_val ? "true" : "false");
break;
case UPB_TYPE_FLOAT:
txtenc_printf(e, "%f", val.float_val);
break;
case UPB_TYPE_DOUBLE:
txtenc_printf(e, "%f", val.double_val);
break;
case UPB_TYPE_INT32:
txtenc_printf(e, "%" PRId32, val.int32_val);
break;
case UPB_TYPE_UINT32:
txtenc_printf(e, "%" PRIu32, val.uint32_val);
break;
case UPB_TYPE_INT64:
txtenc_printf(e, "%" PRId64, val.int64_val);
break;
case UPB_TYPE_UINT64:
txtenc_printf(e, "%" PRIu64, val.uint64_val);
break;
case UPB_TYPE_STRING:
txtenc_string(e, val.str_val, false);
break;
case UPB_TYPE_BYTES:
txtenc_string(e, val.str_val, true);
break;
case UPB_TYPE_ENUM:
txtenc_enum(val.int32_val, f, e);
break;
case UPB_TYPE_MESSAGE:
txtenc_putstr(e, "{");
e->indent_depth++;
txtenc_msg(e, val.msg_val, upb_fielddef_msgsubdef(f));
e->indent_depth--;
txtenc_indent(e);
txtenc_putstr(e, "}");
break;
}
txtenc_endfield(e);
}
/*
* Arrays print as simple repeated elements, eg.
*
* foo_field: 1
* foo_field: 2
* foo_field: 3
*/
static void txtenc_array(txtenc *e, const upb_array *arr,
const upb_fielddef *f) {
size_t i;
size_t size = upb_array_size(arr);
for (i = 0; i < size; i++) {
txtenc_field(e, upb_array_get(arr, i), f);
}
}
/*
* Maps print as messages of key/value, etc.
*
* foo_map: {
* key: "abc"
* value: 123
* }
* foo_map: {
* key: "def"
* value: 456
* }
*/
static void txtenc_map(txtenc *e, const upb_map *map, const upb_fielddef *f) {
const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
size_t iter = UPB_MAP_BEGIN;
while (upb_mapiter_next(map, &iter)) {
upb_msgval key = upb_mapiter_key(map, iter);
upb_msgval val = upb_mapiter_value(map, iter);
txtenc_indent(e);
txtenc_printf(e, "%s: {", upb_fielddef_name(f));
txtenc_endfield(e);
e->indent_depth++;
txtenc_field(e, key, key_f);
txtenc_field(e, val, val_f);
e->indent_depth--;
txtenc_indent(e);
txtenc_putstr(e, "}");
txtenc_endfield(e);
}
}
static const char *txtenc_parsevarint(const char *ptr, const char *limit,
uint64_t *val) {
uint8_t byte;
int bitpos = 0;
*val = 0;
do {
CHK(bitpos < 70 && ptr < limit);
byte = *ptr;
*val |= (uint64_t)(byte & 0x7F) << bitpos;
ptr++;
bitpos += 7;
} while (byte & 0x80);
return ptr;
}
/*
* Unknown fields are printed by number.
*
* 1001: 123
* 1002: "hello"
* 1006: 0xdeadbeef
* 1003: {
* 1: 111
* }
*/
static const char *txtenc_unknown(txtenc *e, const char *ptr, const char *end,
int groupnum) {
while (ptr < end) {
uint64_t tag_64;
uint32_t tag;
CHK(ptr = txtenc_parsevarint(ptr, end, &tag_64));
CHK(tag_64 < UINT32_MAX);
tag = tag_64;
if ((tag & 7) == UPB_WIRE_TYPE_END_GROUP) {
CHK((tag >> 3) == groupnum);
return ptr;
}
txtenc_indent(e);
txtenc_printf(e, "%d: ", (int)(tag >> 3));
switch (tag & 7) {
case UPB_WIRE_TYPE_VARINT: {
uint64_t val;
CHK(ptr = txtenc_parsevarint(ptr, end, &val));
txtenc_printf(e, "%" PRIu64, val);
break;
}
case UPB_WIRE_TYPE_32BIT: {
uint32_t val;
CHK(end - ptr >= 4);
memcpy(&val, ptr, 4);
ptr += 4;
txtenc_printf(e, "0x%08" PRIu32, val);
break;
}
case UPB_WIRE_TYPE_64BIT: {
uint64_t val;
CHK(end - ptr >= 8);
memcpy(&val, ptr, 8);
ptr += 8;
txtenc_printf(e, "0x%016" PRIu64, val);
break;
}
case UPB_WIRE_TYPE_DELIMITED: {
uint64_t len;
char *start = e->ptr;
size_t start_overflow = e->overflow;
CHK(ptr = txtenc_parsevarint(ptr, end, &len));
CHK(end - ptr >= len);
/* Speculatively try to parse as message. */
txtenc_putstr(e, "{");
txtenc_endfield(e);
e->indent_depth++;
if (txtenc_unknown(e, ptr, end, -1)) {
e->indent_depth--;
txtenc_indent(e);
txtenc_putstr(e, "}");
} else {
/* Didn't work out, print as raw bytes. */
e->indent_depth--;
e->ptr = start;
e->overflow = start_overflow;
upb_strview str = {ptr, len};
txtenc_string(e, str, true);
}
ptr += len;
break;
}
case UPB_WIRE_TYPE_START_GROUP:
txtenc_putstr(e, "{");
txtenc_endfield(e);
e->indent_depth++;
CHK(ptr = txtenc_unknown(e, ptr, end, tag >> 3));
e->indent_depth--;
txtenc_indent(e);
txtenc_putstr(e, "}");
break;
}
txtenc_endfield(e);
}
return groupnum == -1 ? ptr : NULL;
}
static void txtenc_msg(txtenc *e, const upb_msg *msg,
const upb_msgdef *m) {
size_t iter = UPB_MSG_BEGIN;
const upb_fielddef *f;
upb_msgval val;
while (upb_msg_next(msg, m, e->ext_pool, &f, &val, &iter)) {
if (upb_fielddef_ismap(f)) {
txtenc_map(e, val.map_val, f);
} else if (upb_fielddef_isseq(f)) {
txtenc_array(e, val.array_val, f);
} else {
txtenc_field(e, val, f);
}
}
if ((e->options & UPB_TXTENC_SKIPUNKNOWN) == 0) {
size_t len;
const char *ptr = upb_msg_getunknown(msg, &len);
char *start = e->ptr;
if (ptr) {
if (!txtenc_unknown(e, ptr, ptr + len, -1)) {
/* Unknown failed to parse, back up and don't print it at all. */
e->ptr = start;
}
}
}
}
size_t txtenc_nullz(txtenc *e, size_t size) {
size_t ret = e->ptr - e->buf + e->overflow;
if (size > 0) {
if (e->ptr == e->end) e->ptr--;
*e->ptr = '\0';
}
return ret;
}
size_t upb_textencode(const upb_msg *msg, const upb_msgdef *m,
const upb_symtab *ext_pool, int options, char *buf,
size_t size) {
txtenc e;
e.buf = buf;
e.ptr = buf;
e.end = buf + size;
e.overflow = 0;
e.indent_depth = 0;
e.options = options;
e.ext_pool = ext_pool;
txtenc_msg(&e, msg, m);
return txtenc_nullz(&e, size);
}
#undef CHK

@ -0,0 +1,27 @@
#ifndef UPB_TEXTENCODE_H_
#define UPB_TEXTENCODE_H_
#include "upb/def.h"
enum {
/* When set, prints everything on a single line. */
UPB_TXTENC_SINGLELINE = 1,
/* When set, unknown fields are not printed. */
UPB_TXTENC_SKIPUNKNOWN = 2
};
/* Encodes the given |msg| to text format. The message's reflection is given in
* |m|. The symtab in |symtab| is used to find extensions (if NULL, extensions
* will not be printed).
*
* Output is placed in the given buffer, and always NULL-terminated. The output
* size (excluding NULL) is returned. This means that a return value >= |size|
* implies that the output was truncated. (These are the same semantics as
* snprintf()). */
size_t upb_textencode(const upb_msg *msg, const upb_msgdef *m,
const upb_symtab *ext_pool, int options, char *buf,
size_t size);
#endif /* UPB_TEXTENCODE_H_ */

@ -318,14 +318,15 @@ typedef enum {
UPB_TYPE_INT32 = 3,
UPB_TYPE_UINT32 = 4,
UPB_TYPE_ENUM = 5, /* Enum values are int32. */
/* Types stored as pointers (probably 4 or 8 bytes). */
UPB_TYPE_STRING = 6,
UPB_TYPE_BYTES = 7,
UPB_TYPE_MESSAGE = 8,
/* Types stored as void* (probably 4 or 8 bytes). */
UPB_TYPE_MESSAGE = 6,
/* Types stored as 8 bytes. */
UPB_TYPE_DOUBLE = 9,
UPB_TYPE_INT64 = 10,
UPB_TYPE_UINT64 = 11
UPB_TYPE_DOUBLE = 7,
UPB_TYPE_INT64 = 8,
UPB_TYPE_UINT64 = 9,
/* Types stored as upb_strview (2 * void*) (probably 8 or 16 bytes). */
UPB_TYPE_STRING = 10,
UPB_TYPE_BYTES = 11
} upb_fieldtype_t;
/* The repeated-ness of each field; this matches descriptor.proto. */
@ -357,7 +358,7 @@ typedef enum {
UPB_DESCRIPTOR_TYPE_SINT64 = 18
} upb_descriptortype_t;
extern const uint8_t upb_desctype_to_fieldtype[];
#define UPB_MAP_BEGIN -1
#include "upb/port_undef.inc"

@ -331,21 +331,24 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
output("/* $0 */\n\n", message->full_name());
std::string msgname = ToCIdent(message->full_name());
output(
"UPB_INLINE $0 *$0_new(upb_arena *arena) {\n"
" return ($0 *)upb_msg_new(&$1, arena);\n"
"}\n"
"UPB_INLINE $0 *$0_parse(const char *buf, size_t size,\n"
" upb_arena *arena) {\n"
" $0 *ret = $0_new(arena);\n"
" return (ret && upb_decode(buf, size, ret, &$1, arena)) ? ret : NULL;\n"
"}\n"
"UPB_INLINE char *$0_serialize(const $0 *msg, upb_arena *arena, size_t "
"*len) {\n"
" return upb_encode(msg, &$1, arena, len);\n"
"}\n"
"\n",
MessageName(message), MessageInit(message));
if (!message->options().map_entry()) {
output(
"UPB_INLINE $0 *$0_new(upb_arena *arena) {\n"
" return ($0 *)_upb_msg_new(&$1, arena);\n"
"}\n"
"UPB_INLINE $0 *$0_parse(const char *buf, size_t size,\n"
" upb_arena *arena) {\n"
" $0 *ret = $0_new(arena);\n"
" return (ret && upb_decode(buf, size, ret, &$1, arena)) ? ret : NULL;\n"
"}\n"
"UPB_INLINE char *$0_serialize(const $0 *msg, upb_arena *arena, size_t "
"*len) {\n"
" return upb_encode(msg, &$1, arena, len);\n"
"}\n"
"\n",
MessageName(message), MessageInit(message));
}
for (int i = 0; i < message->oneof_decl_count(); i++) {
const protobuf::OneofDescriptor* oneof = message->oneof_decl(i);
@ -367,8 +370,10 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
GetSizeInit(layout.GetOneofCaseOffset(oneof)));
}
for (auto field : FieldNumberOrder(message)) {
// Generate const methods.
for (auto field : FieldNumberOrder(message)) {
// Generate hazzer (if any).
if (layout.HasHasbit(field)) {
output(
"UPB_INLINE bool $0_has_$1(const $0 *msg) { "
@ -383,7 +388,43 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
field->number());
}
if (field->is_repeated()) {
// Generate getter.
if (field->is_map()) {
const protobuf::Descriptor* entry = field->message_type();
const protobuf::FieldDescriptor* key = entry->FindFieldByNumber(1);
const protobuf::FieldDescriptor* val = entry->FindFieldByNumber(2);
output(
"UPB_INLINE size_t $0_$1_size(const $0 *msg) {"
"return _upb_msg_map_size(msg, $2); }\n",
msgname, field->name(), GetSizeInit(layout.GetFieldOffset(field)));
output(
"UPB_INLINE bool $0_$1_get(const $0 *msg, $2 key, $3 *val) { "
"return _upb_msg_map_get(msg, $4, &key, $5, val, $6); }\n",
msgname, field->name(), CType(key), CType(val),
GetSizeInit(layout.GetFieldOffset(field)),
key->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0"
: "sizeof(key)",
val->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0"
: "sizeof(*val)");
output(
"UPB_INLINE $0 $1_$2_next(const $1 *msg, size_t* iter) { "
"return ($0)_upb_msg_map_next(msg, $3, iter); }\n",
CTypeConst(field), msgname, field->name(),
GetSizeInit(layout.GetFieldOffset(field)));
} else if (message->options().map_entry()) {
output(
"UPB_INLINE $0 $1_$2(const $1 *msg) {\n"
" $3 ret;\n"
" _upb_msg_map_$2(msg, &ret, $4);\n"
" return ret;\n"
"}\n",
CTypeConst(field), msgname, field->name(), CType(field),
field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0"
: "sizeof(ret)");
} else if (field->is_repeated()) {
output(
"UPB_INLINE $0 const* $1_$2(const $1 *msg, size_t *len) { "
"return ($0 const*)_upb_array_accessor(msg, $3, len); }\n",
@ -408,8 +449,43 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
output("\n");
// Generate mutable methods.
for (auto field : FieldNumberOrder(message)) {
if (field->is_repeated()) {
if (field->is_map()) {
// TODO(haberman): add map-based mutators.
const protobuf::Descriptor* entry = field->message_type();
const protobuf::FieldDescriptor* key = entry->FindFieldByNumber(1);
const protobuf::FieldDescriptor* val = entry->FindFieldByNumber(2);
output(
"UPB_INLINE void $0_$1_clear($0 *msg) { _upb_msg_map_clear(msg, $2); }\n",
msgname, field->name(),
GetSizeInit(layout.GetFieldOffset(field)));
output(
"UPB_INLINE bool $0_$1_set($0 *msg, $2 key, $3 val, upb_arena *a) { "
"return _upb_msg_map_set(msg, $4, &key, $5, &val, $6, a); }\n",
msgname, field->name(), CType(key), CType(val),
GetSizeInit(layout.GetFieldOffset(field)),
key->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0"
: "sizeof(key)",
val->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0"
: "sizeof(val)");
output(
"UPB_INLINE bool $0_$1_delete($0 *msg, $2 key) { "
"return _upb_msg_map_delete(msg, $3, &key, $4); }\n",
msgname, field->name(), CType(key),
GetSizeInit(layout.GetFieldOffset(field)),
key->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0"
: "sizeof(key)");
output(
"UPB_INLINE $0 $1_$2_nextmutable($1 *msg, size_t* iter) { "
"return ($0)_upb_msg_map_next(msg, $3, iter); }\n",
CType(field), msgname, field->name(),
GetSizeInit(layout.GetFieldOffset(field)));
} else if (field->is_repeated()) {
output(
"UPB_INLINE $0* $1_mutable_$2($1 *msg, size_t *len) {\n"
" return ($0*)_upb_array_mutable_accessor(msg, $3, len);\n"
@ -419,17 +495,15 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
output(
"UPB_INLINE $0* $1_resize_$2($1 *msg, size_t len, "
"upb_arena *arena) {\n"
" return ($0*)_upb_array_resize_accessor(msg, $3, len, $4, $5, "
"arena);\n"
" return ($0*)_upb_array_resize_accessor(msg, $3, len, $4, arena);\n"
"}\n",
CType(field), msgname, field->name(),
GetSizeInit(layout.GetFieldOffset(field)),
GetSizeInit(MessageLayout::SizeOfUnwrapped(field).size),
UpbType(field));
if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
output(
"UPB_INLINE struct $0* $1_add_$2($1 *msg, upb_arena *arena) {\n"
" struct $0* sub = (struct $0*)upb_msg_new(&$3, arena);\n"
" struct $0* sub = (struct $0*)_upb_msg_new(&$3, arena);\n"
" bool ok = _upb_array_append_accessor(\n"
" msg, $4, $5, $6, &sub, arena);\n"
" if (!ok) return NULL;\n"
@ -443,8 +517,8 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
} else {
output(
"UPB_INLINE bool $1_add_$2($1 *msg, $0 val, upb_arena *arena) {\n"
" return _upb_array_append_accessor(\n"
" msg, $3, $4, $5, &val, arena);\n"
" return _upb_array_append_accessor(msg, $3, $4, $5, &val,\n"
" arena);\n"
"}\n",
CType(field), msgname, field->name(),
GetSizeInit(layout.GetFieldOffset(field)),
@ -452,9 +526,25 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
UpbType(field));
}
} else {
// Non-repeated field.
if (message->options().map_entry() && field->name() == "key") {
// Key cannot be mutated.
continue;
}
// The common function signature for all setters. Varying implementations
// follow.
output("UPB_INLINE void $0_set_$1($0 *msg, $2 value) {\n", msgname,
field->name(), CType(field));
if (field->containing_oneof()) {
if (message->options().map_entry()) {
output(
" _upb_msg_map_set_value(msg, &value, $0);\n"
"}\n",
field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0"
: "sizeof(" + CType(field) + ")");
} else if (field->containing_oneof()) {
output(
" UPB_WRITE_ONEOF(msg, $0, $1, value, $2, $3);\n"
"}\n",
@ -470,12 +560,14 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
"}\n",
CType(field), GetSizeInit(layout.GetFieldOffset(field)));
}
if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE &&
!message->options().map_entry()) {
output(
"UPB_INLINE struct $0* $1_mutable_$2($1 *msg, upb_arena *arena) {\n"
" struct $0* sub = (struct $0*)$1_$2(msg);\n"
" if (sub == NULL) {\n"
" sub = (struct $0*)upb_msg_new(&$3, arena);\n"
" sub = (struct $0*)_upb_msg_new(&$3, arena);\n"
" if (!sub) return NULL;\n"
" $1_set_$2(msg, sub);\n"
" }\n"
@ -495,7 +587,6 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
output(
"#ifndef $0_UPB_H_\n"
"#define $0_UPB_H_\n\n"
"#include \"upb/generated_util.h\"\n"
"#include \"upb/msg.h\"\n"
"#include \"upb/decode.h\"\n"
"#include \"upb/encode.h\"\n\n",
@ -661,6 +752,8 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
case_offset.size64 = -case_offset.size64 - 1;
presence = GetSizeInit(case_offset);
}
// Sync '4' with UPB_LABEL_MAP in upb/msg.h.
int label = field->is_map() ? 4 : field->label();
output(" {$0, $1, $2, $3, $4, $5},\n",
field->number(),
@ -668,7 +761,7 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
presence,
submsg_index,
field->type(),
field->label());
label);
}
output("};\n\n");
}
@ -752,12 +845,27 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) {
output("extern upb_def_init $0;\n", DefInitSymbol(file->dependency(i)));
}
std::vector<const protobuf::Descriptor*> file_messages =
SortedMessages(file);
for (auto message : file_messages) {
output("extern const upb_msglayout $0;\n", MessageInit(message));
}
output("\n");
output("static const upb_msglayout *layouts[$0] = {\n", file_messages.size());
for (auto message : file_messages) {
output(" &$0,\n", MessageInit(message));
}
output("};\n");
output("\n");
protobuf::FileDescriptorProto file_proto;
file->CopyTo(&file_proto);
std::string file_data;
file_proto.SerializeToString(&file_data);
output("static const char descriptor[$0] =\n", file_data.size());
output("static const char descriptor[$0] =", file_data.size());
{
if (file_data.size() > 65535) {
@ -777,13 +885,15 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) {
// Only write 40 bytes per line.
static const size_t kBytesPerLine = 40;
for (size_t i = 0; i < file_data.size(); i += kBytesPerLine) {
output("\n");
output(
"\"$0\"\n",
" \"$0\"",
EscapeTrigraphs(absl::CEscape(file_data.substr(i, kBytesPerLine))));
}
}
output(";\n");
}
output("\n");
output("static upb_def_init *deps[$0] = {\n", file->dependency_count() + 1);
for (int i = 0; i < file->dependency_count(); i++) {
@ -791,9 +901,11 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) {
}
output(" NULL\n");
output("};\n");
output("\n");
output("upb_def_init $0 = {\n", DefInitSymbol(file));
output(" deps,\n");
output(" layouts,\n");
output(" \"$0\",\n", file->name());
output(" UPB_STRVIEW_INIT(descriptor, $0)\n", file_data.size());
output("};\n");

@ -1,5 +1,6 @@
#include "upbc/message_layout.h"
#include "google/protobuf/descriptor.pb.h"
namespace upbc {
@ -25,12 +26,18 @@ MessageLayout::Size MessageLayout::Place(
bool MessageLayout::HasHasbit(const protobuf::FieldDescriptor* field) {
return field->file()->syntax() == protobuf::FileDescriptor::SYNTAX_PROTO2 &&
field->label() != protobuf::FieldDescriptor::LABEL_REPEATED &&
!field->containing_oneof();
!field->containing_oneof() &&
!field->containing_type()->options().map_entry();
}
MessageLayout::SizeAndAlign MessageLayout::SizeOf(
const protobuf::FieldDescriptor* field) {
if (field->is_repeated()) {
if (field->containing_type()->options().map_entry()) {
// Map entries aren't actually stored, they are only used during parsing.
// For parsing, it helps a lot if all map entry messages have the same
// layout.
return {{8, 16}, {4, 8}}; // upb_stringview
} else if (field->is_repeated()) {
return {{4, 8}, {4, 8}}; // Pointer to array object.
} else {
return SizeOfUnwrapped(field);

Loading…
Cancel
Save