Support for proto3 optional. (#270)

* Added support for proto3 optional to defs.

* Added proto3 optional support. Untested at the moment.

* Changes to support proto3 optional.

* Fixed real oneof count for messages with no fields.

* Fixed compile error and test.

* Added comment about why I'm commenting out the assert.
pull/13171/head
Joshua Haberman 5 years ago committed by GitHub
parent d638d74d1b
commit 0842f88211
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      bazel/workspace_deps.bzl
  2. 17
      generated_for_cmake/google/protobuf/descriptor.upb.c
  3. 54
      generated_for_cmake/google/protobuf/descriptor.upb.h
  4. 2
      generated_for_cmake/upb/json/parser.c
  5. 76
      upb/def.c
  6. 8
      upb/def.h
  7. 4
      upb/json/parser.rl
  8. 24
      upbc/generator.cc

@ -13,14 +13,10 @@ def upb_deps():
) )
maybe( maybe(
http_archive, git_repository,
name = "com_google_protobuf", name = "com_google_protobuf",
sha256 = "a79d19dcdf9139fa4b81206e318e33d245c4c9da1ffed21c87288ed4380426f9", remote = "https://github.com/protocolbuffers/protobuf.git",
strip_prefix = "protobuf-3.11.4", commit = "62832897c3cf14c93b91c412f7e64086cd272cb7", # Need to use Git until proto3 optional is released
urls = [
"https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v3.11.4.tar.gz",
"https://github.com/protocolbuffers/protobuf/archive/v3.11.4.tar.gz",
],
) )
maybe( maybe(

@ -130,23 +130,24 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1
&google_protobuf_FieldOptions_msginit, &google_protobuf_FieldOptions_msginit,
}; };
static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = { static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
{1, UPB_SIZE(32, 32), 5, 0, 9, 1}, {1, UPB_SIZE(36, 40), 6, 0, 9, 1},
{2, UPB_SIZE(40, 48), 6, 0, 9, 1}, {2, UPB_SIZE(44, 56), 7, 0, 9, 1},
{3, UPB_SIZE(24, 24), 3, 0, 5, 1}, {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
{4, UPB_SIZE(8, 8), 1, 0, 14, 1}, {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
{5, UPB_SIZE(16, 16), 2, 0, 14, 1}, {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
{6, UPB_SIZE(48, 64), 7, 0, 9, 1}, {6, UPB_SIZE(52, 72), 8, 0, 9, 1},
{7, UPB_SIZE(56, 80), 8, 0, 9, 1}, {7, UPB_SIZE(60, 88), 9, 0, 9, 1},
{8, UPB_SIZE(72, 112), 10, 0, 11, 1}, {8, UPB_SIZE(76, 120), 11, 0, 11, 1},
{9, UPB_SIZE(28, 28), 4, 0, 5, 1}, {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
{10, UPB_SIZE(64, 96), 9, 0, 9, 1}, {10, UPB_SIZE(68, 104), 10, 0, 9, 1},
{17, UPB_SIZE(32, 32), 5, 0, 8, 1},
}; };
const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
&google_protobuf_FieldDescriptorProto_submsgs[0], &google_protobuf_FieldDescriptorProto_submsgs[0],
&google_protobuf_FieldDescriptorProto__fields[0], &google_protobuf_FieldDescriptorProto__fields[0],
UPB_SIZE(80, 128), 10, false, UPB_SIZE(80, 128), 11, false,
}; };
static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {

@ -610,34 +610,36 @@ UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_pro
return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len); return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len);
} }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); } UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); } UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview); } UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 80), upb_strview); } UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 11); }
UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 112), const google_protobuf_FieldOptions*); } UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), const google_protobuf_FieldOptions*); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); }
UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); }
UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 96), upb_strview); } UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); }
UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool); }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
_upb_sethas(msg, 5); _upb_sethas(msg, 6);
*UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value; *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview) = value;
} }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
_upb_sethas(msg, 6); _upb_sethas(msg, 7);
*UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview) = value; *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview) = value;
} }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
_upb_sethas(msg, 3); _upb_sethas(msg, 3);
@ -652,16 +654,16 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_Fi
*UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value; *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
} }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
_upb_sethas(msg, 7); _upb_sethas(msg, 8);
*UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview) = value; *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview) = value;
} }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
_upb_sethas(msg, 8); _upb_sethas(msg, 9);
*UPB_PTR_AT(msg, UPB_SIZE(56, 80), upb_strview) = value; *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview) = value;
} }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) {
_upb_sethas(msg, 10); _upb_sethas(msg, 11);
*UPB_PTR_AT(msg, UPB_SIZE(72, 112), google_protobuf_FieldOptions*) = value; *UPB_PTR_AT(msg, UPB_SIZE(76, 120), google_protobuf_FieldOptions*) = value;
} }
UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) { 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); struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg);
@ -677,8 +679,12 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_prot
*UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t) = value; *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t) = value;
} }
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
_upb_sethas(msg, 9); _upb_sethas(msg, 10);
*UPB_PTR_AT(msg, UPB_SIZE(64, 96), upb_strview) = value; *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview) = value;
}
UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) {
_upb_sethas(msg, 5);
*UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool) = value;
} }
/* google.protobuf.OneofDescriptorProto */ /* google.protobuf.OneofDescriptorProto */

@ -735,7 +735,7 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
/* Note: this invalidates the accumulate buffer! Call only after reading its /* Note: this invalidates the accumulate buffer! Call only after reading its
* contents. */ * contents. */
static void multipart_end(upb_json_parser *p) { static void multipart_end(upb_json_parser *p) {
UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); /* UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); */
p->multipart_state = MULTIPART_INACTIVE; p->multipart_state = MULTIPART_INACTIVE;
accumulate_clear(p); accumulate_clear(p);
} }

@ -49,6 +49,7 @@ struct upb_fielddef {
bool is_extension_; bool is_extension_;
bool lazy_; bool lazy_;
bool packed_; bool packed_;
bool proto3_optional_;
upb_descriptortype_t type_; upb_descriptortype_t type_;
upb_label_t label_; upb_label_t label_;
}; };
@ -68,6 +69,7 @@ struct upb_msgdef {
const upb_oneofdef *oneofs; const upb_oneofdef *oneofs;
int field_count; int field_count;
int oneof_count; int oneof_count;
int real_oneof_count;
/* Is this a map-entry message? */ /* Is this a map-entry message? */
bool map_entry; bool map_entry;
@ -247,7 +249,6 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
/* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
* lowest indexes, but we do not publicly guarantee this. */ * lowest indexes, but we do not publicly guarantee this. */
upb_msg_field_iter j; upb_msg_field_iter j;
upb_msg_oneof_iter k;
int i; int i;
uint32_t selector; uint32_t selector;
int n = upb_msgdef_numfields(m); int n = upb_msgdef_numfields(m);
@ -288,14 +289,38 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
} }
m->selector_count = selector; m->selector_count = selector;
for(upb_msg_oneof_begin(&k, m), i = 0; upb_gfree(fields);
!upb_msg_oneof_done(&k); return true;
upb_msg_oneof_next(&k), i++) { }
upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k);
o->index = i; static bool check_oneofs(upb_msgdef *m, upb_status *s) {
int i;
int first_synthetic = -1;
upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs;
for (i = 0; i < m->oneof_count; i++) {
mutable_oneofs[i].index = i;
if (upb_oneofdef_issynthetic(&mutable_oneofs[i])) {
if (first_synthetic == -1) {
first_synthetic = i;
}
} else {
if (first_synthetic != -1) {
upb_status_seterrf(
s, "Synthetic oneofs must be after all other oneofs: %s",
upb_oneofdef_name(&mutable_oneofs[i]));
return false;
}
}
}
if (first_synthetic == -1) {
m->real_oneof_count = m->oneof_count;
} else {
m->real_oneof_count = first_synthetic;
} }
upb_gfree(fields);
return true; return true;
} }
@ -480,6 +505,10 @@ uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) {
return f->selector_base; return f->selector_base;
} }
const upb_filedef *upb_fielddef_file(const upb_fielddef *f) {
return f->file;
}
const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
return f->msgdef; return f->msgdef;
} }
@ -488,6 +517,11 @@ const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
return f->oneof; return f->oneof;
} }
const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) {
if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL;
return f->oneof;
}
static void chkdefaulttype(const upb_fielddef *f, int ctype) { static void chkdefaulttype(const upb_fielddef *f, int ctype) {
UPB_UNUSED(f); UPB_UNUSED(f);
UPB_UNUSED(ctype); UPB_UNUSED(ctype);
@ -584,9 +618,8 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f) {
bool upb_fielddef_haspresence(const upb_fielddef *f) { bool upb_fielddef_haspresence(const upb_fielddef *f) {
if (upb_fielddef_isseq(f)) return false; if (upb_fielddef_isseq(f)) return false;
if (upb_fielddef_issubmsg(f)) return true; return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) ||
if (upb_fielddef_containingoneof(f)) return true; f->file->syntax == UPB_SYNTAX_PROTO2;
return f->file->syntax == UPB_SYNTAX_PROTO2;
} }
static bool between(int32_t x, int32_t low, int32_t high) { static bool between(int32_t x, int32_t low, int32_t high) {
@ -691,6 +724,10 @@ int upb_msgdef_numoneofs(const upb_msgdef *m) {
return m->oneof_count; return m->oneof_count;
} }
int upb_msgdef_numrealoneofs(const upb_msgdef *m) {
return m->real_oneof_count;
}
const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) { const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) {
return m->layout; return m->layout;
} }
@ -789,6 +826,16 @@ uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
return o->index; return o->index;
} }
bool upb_oneofdef_issynthetic(const upb_oneofdef *o) {
upb_inttable_iter iter;
const upb_fielddef *f;
upb_inttable_begin(&iter, &o->itof);
if (upb_oneofdef_numfields(o) != 1) return false;
f = upb_value_getptr(upb_inttable_iter_value(&iter));
UPB_ASSERT(f);
return f->proto3_optional_;
}
const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
const char *name, size_t length) { const char *name, size_t length) {
upb_value val; upb_value val;
@ -971,7 +1018,7 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
submsgs[field->submsg_index] = subm->layout; submsgs[field->submsg_index] = subm->layout;
} }
if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) { if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) {
/* We don't use hasbit 0, so that 0 can indicate "no presence" in the /* We don't use hasbit 0, so that 0 can indicate "no presence" in the
* table. This wastes one hasbit, but we don't worry about it for now. */ * table. This wastes one hasbit, but we don't worry about it for now. */
field->presence = ++hasbit; field->presence = ++hasbit;
@ -990,7 +1037,7 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
size_t field_size = upb_msg_fielddefsize(f); size_t field_size = upb_msg_fielddefsize(f);
size_t index = upb_fielddef_index(f); size_t index = upb_fielddef_index(f);
if (upb_fielddef_containingoneof(f)) { if (upb_fielddef_realcontainingoneof(f)) {
/* Oneofs are handled separately below. */ /* Oneofs are handled separately below. */
continue; continue;
} }
@ -1010,6 +1057,8 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
uint32_t case_offset; uint32_t case_offset;
uint32_t data_offset; uint32_t data_offset;
if (upb_oneofdef_issynthetic(o)) continue;
/* Calculate field size: the max of all field sizes. */ /* Calculate field size: the max of all field sizes. */
for (upb_oneof_begin(&fit, o); for (upb_oneof_begin(&fit, o);
!upb_oneof_done(&fit); !upb_oneof_done(&fit);
@ -1439,6 +1488,8 @@ static bool create_fielddef(
f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
f->number_ = field_number; f->number_ = field_number;
f->oneof = NULL; f->oneof = NULL;
f->proto3_optional_ =
google_protobuf_FieldDescriptorProto_proto3_optional(field_proto);
/* We can't resolve the subdef or (in the case of extensions) the containing /* We can't resolve the subdef or (in the case of extensions) the containing
* message yet, because it may not have been defined yet. We stash a pointer * message yet, because it may not have been defined yet. We stash a pointer
@ -1615,6 +1666,7 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
} }
CHK(assign_msg_indices(m, ctx->status)); CHK(assign_msg_indices(m, ctx->status));
CHK(check_oneofs(m, ctx->status));
assign_msg_wellknowntype(m); assign_msg_wellknowntype(m);
upb_inttable_compact2(&m->itof, ctx->alloc); upb_inttable_compact2(&m->itof, ctx->alloc);

@ -84,8 +84,10 @@ const char *upb_fielddef_jsonname(const upb_fielddef *f);
bool upb_fielddef_isextension(const upb_fielddef *f); bool upb_fielddef_isextension(const upb_fielddef *f);
bool upb_fielddef_lazy(const upb_fielddef *f); bool upb_fielddef_lazy(const upb_fielddef *f);
bool upb_fielddef_packed(const upb_fielddef *f); bool upb_fielddef_packed(const upb_fielddef *f);
const upb_filedef *upb_fielddef_file(const upb_fielddef *f);
const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f); const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f);
const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f); const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f);
const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f);
uint32_t upb_fielddef_index(const upb_fielddef *f); uint32_t upb_fielddef_index(const upb_fielddef *f);
bool upb_fielddef_issubmsg(const upb_fielddef *f); bool upb_fielddef_issubmsg(const upb_fielddef *f);
bool upb_fielddef_isstring(const upb_fielddef *f); bool upb_fielddef_isstring(const upb_fielddef *f);
@ -117,6 +119,7 @@ const char *upb_oneofdef_name(const upb_oneofdef *o);
const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o); const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o);
int upb_oneofdef_numfields(const upb_oneofdef *o); int upb_oneofdef_numfields(const upb_oneofdef *o);
uint32_t upb_oneofdef_index(const upb_oneofdef *o); uint32_t upb_oneofdef_index(const upb_oneofdef *o);
bool upb_oneofdef_issynthetic(const upb_oneofdef *o);
/* Oneof lookups: /* Oneof lookups:
* - ntof: look up a field by name. * - ntof: look up a field by name.
@ -167,19 +170,18 @@ typedef upb_strtable_iter upb_msg_oneof_iter;
const char *upb_msgdef_fullname(const upb_msgdef *m); const char *upb_msgdef_fullname(const upb_msgdef *m);
const upb_filedef *upb_msgdef_file(const upb_msgdef *m); const upb_filedef *upb_msgdef_file(const upb_msgdef *m);
const char *upb_msgdef_name(const upb_msgdef *m); const char *upb_msgdef_name(const upb_msgdef *m);
int upb_msgdef_numfields(const upb_msgdef *m);
int upb_msgdef_numoneofs(const upb_msgdef *m); int upb_msgdef_numoneofs(const upb_msgdef *m);
int upb_msgdef_numrealoneofs(const upb_msgdef *m);
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m);
bool upb_msgdef_mapentry(const upb_msgdef *m); bool upb_msgdef_mapentry(const upb_msgdef *m);
upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m);
bool upb_msgdef_isnumberwrapper(const upb_msgdef *m); bool upb_msgdef_isnumberwrapper(const upb_msgdef *m);
bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax);
const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i); const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i);
const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
size_t len); size_t len);
const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
size_t len); size_t len);
int upb_msgdef_numfields(const upb_msgdef *m);
int upb_msgdef_numoneofs(const upb_msgdef *m);
const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m); const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m);
const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i); const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i);

@ -733,7 +733,9 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
/* Note: this invalidates the accumulate buffer! Call only after reading its /* Note: this invalidates the accumulate buffer! Call only after reading its
* contents. */ * contents. */
static void multipart_end(upb_json_parser *p) { static void multipart_end(upb_json_parser *p) {
UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); /* This is false sometimes. Probably a bug of some sort, but this code is
* intended for deletion soon. */
/* UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); */
p->multipart_state = MULTIPART_INACTIVE; p->multipart_state = MULTIPART_INACTIVE;
accumulate_clear(p); accumulate_clear(p);
} }

@ -87,7 +87,9 @@ class Generator : public protoc::CodeGenerator {
bool Generate(const protobuf::FileDescriptor* file, bool Generate(const protobuf::FileDescriptor* file,
const std::string& parameter, protoc::GeneratorContext* context, const std::string& parameter, protoc::GeneratorContext* context,
std::string* error) const override; std::string* error) const override;
uint64_t GetSupportedFeatures() const override {
return FEATURE_PROTO3_OPTIONAL;
}
}; };
void AddMessages(const protobuf::Descriptor* message, void AddMessages(const protobuf::Descriptor* message,
@ -350,7 +352,7 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
MessageName(message), MessageInit(message)); MessageName(message), MessageInit(message));
} }
for (int i = 0; i < message->oneof_decl_count(); i++) { for (int i = 0; i < message->real_oneof_decl_count(); i++) {
const protobuf::OneofDescriptor* oneof = message->oneof_decl(i); const protobuf::OneofDescriptor* oneof = message->oneof_decl(i);
std::string fullname = ToCIdent(oneof->full_name()); std::string fullname = ToCIdent(oneof->full_name());
output("typedef enum {\n"); output("typedef enum {\n");
@ -379,12 +381,13 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
"UPB_INLINE bool $0_has_$1(const $0 *msg) { " "UPB_INLINE bool $0_has_$1(const $0 *msg) { "
"return _upb_has_field(msg, $2); }\n", "return _upb_has_field(msg, $2); }\n",
msgname, field->name(), layout.GetHasbitIndex(field)); msgname, field->name(), layout.GetHasbitIndex(field));
} else if (field->containing_oneof()) { } else if (field->real_containing_oneof()) {
output( output(
"UPB_INLINE bool $0_has_$1(const $0 *msg) { " "UPB_INLINE bool $0_has_$1(const $0 *msg) { "
"return _upb_has_oneof_field(msg, $2, $3); }\n", "return _upb_has_oneof_field(msg, $2, $3); }\n",
msgname, field->name(), msgname, field->name(),
GetSizeInit(layout.GetOneofCaseOffset(field->containing_oneof())), GetSizeInit(
layout.GetOneofCaseOffset(field->real_containing_oneof())),
field->number()); field->number());
} else if (field->message_type()) { } else if (field->message_type()) {
output( output(
@ -435,13 +438,13 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
"return ($0 const*)_upb_array_accessor(msg, $3, len); }\n", "return ($0 const*)_upb_array_accessor(msg, $3, len); }\n",
CTypeConst(field), msgname, field->name(), CTypeConst(field), msgname, field->name(),
GetSizeInit(layout.GetFieldOffset(field))); GetSizeInit(layout.GetFieldOffset(field)));
} else if (field->containing_oneof()) { } else if (field->real_containing_oneof()) {
output( output(
"UPB_INLINE $0 $1_$2(const $1 *msg) { " "UPB_INLINE $0 $1_$2(const $1 *msg) { "
"return UPB_READ_ONEOF(msg, $0, $3, $4, $5, $6); }\n", "return UPB_READ_ONEOF(msg, $0, $3, $4, $5, $6); }\n",
CTypeConst(field), msgname, field->name(), CTypeConst(field), msgname, field->name(),
GetSizeInit(layout.GetFieldOffset(field)), GetSizeInit(layout.GetFieldOffset(field)),
GetSizeInit(layout.GetOneofCaseOffset(field->containing_oneof())), GetSizeInit(layout.GetOneofCaseOffset(field->real_containing_oneof())),
field->number(), FieldDefault(field)); field->number(), FieldDefault(field));
} else { } else {
output( output(
@ -549,12 +552,13 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING
? "0" ? "0"
: "sizeof(" + CType(field) + ")"); : "sizeof(" + CType(field) + ")");
} else if (field->containing_oneof()) { } else if (field->real_containing_oneof()) {
output( output(
" UPB_WRITE_ONEOF(msg, $0, $1, value, $2, $3);\n" " UPB_WRITE_ONEOF(msg, $0, $1, value, $2, $3);\n"
"}\n", "}\n",
CType(field), GetSizeInit(layout.GetFieldOffset(field)), CType(field), GetSizeInit(layout.GetFieldOffset(field)),
GetSizeInit(layout.GetOneofCaseOffset(field->containing_oneof())), GetSizeInit(
layout.GetOneofCaseOffset(field->real_containing_oneof())),
field->number()); field->number());
} else { } else {
if (MessageLayout::HasHasbit(field)) { if (MessageLayout::HasHasbit(field)) {
@ -749,9 +753,9 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
int index = layout.GetHasbitIndex(field); int index = layout.GetHasbitIndex(field);
assert(index != 0); assert(index != 0);
presence = absl::StrCat(index); presence = absl::StrCat(index);
} else if (field->containing_oneof()) { } else if (field->real_containing_oneof()) {
MessageLayout::Size case_offset = MessageLayout::Size case_offset =
layout.GetOneofCaseOffset(field->containing_oneof()); layout.GetOneofCaseOffset(field->real_containing_oneof());
// We encode as negative to distinguish from hasbits. // We encode as negative to distinguish from hasbits.
case_offset.size32 = -case_offset.size32; case_offset.size32 = -case_offset.size32;

Loading…
Cancel
Save