Merge pull request #224 from haberman/maps

Implemented support for maps (generated & reflection), and improved reflection API
pull/13171/head
Joshua Haberman 5 years ago committed by GitHub
commit 9e1f89ef2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 122
      BUILD
  2. 13
      CMakeLists.txt
  3. 91
      bazel/build_defs.bzl
  4. 71
      bazel/upb_proto_library.bzl
  5. 237
      generated_for_cmake/google/protobuf/descriptor.upb.h
  6. 165
      tests/bindings/googlepb/test_vs_proto2.cc
  7. 56
      tests/bindings/lua/main.c
  8. 932
      tests/bindings/lua/test_upb.lua
  9. 80
      tests/bindings/lua/test_upb.pb.lua
  10. 62
      tests/bindings/ruby/upb.rb
  11. BIN
      tests/google_message1.dat
  12. BIN
      tests/google_message2.dat
  13. 149
      tests/google_messages.proto
  14. 33
      tests/pb/test_varint.c
  15. BIN
      tests/test.proto.pb
  16. 329
      tests/test_generated_code.c
  17. 3
      tests/test_table.cc
  18. 13
      tools/make_cmakelists.py
  19. 453
      upb/bindings/lua/def.c
  20. 109
      upb/bindings/lua/lua_proto_library.bzl
  21. 1266
      upb/bindings/lua/msg.c
  22. 168
      upb/bindings/lua/upb.c
  23. 119
      upb/bindings/lua/upb.h
  24. 182
      upb/bindings/lua/upb.lua
  25. 56
      upb/bindings/lua/upb/pb.c
  26. 3
      upb/bindings/lua/upb/pb.lua
  27. 112
      upb/bindings/lua/upbc.cc
  28. 92
      upb/decode.c
  29. 265
      upb/def.c
  30. 7
      upb/def.h
  31. 203
      upb/encode.c
  32. 105
      upb/generated_util.h
  33. 19
      upb/json/printer.c
  34. 399
      upb/legacy_msg_reflection.c
  35. 191
      upb/legacy_msg_reflection.h
  36. 147
      upb/msg.c
  37. 351
      upb/msg.h
  38. 248
      upb/msgfactory.c
  39. 48
      upb/msgfactory.h
  40. 20
      upb/pb/varint.int.h
  41. 5
      upb/port_def.inc
  42. 1
      upb/port_undef.inc
  43. 251
      upb/reflection.c
  44. 126
      upb/reflection.h
  45. 92
      upb/table.c
  46. 54
      upb/table.int.h
  47. 17
      upb/upb.h
  48. 146
      upbc/generator.cc
  49. 11
      upbc/message_layout.cc

122
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": [],
@ -156,24 +155,6 @@ cc_library(
# Legacy C/C++ Libraries (not recommended for new code) ########################
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
}),
deps = [
":port",
":table",
":upb",
],
)
cc_library(
name = "handlers",
srcs = [
@ -359,6 +340,15 @@ cc_test(
],
)
cc_test(
name = "test_generated_code",
srcs = ["tests/test_generated_code.c"],
deps = [
":test_messages_proto3_proto_upb",
":upb_test",
],
)
proto_library(
name = "test_decoder_proto",
srcs = [
@ -563,6 +553,7 @@ sh_test(
":conformance_upb",
"@com_google_protobuf//:conformance_test_runner",
],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
# copybara:strip_for_google3_begin
@ -602,10 +593,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 +606,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 +682,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,9 +80,9 @@ 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
@ -93,14 +92,6 @@ 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
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);

@ -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

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");
}
typedef struct {
const void* def; /* upb_msgdef, upb_enumdef, upb_oneofdef, etc. */
} lupb_wrapper;
memcpy(&ret, ud, sizeof(ret));
if (!ret) {
luaL_error(L, "called into dead object");
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;
}
luaL_checkudata(L, narg, type);
return ret;
static void lupb_wrapper_pushsymtab(lua_State *L, int narg) {
lua_getiuservalue(L, narg, LUPB_SYMTAB_INDEX);
}
void lupb_pushwrapper(lua_State *L, const void *obj, const char *type) {
void *ud;
if (obj == NULL) {
lua_pushnil(L);
return;
/* 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. */
}
/* 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);
/* 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. */
}
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_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);
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) {
switch (lua_type(L, 2)) {
case LUA_TNUMBER:
f = upb_oneofdef_itof(o, lua_tointeger(L, 2));
} else if (type == LUA_TSTRING) {
break;
case LUA_TSTRING:
f = upb_oneofdef_ntofz(o, lua_tostring(L, 2));
} else {
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) {
switch (lua_type(L, 2)) {
case LUA_TNUMBER:
f = upb_msgdef_itof(m, lua_tointeger(L, 2));
} else if (type == LUA_TSTRING) {
break;
case LUA_TSTRING:
f = upb_msgdef_ntofz(m, lua_tostring(L, 2));
} else {
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,14 +483,30 @@ 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. */
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));
} else if (type == LUA_TSTRING) {
break;
}
case LUA_TSTRING: {
const char *key = lua_tostring(L, 2);
int32_t num;
if (upb_enumdef_ntoiz(e, key, &num)) {
@ -476,11 +514,15 @@ static int lupb_enumdef_value(lua_State *L) {
} else {
lua_pushnil(L);
}
} else {
break;
}
default: {
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. */
#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;
}
}
return NULL; /* value is not a userdata with a metatable */
/* Shims for upcoming Lua 5.3 functionality. */
static bool lua_isinteger(lua_State *L, int argn) {
LUPB_UNUSED(L);
LUPB_UNUSED(argn);
return false;
}
static void lupb_newlib(lua_State *L, const char *name, const luaL_Reg *funcs) {
luaL_register(L, name, funcs);
}
#elif LUA_VERSION_NUM == 502
/* Utility functions **********************************************************/
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);
void lupb_checkstatus(lua_State *L, upb_status *s) {
if (!upb_ok(s)) {
lua_pushstring(L, upb_status_errmsg(s));
lua_error(L);
}
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);
}
/* 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
#error Only Lua 5.1 and 5.2 are supported
void *ret = lua_newuserdata(L, size);
lua_createtable(L, 0, n);
lua_setuservalue(L, -2);
#endif
/* Shims for upcoming Lua 5.3 functionality. */
bool lua_isinteger(lua_State *L, int argn) {
UPB_UNUSED(L);
UPB_UNUSED(argn);
return false;
}
/* Set metatable. */
luaL_getmetatable(L, type);
assert(!lua_isnil(L, -1)); /* Should have been created by luaopen_upb. */
lua_setmetatable(L, -2);
/* Utility functions **********************************************************/
return ret;
}
/* 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 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;
}
lupb_newlib(L, name, funcs);
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
/* Save module table in cache. */
lua_pushlightuserdata(L, ptr);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);
void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
const luaL_Reg *mm) {
luaL_newmetatable(L, name);
return false;
if (mm) {
lupb_setfuncs(L, mm);
}
void lupb_checkstatus(lua_State *L, upb_status *s) {
if (!upb_ok(s)) {
lua_pushstring(L, upb_status_errmsg(s));
lua_error(L);
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. */
}
/* 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
local module_metatable = {
__index = function(t, k)
local package = t._filedef:package()
if package then
k = package .. "." .. k
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)
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,6 +28,29 @@ 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. */
@ -166,35 +189,12 @@ static bool upb_skip_unknowngroup(upb_decstate *d, int field_number) {
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,
@ -219,7 +219,8 @@ static upb_array *upb_getorcreatearr(upb_decframe *frame,
upb_array *arr = upb_getarr(frame, field);
if (!arr) {
arr = upb_array_new(frame->state->arena);
upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype];
arr = _upb_array_new(frame->state->arena, type);
CHK(arr);
*(upb_array**)&frame->msg[field->offset] = arr;
}
@ -236,7 +237,7 @@ static upb_msg *upb_getorcreatemsg(upb_decframe *frame,
UPB_ASSERT(field->label != UPB_LABEL_REPEATED);
if (!*submsg) {
*submsg = upb_msg_new(*subm, frame->state->arena);
*submsg = _upb_msg_new(*subm, frame->state->arena);
CHK(*submsg);
}
@ -254,7 +255,7 @@ static upb_msg *upb_addmsg(upb_decframe *frame,
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(*subm, frame->state->arena);
CHK(submsg);
upb_array_add(arr, 1, sizeof(submsg), &submsg, frame->state->arena);
@ -487,6 +488,35 @@ static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
UPB_UNREACHABLE();
}
static bool upb_decode_mapfield(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field, int len) {
upb_map *map = *(upb_map**)&frame->msg[field->offset];
const upb_msglayout *entry = frame->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(frame->state->arena, key_size, val_size);
*(upb_map**)&frame->msg[field->offset] = map;
}
/* Parse map entry. */
memset(&ent, 0, sizeof(ent));
CHK(upb_decode_msgfield(d, &ent.k, entry, len));
/* Insert into map. */
_upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena);
return true;
}
static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
const upb_msglayout_field *field) {
int len;
@ -495,6 +525,8 @@ static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
if (field->label == UPB_LABEL_REPEATED) {
return upb_decode_toarray(d, frame, field, len);
} else if (field->label == UPB_LABEL_MAP) {
return upb_decode_mapfield(d, frame, field, len);
} else {
switch (field->descriptortype) {
case UPB_DESCRIPTOR_TYPE_STRING:

@ -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;
}
@ -697,6 +703,10 @@ 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;
}
bool upb_msgdef_mapentry(const upb_msgdef *m) {
return m->map_entry;
}
@ -819,6 +829,192 @@ 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)) {
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
@ -834,7 +1030,8 @@ typedef struct {
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_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;
@ -990,7 +1187,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 +1200,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 +1318,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;
}
}
assert(found);
}
} else {
/* extension field. */
f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count];
@ -1257,7 +1469,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 +1499,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 +1653,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 +1767,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 +1780,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 +1801,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 +1905,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 +1924,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 +1936,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 +1977,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,7 @@ 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);
UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m,
const char *name) {
@ -851,9 +853,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,80 +312,39 @@ do { ; } while(0)
return true;
}
static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
static bool upb_encode_map(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)
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) {
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;
}
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: {
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;
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);
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));
}
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();
}
bool upb_encode_message(upb_encstate *e, const char *msg,
const upb_msglayout *m, size_t *size) {
@ -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_ */

@ -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);
@ -108,4 +99,98 @@ const char *upb_msg_getunknown(const upb_msg *msg, size_t *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 *******************************************************************/
/* 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;
/* 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_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 {
void *data; /* Each element is element_size. */
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_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) {
return (void*)((uintptr_t)arr->data & ~7UL);
}
void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
upb_arena *arena);
const char *upb_msg_getunknown(const upb_msg *msg, size_t *len);
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_array *upb_array_new(upb_arena *a);
/** 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_ */

@ -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

@ -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

@ -0,0 +1,251 @@
#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);
}
bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
UPB_ASSERT(field->presence);
if (in_oneof(field)) {
return *oneofcase(msg, field) == field->number;
} else {
uint32_t hasbit = field->presence;
return *PTR_AT(msg, hasbit / 8, char) | (1 << (hasbit % 8));
}
}
upb_msgval upb_msg_get(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;
if (field->presence == 0 || upb_msg_has(msg, f)) {
int size = upb_fielddef_isseq(f) ? sizeof(void *)
: field_size[field->descriptortype];
memcpy(&val, mem, size);
} else {
/* TODO(haberman): change upb_fielddef to not require this switch(). */
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;
}
}
#undef DEREF
/** 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,126 @@
#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);
/** 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)) {
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);

@ -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,9 +331,11 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
output("/* $0 */\n\n", message->full_name());
std::string msgname = ToCIdent(message->full_name());
if (!message->options().map_entry()) {
output(
"UPB_INLINE $0 *$0_new(upb_arena *arena) {\n"
" return ($0 *)upb_msg_new(&$1, 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"
@ -346,6 +348,7 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
"}\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