summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile21
-rw-r--r--benchmarks/parsestream.upb_table.c6
-rw-r--r--benchmarks/parsetostruct.upb_table.c1
-rw-r--r--src/descriptor_const.h24
-rw-r--r--src/upb_decoder.c2
-rw-r--r--src/upb_def.c87
-rw-r--r--src/upb_def.h27
-rw-r--r--src/upb_glue.c3
-rw-r--r--src/upbc.c20
-rw-r--r--tests/test_def.c9
-rw-r--r--tests/test_vs_proto2.cc16
11 files changed, 100 insertions, 116 deletions
diff --git a/Makefile b/Makefile
index f2bd34e..6801f63 100644
--- a/Makefile
+++ b/Makefile
@@ -179,22 +179,28 @@ tests/test.proto.pb: tests/test.proto
@# TODO: replace with upbc
protoc tests/test.proto -otests/test.proto.pb
-TESTS= \
+SIMPLE_TESTS= \
tests/test_string \
- tests/test_table \
tests/test_def \
tests/test_stream \
+ tests/tests
+# tests/test_decoder \
+
+SIMPLE_CXX_TESTS= \
+ tests/test_table
+
+VARIADIC_TESTS= \
tests/t.test_vs_proto2.googlemessage1 \
tests/t.test_vs_proto2.googlemessage2 \
- tests/test.proto.pb \
- tests/tests
-# tests/test_decoder \
+TESTS=$(SIMPLE_TESTS) $(SIMPLE_CXX_TESTS) $(VARIADIC_TESTS)
+
tests: $(TESTS)
$(TESTS): $(LIBUPB)
+tests/tests: tests/test.proto.pb
-% : %.c
+$(SIMPLE_TESTS): % : %.c
$(E) CC $<
$(Q) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
@@ -237,9 +243,6 @@ tests/test_table: tests/test_table.cc
tests/tests: src/libupb.a
-# Tools
-tools: src/upbc
-src/upbc: $(LIBUPB)
# Benchmarks. ##################################################################
diff --git a/benchmarks/parsestream.upb_table.c b/benchmarks/parsestream.upb_table.c
index a646999..85c9ff9 100644
--- a/benchmarks/parsestream.upb_table.c
+++ b/benchmarks/parsestream.upb_table.c
@@ -17,12 +17,6 @@ static bool initialize()
// Initialize upb state, decode descriptor.
upb_status status = UPB_STATUS_INIT;
upb_symtab *s = upb_symtab_new();
- upb_symtab_add_descriptorproto(s);
- upb_def *fds_def = upb_symtab_lookup(
- s, UPB_STRLIT("google.protobuf.FileDescriptorSet"));
- if (!fds_def) {
- fprintf(stderr, "Couldn't load FileDescriptorSet def");
- }
upb_string *fds_str = upb_strreadfile(MESSAGE_DESCRIPTOR_FILE);
if(fds_str == NULL) {
diff --git a/benchmarks/parsetostruct.upb_table.c b/benchmarks/parsetostruct.upb_table.c
index 592f86e..dfdd5b2 100644
--- a/benchmarks/parsetostruct.upb_table.c
+++ b/benchmarks/parsetostruct.upb_table.c
@@ -20,7 +20,6 @@ static bool initialize()
// Initialize upb state, decode descriptor.
upb_status status = UPB_STATUS_INIT;
upb_symtab *s = upb_symtab_new();
- upb_symtab_add_descriptorproto(s);
upb_string *fds_str = upb_strreadfile(MESSAGE_DESCRIPTOR_FILE);
if(fds_str == NULL) {
diff --git a/src/descriptor_const.h b/src/descriptor_const.h
index 44598dc..f02eb75 100644
--- a/src/descriptor_const.h
+++ b/src/descriptor_const.h
@@ -11,8 +11,8 @@ extern "C" {
typedef enum google_protobuf_FieldOptions_CType {
GOOGLE_PROTOBUF_FIELDOPTIONS_STRING = 0,
- GOOGLE_PROTOBUF_FIELDOPTIONS_CORD = 1,
- GOOGLE_PROTOBUF_FIELDOPTIONS_STRING_PIECE = 2
+ GOOGLE_PROTOBUF_FIELDOPTIONS_STRING_PIECE = 2,
+ GOOGLE_PROTOBUF_FIELDOPTIONS_CORD = 1
} google_protobuf_FieldOptions_CType;
typedef enum google_protobuf_FieldDescriptorProto_Type {
@@ -50,10 +50,8 @@ typedef enum google_protobuf_FileOptions_OptimizeMode {
/* Constants for field names and numbers. */
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_FIELDNUM 1
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_FIELDNAME "name_part"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_FIELDNUM 2
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_FIELDNAME "is_extension"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM 1
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNAME "file"
#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_FIELDNUM 1
#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_FIELDNAME "name"
#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_FIELDNUM 2
@@ -132,8 +130,10 @@ typedef enum google_protobuf_FileOptions_OptimizeMode {
#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_FIELDNAME "method"
#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_FIELDNUM 3
#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM 1
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNAME "file"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_FIELDNUM 1
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_FIELDNAME "name_part"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_FIELDNUM 2
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_FIELDNAME "is_extension"
#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_FIELDNUM 1
#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_FIELDNAME "location"
#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START_FIELDNUM 1
@@ -146,14 +146,12 @@ typedef enum google_protobuf_FileOptions_OptimizeMode {
#define GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED_FIELDNAME "packed"
#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED_FIELDNUM 3
#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED_FIELDNAME "deprecated"
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_FIELDNUM 9
#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_FIELDNAME "experimental_map_key"
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_FIELDNUM 1
#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_FIELDNAME "java_package"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_FIELDNUM 8
#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_FIELDNAME "java_outer_classname"
#define GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR_FIELDNUM 9
@@ -168,6 +166,8 @@ typedef enum google_protobuf_FileOptions_OptimizeMode {
#define GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES_FIELDNAME "py_generic_services"
#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH_FIELDNUM 20
#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH_FIELDNAME "java_generate_equals_and_hash"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
+#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT_FIELDNUM 1
#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT_FIELDNAME "message_set_wire_format"
#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR_FIELDNUM 2
diff --git a/src/upb_decoder.c b/src/upb_decoder.c
index 47e67b6..40ab790 100644
--- a/src/upb_decoder.c
+++ b/src/upb_decoder.c
@@ -346,8 +346,8 @@ void upb_decoder_run(upb_src *src, upb_status *status) {
//const char *ptr = d->ptr;
// Decodes as many fields as possible, updating d->ptr appropriately,
// before falling through to the slow(er) path.
- const char *end = UPB_MIN(d->end, d->submsg_end);
#ifdef USE_ASSEMBLY_FASTPATH
+ const char *end = UPB_MIN(d->end, d->submsg_end);
fastdecode_ret ret = upb_fastdecode(d->ptr, end,
d->dispatcher.top->handlers.set->value,
d->dispatcher.top->handlers.closure,
diff --git a/src/upb_def.c b/src/upb_def.c
index 6a1e543..0382610 100644
--- a/src/upb_def.c
+++ b/src/upb_def.c
@@ -859,6 +859,7 @@ static upb_symtab_ent *upb_resolve(upb_strtable *t,
// TODO: This branch is totally broken, but currently not used.
upb_string *sym_str = upb_string_new();
int baselen = upb_string_len(base);
+ upb_symtab_ent *ret = NULL;
while(1) {
// sym_str = base[0...base_len] + UPB_SYMBOL_SEPARATOR + sym
upb_strlen_t len = baselen + upb_string_len(sym) + 1;
@@ -868,11 +869,18 @@ static upb_symtab_ent *upb_resolve(upb_strtable *t,
memcpy(buf + baselen + 1, upb_string_getrobuf(sym), upb_string_len(sym));
upb_symtab_ent *e = upb_strtable_lookup(t, sym_str);
- if (e) return e;
- else if(baselen == 0) return NULL; // No more scopes to try.
-
+ if (e) {
+ ret = e;
+ break;
+ } else if(baselen == 0) {
+ // No more scopes to try.
+ ret = NULL;
+ break;
+ }
baselen = my_memrchr(buf, UPB_SYMBOL_SEPARATOR, baselen);
}
+ upb_string_unref(sym_str);
+ return ret;
}
}
@@ -1307,38 +1315,51 @@ static upb_src *upb_baredecoder_src(upb_baredecoder *d) {
return &d->src;
}
-void upb_symtab_add_descriptorproto(upb_symtab *symtab) {
- // For the moment we silently decline to perform the operation if the symbols
- // already exist in the symtab. Revisit this when we have a better story
- // about whether syms in a table can be replaced.
- if(symtab->fds_msgdef) return;
-
- static upb_string descriptor_str =
- UPB_STATIC_STRING_ARRAY(descriptor_pb);
- upb_baredecoder *decoder = upb_baredecoder_new(&descriptor_str);
- upb_status status = UPB_STATUS_INIT;
- upb_symtab_addfds(symtab, upb_baredecoder_src(decoder), &status);
- upb_baredecoder_free(decoder);
-
- if(!upb_ok(&status)) {
- // upb itself is corrupt.
- upb_printerr(&status);
- upb_clearerr(&status);
- upb_symtab_unref(symtab);
- abort();
+static upb_symtab *descriptor_symtab = NULL;
+
+static void upb_free_descriptor_symtab() {
+ if (descriptor_symtab) {
+ // There should be no way for anyone to acquire a ref on this symtab.
+ assert(upb_atomic_only(&descriptor_symtab->refcount));
+ _upb_symtab_free(descriptor_symtab);
+ descriptor_symtab = NULL;
}
- upb_def *def = upb_symtab_lookup(
- symtab, UPB_STRLIT("google.protobuf.FileDescriptorSet"));
- if (!def || (symtab->fds_msgdef = upb_dyncast_msgdef(def)) == NULL) {
- // upb itself is corrupt.
- abort();
+}
+
+upb_def *upb_getdescriptordef(upb_string *str) {
+ // TODO: add locking.
+ if (descriptor_symtab == NULL) {
+ descriptor_symtab = upb_symtab_new();
+
+ static upb_string descriptor_str =
+ UPB_STATIC_STRING_ARRAY(descriptor_pb);
+ upb_baredecoder *decoder = upb_baredecoder_new(&descriptor_str);
+ upb_status status = UPB_STATUS_INIT;
+ upb_symtab_addfds(descriptor_symtab, upb_baredecoder_src(decoder), &status);
+ upb_baredecoder_free(decoder);
+
+ if(!upb_ok(&status)) {
+ // upb itself is corrupt.
+ upb_printerr(&status);
+ upb_clearerr(&status);
+ abort();
+ }
+ upb_status_uninit(&status);
+
+ // As a sanity check, make sure that FileDescriptorSet was loaded.
+ upb_msgdef *def = upb_getfdsdef();
+ if (!def) {
+ // upb itself is corrupt.
+ abort();
+ }
+ upb_def_unref(UPB_UPCAST(def)); // The symtab already holds a ref on it.
+ atexit(upb_free_descriptor_symtab);
}
- upb_def_unref(def); // The symtab already holds a ref on it.
- upb_status_uninit(&status);
+ return upb_symtab_resolve(
+ descriptor_symtab, UPB_STRLIT("google.protobuf"), str);
}
-upb_msgdef *upb_symtab_fds_def(upb_symtab *s) {
- assert(s->fds_msgdef != NULL);
- upb_def_ref(UPB_UPCAST(s->fds_msgdef));
- return s->fds_msgdef;
+upb_msgdef *upb_getfdsdef() {
+ return upb_downcast_msgdef(
+ upb_getdescriptordef(UPB_STRLIT("FileDescriptorSet")));
}
diff --git a/src/upb_def.h b/src/upb_def.h
index db33fbb..121d5bc 100644
--- a/src/upb_def.h
+++ b/src/upb_def.h
@@ -276,7 +276,7 @@ void _upb_symtab_free(upb_symtab *s); // Must not be called directly!
INLINE void upb_symtab_ref(upb_symtab *s) { upb_atomic_ref(&s->refcount); }
INLINE void upb_symtab_unref(upb_symtab *s) {
- if(upb_atomic_unref(&s->refcount)) _upb_symtab_free(s);
+ if(s && upb_atomic_unref(&s->refcount)) _upb_symtab_free(s);
}
// Resolves the given symbol using the rules described in descriptor.proto,
@@ -314,17 +314,20 @@ upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_deftype_t type);
// more useful? Maybe it should be an option.
void upb_symtab_addfds(upb_symtab *s, upb_src *desc, upb_status *status);
-// Adds defs for google.protobuf.FileDescriptorSet and friends to this symtab.
-// This is necessary for bootstrapping, since these are the upb_defs that
-// specify other defs and allow them to be loaded.
-void upb_symtab_add_descriptorproto(upb_symtab *s);
-
-// Returns the upb_msgdef for google.protobuf.FileDescriptorSet, which the
-// caller owns a ref on. This is a convenience method that is equivalent to
-// looking up the symbol called "google.protobuf.FileDescriptorSet" yourself,
-// except that it only will return a def that was added by
-// upb_symtab_add_descriptorproto().
-upb_msgdef *upb_symtab_fds_def(upb_symtab *s);
+// Returns a def corresponding to the given name, from descriptor.proto.
+// upb internally bootstraps the defs in descriptor.proto, since they are
+// necessary for loading other descriptors. The caller owns a ref on the
+// returned def (which is NULL if no such def exists in descriptor.proto).
+//
+// The name should *not* be qualified by the package, to promote
+// interoperability between the internal and external releases of Protocol
+// Buffers (inside Google, these are in the "proto2" package, externally they
+// are in "google.protobuf".
+upb_def *upb_getdescriptordef(upb_string *str);
+
+// A convenience method for getting the upb_def for FileDescriptorProto.
+// Return should never be NULL.
+upb_msgdef *upb_getfdsdef();
/* upb_def casts **************************************************************/
diff --git a/src/upb_glue.c b/src/upb_glue.c
index 536adc0..a3d4e7d 100644
--- a/src/upb_glue.c
+++ b/src/upb_glue.c
@@ -38,13 +38,12 @@ void upb_strtomsg(upb_string *str, upb_msg *msg, upb_msgdef *md,
}
void upb_parsedesc(upb_symtab *symtab, upb_string *str, upb_status *status) {
- upb_symtab_add_descriptorproto(symtab);
upb_stringsrc strsrc;
upb_stringsrc_init(&strsrc);
upb_stringsrc_reset(&strsrc, str);
upb_decoder d;
- upb_msgdef *fds_msgdef = upb_symtab_fds_def(symtab);
+ upb_msgdef *fds_msgdef = upb_getfdsdef();
upb_decoder_init(&d, fds_msgdef);
upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc));
diff --git a/src/upbc.c b/src/upbc.c
index 4cfa6e6..428ec41 100644
--- a/src/upbc.c
+++ b/src/upbc.c
@@ -191,29 +191,12 @@ int main(int argc, char *argv[])
// TODO: make upb_parsedesc use a separate symtab, so we can use it here when
// importing descriptor.proto.
upb_symtab *s = upb_symtab_new();
- upb_symtab_add_descriptorproto(s);
- upb_symtab *s2 = upb_symtab_new();
upb_status status = UPB_STATUS_INIT;
-
- upb_stringsrc strsrc;
- upb_stringsrc_init(&strsrc);
- upb_stringsrc_reset(&strsrc, descriptor);
-
- upb_decoder d;
- upb_msgdef *fds_msgdef = upb_symtab_fds_def(s);
- upb_decoder_init(&d, fds_msgdef);
- upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc));
-
- upb_symtab_addfds(s2, upb_decoder_src(&d), &status);
- upb_stringsrc_uninit(&strsrc);
- upb_decoder_uninit(&d);
- upb_def_unref(UPB_UPCAST(fds_msgdef));
-
+ upb_parsedesc(s, descriptor, &status);
if(!upb_ok(&status)) {
upb_printerr(&status);
error("Failed to parse input file descriptor\n");
}
-
upb_status_uninit(&status);
/* Emit output files. */
@@ -232,7 +215,6 @@ int main(int argc, char *argv[])
free(defs);
upb_string_unref(descriptor);
upb_symtab_unref(s);
- upb_symtab_unref(s2);
fclose(h_const_file);
return 0;
diff --git a/tests/test_def.c b/tests/test_def.c
index 2d2658f..287cc32 100644
--- a/tests/test_def.c
+++ b/tests/test_def.c
@@ -5,8 +5,8 @@
int main() {
upb_symtab *s = upb_symtab_new();
- upb_symtab_add_descriptorproto(s);
+ // Will be empty atm since we haven't added anything to the symtab.
int count;
upb_def **defs = upb_symtab_getdefs(s, &count, UPB_DEF_ANY);
for (int i = 0; i < count; i++) {
@@ -14,12 +14,9 @@ int main() {
}
free(defs);
- upb_string *str = upb_strdupc("google.protobuf.FileDescriptorSet");
- upb_def *fds = upb_symtab_lookup(s, str);
+ upb_msgdef *fds = upb_getfdsdef();
assert(fds != NULL);
- assert(upb_dyncast_msgdef(fds) != NULL);
- upb_def_unref(fds);
- upb_string_unref(str);
+ upb_def_unref(UPB_UPCAST(fds));
upb_symtab_unref(s);
return 0;
}
diff --git a/tests/test_vs_proto2.cc b/tests/test_vs_proto2.cc
index 749eedf..1839123 100644
--- a/tests/test_vs_proto2.cc
+++ b/tests/test_vs_proto2.cc
@@ -213,26 +213,13 @@ int main(int argc, char *argv[])
fprintf(stderr, "Couldn't read " MESSAGE_DESCRIPTOR_FILE ".\n");
return 1;
}
- upb_symtab_add_descriptorproto(symtab);
- upb_def *fds_msgdef = upb_symtab_lookup(
- symtab, UPB_STRLIT("google.protobuf.FileDescriptorSet"));
- assert(fds_msgdef);
-
- upb_stringsrc ssrc;
- upb_stringsrc_init(&ssrc);
- upb_stringsrc_reset(&ssrc, fds);
- upb_decoder decoder;
- upb_decoder_init(&decoder, upb_downcast_msgdef(fds_msgdef));
- upb_decoder_reset(&decoder, upb_stringsrc_bytesrc(&ssrc));
- upb_symtab_addfds(symtab, upb_decoder_src(&decoder), &status);
+ upb_parsedesc(symtab, fds, &status);
if(!upb_ok(&status)) {
fprintf(stderr, "Error importing " MESSAGE_DESCRIPTOR_FILE ": ");
upb_printerr(&status);
return 1;
}
upb_string_unref(fds);
- upb_decoder_uninit(&decoder);
- upb_stringsrc_uninit(&ssrc);
upb_string *proto_name = upb_strdupc(MESSAGE_NAME);
upb_def *def = upb_symtab_lookup(symtab, proto_name);
@@ -260,7 +247,6 @@ int main(int argc, char *argv[])
upb_msg_unref(upb_msg, msgdef);
upb_def_unref(UPB_UPCAST(msgdef));
- upb_def_unref(fds_msgdef);
upb_string_unref(str);
upb_symtab_unref(symtab);
upb_status_uninit(&status);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback